зеркало из https://github.com/mozilla/glean.git
Update documentation to reflect both supported platforms everywh… (#389)
Update documentation to reflect both supported platforms everywhere
This commit is contained in:
Коммит
f0b4fdcbbb
|
@ -13,6 +13,10 @@ Products using the Glean SDK to collect telemetry **must**:
|
||||||
|
|
||||||
### Integrating with your project
|
### Integrating with your project
|
||||||
|
|
||||||
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
#### Setting up the dependency
|
#### Setting up the dependency
|
||||||
|
|
||||||
Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](https://github.com/mozilla-mobile/android-components/blob/master/README.md#maven-repository)) by adding the following to your Gradle configuration:
|
Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](https://github.com/mozilla-mobile/android-components/blob/master/README.md#maven-repository)) by adding the following to your Gradle configuration:
|
||||||
|
@ -58,20 +62,43 @@ apply from: 'https://raw.githubusercontent.com/mozilla-mobile/android-components
|
||||||
|
|
||||||
There are [additional parameters](android-build-configuration-options.md) that can be set to control the behavior of the `sdk_generator.gradle` script, but they are rarely used in normal use.
|
There are [additional parameters](android-build-configuration-options.md) that can be set to control the behavior of the `sdk_generator.gradle` script, but they are rarely used in normal use.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
#### Setting up the dependency
|
||||||
|
|
||||||
|
Glean can be consumed through [Carthage](https://github.com/Carthage/Carthage), a dependency manager for macOS and iOS.
|
||||||
|
For consuming the latest version of Glean, add the following line to your `Cartfile`::
|
||||||
|
|
||||||
|
```
|
||||||
|
github "mozilla/glean" "master"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Integrating with the build system
|
||||||
|
|
||||||
|
> **Note:** This is not yet documented, as the exact mechanism is not finalized. See [Bug 1589383](https://bugzilla.mozilla.org/show_bug.cgi?id=1589383) for more information.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
||||||
### Adding new metrics
|
### Adding new metrics
|
||||||
|
|
||||||
All metrics that your project collects must be defined in a `metrics.yaml` file.
|
All metrics that your project collects must be defined in a `metrics.yaml` file.
|
||||||
This file should be at the root of the module (the same directory as the `build.gradle` file you updated).
|
Add this file to your project and define it as an input file for the `sdk_generator.sh` script in the `Run Script` step defined before.
|
||||||
The format of that file is documented [with `glean_parser`](https://mozilla.github.io/glean_parser/metrics-yaml.html).
|
The format of that file is documented [with `glean_parser`](https://mozilla.github.io/glean_parser/metrics-yaml.html).
|
||||||
To learn more, see [adding new metrics](adding-new-metrics.md).
|
To learn more, see [adding new metrics](adding-new-metrics.md).
|
||||||
|
|
||||||
> **Important**: as stated [above](#before-using-glean), any new data collection requires documentation and data-review. This is also required for any new metric automatically collected by the Glean SDK.
|
> **Important**: as stated [before](adding-glean-to-your-project.md#before-using-glean), any new data collection requires documentation and data-review.
|
||||||
|
> This is also required for any new metric automatically collected by the Glean SDK.
|
||||||
|
|
||||||
### Adding custom pings
|
### Adding custom pings
|
||||||
|
|
||||||
Please refer to the [custom pings documentation](pings/custom.md).
|
Please refer to the [custom pings documentation](pings/custom.md).
|
||||||
|
|
||||||
> **Important**: as stated [above](#before-using-glean), any new data collection, including new custom pings, requires documentation and data-review. This is also required for any new ping automatically collected by the Glean SDK.
|
> **Important**: as stated [before](adding-glean-to-your-project.md#before-using-glean), any new data collection requires documentation and data-review.
|
||||||
|
> This is also required for any new metric automatically collected by the Glean SDK.
|
||||||
|
|
||||||
### Testing metrics
|
### Testing metrics
|
||||||
|
|
||||||
|
@ -87,14 +114,17 @@ These specific steps are described in [the `probe_scraper` documentation](https:
|
||||||
|
|
||||||
The following steps are required for applications using the Glean SDK, but not libraries.
|
The following steps are required for applications using the Glean SDK, but not libraries.
|
||||||
|
|
||||||
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
### Initializing the Glean SDK
|
### Initializing the Glean SDK
|
||||||
|
|
||||||
The Glean SDK should only be initialized from the main application, not individual libraries. If you are adding Glean support to a library, you can safely skip this section.
|
The Glean SDK should only be initialized from the main application, not individual libraries. If you are adding Glean support to a library, you can safely skip this section.
|
||||||
Please also note that the Glean SDK does not support use across multiple processes, and must only be initialized on the application's main process. Initializing in other processes is a no-op.
|
Please also note that the Glean SDK does not support use across multiple processes, and must only be initialized on the application's main process. Initializing in other processes is a no-op.
|
||||||
Additionally, Glean must be initialized on the main (UI) thread of the applications main process. Failure to do so will throw an `IllegalThreadStateException`.
|
Additionally, Glean must be initialized on the main (UI) thread of the applications main process. Failure to do so will throw an `IllegalThreadStateException`.
|
||||||
|
|
||||||
Before any data collection can take place, the Glean SDK **must** be initialized from the application.
|
An excellent place to initialize Glean is within the `onCreate` method of the class that extends Android's `Application` class.
|
||||||
An excellent place to perform this operation is within the `onCreate` method of the class that extends Android's `Application` class.
|
|
||||||
|
|
||||||
```Kotlin
|
```Kotlin
|
||||||
import org.mozilla.yourApplication.GleanMetrics.Pings
|
import org.mozilla.yourApplication.GleanMetrics.Pings
|
||||||
|
@ -140,3 +170,64 @@ The application should provide some form of user interface to call this method.
|
||||||
|
|
||||||
When going from enabled to disabled, all pending events, metrics and pings are cleared, except for `first_run_date`.
|
When going from enabled to disabled, all pending events, metrics and pings are cleared, except for `first_run_date`.
|
||||||
When re-enabling, core Glean metrics will be recomputed at that time.
|
When re-enabling, core Glean metrics will be recomputed at that time.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
### Initializing the Glean SDK
|
||||||
|
|
||||||
|
The Glean SDK should only be initialized from the main application, not individual libraries.
|
||||||
|
If you are adding Glean support to a library, you can safely skip this section.
|
||||||
|
Please also note that the Glean SDK does not support use across multiple processes, and must only be initialized on the application's main process.
|
||||||
|
|
||||||
|
An excellent place to initialize Glean is within the `application(_:)` method of the class that extends the `UIApplicationDelegate` class.
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
import Glean
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@UIApplicationMain
|
||||||
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
// If you have custom pings in your application, you must register them
|
||||||
|
// using the following command. This command should be omitted for
|
||||||
|
// applications not using custom pings.
|
||||||
|
Glean.shared.registerPings(GleanMetrics.Pings)
|
||||||
|
|
||||||
|
// Call setUploadEnabled first, since Glean.initialize
|
||||||
|
// might send pings if there are any metrics queued up
|
||||||
|
// from a previous run.
|
||||||
|
Glean.shared.setUploadEnabled(Settings.isTelemetryEnabled)
|
||||||
|
|
||||||
|
// Initialize the Glean library.
|
||||||
|
Glean.shared.initialize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once initialized, if collection is enabled, the Glean SDK will automatically start collecting [baseline metrics](pings/metrics.md) and sending its [pings](pings/index.md).
|
||||||
|
|
||||||
|
The Glean SDK should be initialized as soon as possible, and importantly, before any other libraries in the application start using Glean.
|
||||||
|
Library code should never call `Glean.shared.initialize`, since it should be called exactly once per application.
|
||||||
|
|
||||||
|
> **Note**: if the application has the concept of release channels and knows which channel it is on at run-time,
|
||||||
|
> then it can provide the Glean SDK with this information by setting it as part of the `Configuration` object parameter of the `Glean.shared.initialize` method. For example:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
Glean.shared.initialize(Configuration(channel: "beta"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enabling and disabling metrics
|
||||||
|
|
||||||
|
`Glean.shared.setUploadEnabled()` should be called in response to the user enabling or disabling telemetry.
|
||||||
|
This method should also be called at least once prior to calling `Glean.shared.initialize()`.
|
||||||
|
|
||||||
|
The application should provide some form of user interface to call this method.
|
||||||
|
|
||||||
|
When going from enabled to disabled, all pending events, metrics and pings are cleared, except for `first_run_date`.
|
||||||
|
When re-enabling, core Glean metrics will be recomputed at that time.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Adding new metrics
|
# Adding new metrics
|
||||||
|
|
||||||
All metrics that your project collects must be defined in a `metrics.yaml` file.
|
All metrics that your project collects must be defined in a `metrics.yaml` file.
|
||||||
This file should be at the root of the application or library module (the same directory as the `build.gradle` file you updated).
|
This file should be at the root of the application or library module.
|
||||||
The format of that file is documented [here](https://mozilla.github.io/glean_parser/metrics-yaml.html).
|
The format of that file is documented [here](https://mozilla.github.io/glean_parser/metrics-yaml.html).
|
||||||
|
|
||||||
When adding a new metric, the workflow is:
|
When adding a new metric, the workflow is:
|
||||||
|
@ -47,7 +47,7 @@ category2.subcategory: # Categories can contain subcategories
|
||||||
|
|
||||||
The details of the metric parameters are described in [metric parameters](metric-parameters.md).
|
The details of the metric parameters are described in [metric parameters](metric-parameters.md).
|
||||||
|
|
||||||
The `metrics.yaml` file is used to generate `Kotlin` code that becomes the public API to access your application's metrics.
|
The `metrics.yaml` file is used to generate code in the target language (e.g. Kotlin, Swift, ...) that becomes the public API to access your application's metrics.
|
||||||
|
|
||||||
## Recommendations for defining new metrics
|
## Recommendations for defining new metrics
|
||||||
|
|
||||||
|
@ -93,7 +93,14 @@ If the metric is still needed, it should go back for [another round of data revi
|
||||||
|
|
||||||
## A note about case inflection
|
## A note about case inflection
|
||||||
|
|
||||||
Category and metric names in the `metrics.yaml` are in `snake_case`, but given the Kotlin coding standards defined by [ktlint](https://github.com/pinterest/ktlint), these identifiers must be `camelCase` in Kotlin. For example, the metric defined in the `metrics.yaml` as:
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
|
Category and metric names in the `metrics.yaml` are in `snake_case`,
|
||||||
|
but given the Kotlin coding standards defined by [ktlint](https://github.com/pinterest/ktlint),
|
||||||
|
these identifiers must be `camelCase` in Kotlin.
|
||||||
|
For example, the metric defined in the `metrics.yaml` as:
|
||||||
|
|
||||||
|
|
||||||
```YAML
|
```YAML
|
||||||
|
@ -106,5 +113,30 @@ is accessible in Kotlin as:
|
||||||
|
|
||||||
```Kotlin
|
```Kotlin
|
||||||
import org.mozilla.yourApplication.GleanMetrics.Views
|
import org.mozilla.yourApplication.GleanMetrics.Views
|
||||||
Views.loginOpened...
|
GleanMetrics.Views.loginOpened...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
Category and metric names in the `metrics.yaml` are in `snake_case`,
|
||||||
|
but given the Swift coding standards defined by [swiftlint](https://github.com/realm/SwiftLint),
|
||||||
|
these identifiers must be `camelCase` in Swift.
|
||||||
|
For example, the metric defined in the `metrics.yaml` as:
|
||||||
|
|
||||||
|
```YAML
|
||||||
|
views:
|
||||||
|
login_opened:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
is accessible in Kotlin as:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
GleanMetrics.Views.loginOpened...
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
|
@ -7,6 +7,10 @@ The Glean SDK supports tagging all its pings with experiments annotations. The a
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
```Kotlin
|
```Kotlin
|
||||||
// Annotate Glean pings with experiments data.
|
// Annotate Glean pings with experiments data.
|
||||||
Glean.setExperimentActive(
|
Glean.setExperimentActive(
|
||||||
|
@ -37,6 +41,16 @@ assertEquals(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
> **Note**: Experiments are currently not supported by Glean for iOS.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
||||||
## Limits
|
## Limits
|
||||||
|
|
||||||
* `experimentId`, `branch`, and the keys of the 'extra' field are fixed at a maximum length of 30. Length for the values of the `extra` field is fixed at 50. Longer strings used as ids, keys, or values are truncated to their respective maximum length. For the original Kotlin implementation of the Glean SDK, this is measured in Unicode characters. For the Rust implementation, this is measured in the number of bytes when the string is encoded in UTF-8.
|
* `experimentId`, `branch`, and the keys of the 'extra' field are fixed at a maximum length of 30. Length for the values of the `extra` field is fixed at 50. Longer strings used as ids, keys, or values are truncated to their respective maximum length. For the original Kotlin implementation of the Glean SDK, this is measured in Unicode characters. For the Rust implementation, this is measured in the number of bytes when the string is encoded in UTF-8.
|
||||||
|
|
|
@ -77,4 +77,4 @@ XCTAssertTrue(try Flags.a11yEnabled.testGetValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-boolean-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-boolean-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/BooleanMetricType.html)
|
||||||
|
|
|
@ -78,4 +78,4 @@ XCTAssertEqual(6, try Controls.refreshPressed.testGetValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-counter-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-counter-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/CounterMetricType.html)
|
||||||
|
|
|
@ -81,6 +81,4 @@ assertEquals(2L, snapshot.count())
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* See [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-custom-distribution-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-custom-distribution-metric-type/index.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -103,3 +103,4 @@ XCTAssertEqual(6, try Controls.refreshPressed.testGetValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-datetime-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-datetime-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/DatetimeMetricType.html)
|
||||||
|
|
|
@ -95,5 +95,5 @@ XCTAssertEqual("login_opened", first.name)
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* See [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-event-metric-type/index.html).
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-event-metric-type/index.html).
|
||||||
|
* [Swift API docs](../../../swift/Classes/EventMetricType.html)
|
||||||
|
|
|
@ -95,3 +95,4 @@ XCTAssertEqual(3, try Stability.crashCount["native_code_crash"].testGetValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* Kotlin API docs [LabeledMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [CounterMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-counter-metric-type/index.html)
|
* Kotlin API docs [LabeledMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [CounterMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-counter-metric-type/index.html)
|
||||||
|
* Swift API docs: [LabeledMetricType](../../../swift/Classes/LabeledMetricType.html), [CounterMetricType](../../../swift/Classes/CounterMetricType.html)
|
||||||
|
|
|
@ -87,3 +87,4 @@ XCTAssert(Login.errorsByStage["server_auth"].testHasValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* Kotlin API docs: [LabeledMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [StringMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-string-metric-type/index.html)
|
* Kotlin API docs: [LabeledMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-labeled-metric-type/index.html), [StringMetricType](../../../javadoc/glean/mozilla.telemetry.glean.private/-string-metric-type/index.html)
|
||||||
|
* Swift API docs: [LabeledMetricType](../../../swift/Classes/LabeledMetricType.html), [StringMetricType](../../../swift/Classes/StringMetricType.html)
|
||||||
|
|
|
@ -108,4 +108,5 @@ XCTAssertEqual(2, snapshot.count)
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* See [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-memory-distribution-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-memory-distribution-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/MemoryDistributionMetricType.html)
|
||||||
|
|
|
@ -91,3 +91,4 @@ XCTAssertEqual("wikipedia", try SearchDefault.name.testGetValue())
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-string-metric-type/index.html).
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-string-metric-type/index.html).
|
||||||
|
* [Swift API docs](../../../swift/Classes/StringMetricType.html)
|
||||||
|
|
|
@ -159,3 +159,4 @@ HistorySync.setRawNanos(duration)
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-timespan-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-timespan-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/TimespanMetricType.html)
|
||||||
|
|
|
@ -34,7 +34,7 @@ For example, to measure page load time on a number of tabs that are loading at t
|
||||||
<div data-lang="Kotlin" class="tab">
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
```Kotlin
|
```Kotlin
|
||||||
import mozilla.components.service.glean.timing.GleanTimerId
|
import mozilla.components.service.glean.GleanTimerId
|
||||||
import org.mozilla.yourApplication.GleanMetrics.Pages
|
import org.mozilla.yourApplication.GleanMetrics.Pages
|
||||||
|
|
||||||
val timerId : GleanTimerId
|
val timerId : GleanTimerId
|
||||||
|
@ -129,4 +129,5 @@ XCTAssertEqual(2, snapshot.count)
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* See [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-timing-distribution-metric-type/index.html)
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-timing-distribution-metric-type/index.html)
|
||||||
|
* [Swift API docs](../../../swift/Classes/TimingDistributionMetricType.html)
|
||||||
|
|
|
@ -80,5 +80,5 @@ XCTAssertEqual(uuid, try User.clientId.testGetValue())
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
* See [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-uuid-metric-type/index.html).
|
* [Kotlin API docs](../../../javadoc/glean/mozilla.telemetry.glean.private/-uuid-metric-type/index.html).
|
||||||
|
* [Swift API docs](../../../swift/Classes/UuidMetricType.html)
|
||||||
|
|
|
@ -2,11 +2,19 @@
|
||||||
|
|
||||||
In order to support unit testing inside of client applications using the Glean SDK, a set of testing API functions have been included.
|
In order to support unit testing inside of client applications using the Glean SDK, a set of testing API functions have been included.
|
||||||
The intent is to make the Glean SDK easier to test 'out of the box' in any client application it may be used in.
|
The intent is to make the Glean SDK easier to test 'out of the box' in any client application it may be used in.
|
||||||
These functions expose a way to inspect and validate recorded metric values within the client application but are restricted to test code only through visibility annotations (`@VisibleForTesting(otherwise = VisibleForTesting.NONE)`).
|
These functions expose a way to inspect and validate recorded metric values within the client application but are restricted to test code only through visibility annotations
|
||||||
|
(`@VisibleForTesting(otherwise = VisibleForTesting.NONE)` for Kotlin, `internal` methods for Swift).
|
||||||
|
|
||||||
## General test API method semantics
|
## General test API method semantics
|
||||||
|
|
||||||
In order to prevent issues with async calls when unit testing Glean, it is important to put the Glean SDK into testing mode by applying the JUnit `GleanTestRule` to your test class. When the Glean SDK is in testing mode, it enables uploading and clears the recorded metrics at the beginning of each test run. The rule can be used as shown below:
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
|
In order to prevent issues with async calls when unit testing Glean,
|
||||||
|
it is important to put the Glean SDK into testing mode by applying the JUnit `GleanTestRule` to your test class.
|
||||||
|
When the Glean SDK is in testing mode, it enables uploading and clears the recorded metrics at the beginning of each test run.
|
||||||
|
The rule can be used as shown below:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
@ -39,7 +47,58 @@ This function will return a datatype appropriate to the specific type of the met
|
||||||
assertEquals("https://example.com/search?", GleanMetrics.Search.defaultSearchEngineUrl.testGetValue())
|
assertEquals("https://example.com/search?", GleanMetrics.Search.defaultSearchEngineUrl.testGetValue())
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that each of these functions has its visibility limited to the scope of unit tests by making use of the `@VisibleForTesting` annotation, so the IDE should complain if you attempt to use them inside of client code.
|
Note that each of these functions has its visibility limited to the scope of unit tests by making use of the `@VisibleForTesting` annotation,
|
||||||
|
so the IDE should complain if you attempt to use them inside of client code.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
> **NOTE**: There's no automatic test rule for Glean tests implemented.
|
||||||
|
|
||||||
|
In order to prevent issues with async calls when unit testing Glean, it is important to put the Glean SDK into testing mode.
|
||||||
|
When the Glean SDK is in testing mode, it enables uploading and clears the recorded metrics at the beginning of each test run.
|
||||||
|
|
||||||
|
Activate it by resetting Glean in your test's setup:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
@testable import Glean
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class GleanUsageTests: XCTestCase {
|
||||||
|
override func setUp() {
|
||||||
|
Glean.shared.resetGlean(clearStores: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will ensure that metrics are done recording when the other test functions are used.
|
||||||
|
|
||||||
|
To check if a value exists (i.e. it has been recorded), there is a `testHasValue()` function on each of the metric instances:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
XCTAssertTrue(GleanMetrics.Search.defaultSearchEngineUrl.testHasValue())
|
||||||
|
```
|
||||||
|
|
||||||
|
To check the actual values, there is a `testGetValue()` function on each of the metric instances.
|
||||||
|
It is important to check that the values are recorded as expected, since many of the metric types may truncate or error-correct the value.
|
||||||
|
This function will return a datatype appropriate to the specific type of the metric it is being used with:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
XCTAssertEqual("https://example.com/search?", try GleanMetrics.Search.defaultSearchEngineUrl.testGetValue())
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that each of these functions is marked as `internal`, you need to import `Glean` explicitly in test mode:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
@testable import Glean
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
||||||
## Testing metrics for custom pings
|
## Testing metrics for custom pings
|
||||||
|
|
||||||
|
@ -53,13 +112,18 @@ You should only need to provide a `pingName` if the metric is being sent in more
|
||||||
You can call the `testHasValue()` and `testGetValue()` functions with `pingName` like this:
|
You can call the `testHasValue()` and `testGetValue()` functions with `pingName` like this:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
GleanMetrics.Foo.UriCount.testHasValue("customPing")
|
GleanMetrics.Foo.uriCount.testHasValue("customPing")
|
||||||
GleanMetrics.Foo.UriCount.testGetValue("customPing")
|
GleanMetrics.Foo.uriCount.testGetValue("customPing")
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example of using the test API
|
## Example of using the test API
|
||||||
|
|
||||||
|
{{#include ../tab_header.md}}
|
||||||
|
|
||||||
|
<div data-lang="Kotlin" class="tab">
|
||||||
|
|
||||||
Here is a longer example to better illustrate the intended use of the test API:
|
Here is a longer example to better illustrate the intended use of the test API:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
// Record a metric value with extra to validate against
|
// Record a metric value with extra to validate against
|
||||||
GleanMetrics.BrowserEngagement.click.record(
|
GleanMetrics.BrowserEngagement.click.record(
|
||||||
|
@ -84,3 +148,34 @@ assertEquals(3, events.size)
|
||||||
// Check extra key/value for first event in the list
|
// Check extra key/value for first event in the list
|
||||||
assertEquals("Courier", events.elementAt(0).extra["font"])
|
assertEquals("Courier", events.elementAt(0).extra["font"])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-lang="Swift" class="tab">
|
||||||
|
|
||||||
|
Here is a longer example to better illustrate the intended use of the test API:
|
||||||
|
|
||||||
|
```Swift
|
||||||
|
// Record a metric value with extra to validate against
|
||||||
|
GleanMetrics.BrowserEngagement.click.record([.font: "Courier"])
|
||||||
|
|
||||||
|
// Record more events without extras attached
|
||||||
|
BrowserEngagement.click.record()
|
||||||
|
BrowserEngagement.click.record()
|
||||||
|
|
||||||
|
// Check if we collected any events into the 'click' metric
|
||||||
|
XCTAssertTrue(BrowserEngagement.click.testHasValue())
|
||||||
|
|
||||||
|
// Retrieve a snapshot of the recorded events
|
||||||
|
let events = try! BrowserEngagement.click.testGetValue()
|
||||||
|
|
||||||
|
// Check if we collected all 3 events in the snapshot
|
||||||
|
XCTAssertEqual(3, events.count)
|
||||||
|
|
||||||
|
// Check extra key/value for first event in the list
|
||||||
|
XCTAssertEqual("Courier", events[0].extra?["font"])
|
||||||
|
```
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#include ../tab_footer.md}}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче