blob: 5a40e43b5b11066ea4a1405c60e0186e6df1963a [file] [log] [blame] [view]
jbudorick5a9b37f52016-08-17 00:36:431# Android Instrumentation Tests
2
3Instrumentation tests are Java tests based on
4[`android.app.Instrumentation`](https://developer.android.com/reference/android/app/Instrumentation.html).
5They run on a device.
6
7[TOC]
8
9## Writing an instrumentation test
10
11Currently, an instrumentation test is just a JUnit3-style test based on
12[android.test.InstrumentationTestCase](https://developer.android.com/reference/android/test/InstrumentationTestCase.html).
13(This will change starting in [Android N](https://en.wikipedia.org/wiki/Android_Nougat).)
14
15Writing an instrumentation test case can be simple, e.g.
16
17```java
18package org.chromium.sample.test;
19
20import android.test.InstrumentationTestCase;
21
22public class MyInstrumentationTest extends InstrumentationTestCase {
23
24 // Note that, because it's a JUnit3-style test, the test method *must*
25 // start with "test".
26 public void testTheFirst() {
27 bool writingInstrumentationTestsCanBeEasy = true;
28
29 // InstrumentationTestCase inherits the assert* methods through
30 // junit.framework.TestCase.
31 assertTrue(writingInstrumentationTestsCanBeEasy);
32 }
33
34 public void testTheSecond() {
35 bool writingInstrumentationTestsIsAlwaysEasy = false;
36 assertFalse(writingInstrumentationTestsIsAlwaysEasy);
37 }
38}
39```
40
41After writing a test, you can run it by:
42
43 - Adding the file to the relevant gn target if the entire file is new.
44Typically, the "relevant gn target" is simply the target containing the
45other files in the same directory.
46 - Rebuild.
47 - Run the test using the process described [here](/testing/android/docs/todo.md).
48
49## Instrumentation test features
50
51In many cases, Chromium has extended the instrumentation test framework
52classes to implement additional features.
53
Nick Wardc650fdf2017-08-12 01:13:4254### Tracing
jbudorick5a9b37f52016-08-17 00:36:4355
Nick Wardc650fdf2017-08-12 01:13:4256Enabling tracing during a test run allows all the function calls involved to be
57observed in a visual display (using Chrome's built-in chrome://tracing feature).
58To run a test with tracing, add the `--trace-output` flag to the command used to
59call the instrumentation test (either running the test_runner.py script, or a
60generated binary such as `run_chrome_public_test_apk`). The `--trace-output` flag
61takes a filename, which, after the test run, will contain a JSON file readable
62by chrome://tracing.
jbudorick5a9b37f52016-08-17 00:36:4363
Nick Wardc650fdf2017-08-12 01:13:4264By default, the trace includes only certain function calls important to the test
65run, both within the Python test runner framework and the Java code running on
66the device. For a more detailed look, add the (no-argument) `--trace-all` flag.
67This causes every function called on the Python side to be added to the trace.
jbudorick5a9b37f52016-08-17 00:36:4368
69### Annotations
70
71Instrumentation tests in Chromium use a wide variety of annotations to control
72and manipulate test execution. Some of these are implemented in Chromium, while
73others are pulled in from outside. They include:
74
Michael Thiessen6bafbf02020-05-25 20:49:3575#### Test Batching
76
John Palmera8515fca2021-05-20 03:35:3277The [`@Batch("group_name")`](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/Batch.java)
Michael Thiessen6bafbf02020-05-25 20:49:3578annotation is used to run all tests with the same batch group name in the same
79instrumentation invocation. In other words, the browser process is not
80restarted between these tests, and so any changes to global state, like
81launching an Activity, will persist between tests within a batch group. The
82benefit of this is that these tests run significantly faster - the per-test cost
83of restarting the process can be as high as 10 seconds (usually around 2
84seconds), and that doesn't count the cost of starting an Activity like
85ChromeTabbedActivity.
86
jbudorick5a9b37f52016-08-17 00:36:4387#### Size annotations
88
89Size annotations are used primarily by the test runner to determine the length
90of time to wait before considering a test hung (i.e., its timeout duration).
91
92Several of the annotations are Android APIs from
93[android.test.suitebuilder.annotation](https://developer.android.com/reference/android/test/suitebuilder/annotation/package-summary.html)
94(prior to [Android N](https://en.wikipedia.org/wiki/Android_Nougat)) or
95[android.support.test.filters](https://developer.android.com/reference/android/support/test/filters/package-summary.html)
96(starting in Android N). These are all fairly self-explanatory:
97
Michael Thiessen4dd7278c2021-03-22 16:46:3298 - [`@SmallTest`](https://developer.android.com/reference/android/support/test/filters/SmallTest.html) (timeout: **10 seconds**)
99 - [`@MediumTest`](https://developer.android.com/reference/android/support/test/filters/MediumTest.html) (timeout: **30 seconds**)
100 - [`@LargeTest`](https://developer.android.com/reference/android/support/test/filters/LargeTest.html) (timeout: **2 minutes**)
jbudorick5a9b37f52016-08-17 00:36:43101
102A few additional size annotations are provided in
John Palmera8515fca2021-05-20 03:35:32103[//base](https://chromium.googlesource.com/chromium/src/+/main/base):
jbudorick5a9b37f52016-08-17 00:36:43104
John Palmera8515fca2021-05-20 03:35:32105 - [`@EnormousTest`](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/EnormousTest.java)
Michael Thiessen4dd7278c2021-03-22 16:46:32106(timeout: **5 minutes**) Typically used for tests that require WiFi.
John Palmera8515fca2021-05-20 03:35:32107 - [`@IntegrationTest`](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/IntegrationTest.java)
Michael Thiessen4dd7278c2021-03-22 16:46:32108(timeout: **10 minutes**) Used for tests that run against real services.
John Palmera8515fca2021-05-20 03:35:32109 - [`@Manual`](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/Manual.java)
jbudorick5a9b37f52016-08-17 00:36:43110(timeout: **10 hours**) Used for manual tests.
111
112Beware that the timeout durations for these annotations are subject to
113change, though they rarely do. These values are defined
John Palmera8515fca2021-05-20 03:35:32114[here](https://chromium.googlesource.com/chromium/src/+/main/build/android/pylib/local/device/local_device_instrumentation_test_run.py#20).
jbudorick5a9b37f52016-08-17 00:36:43115
116#### Annotations that disable tests
117
118There are several annotations that control whether or not a test runs.
119Some are conditional, others are not.
120
121##### Unconditional disabling
122
John Palmera8515fca2021-05-20 03:35:32123[**@DisabledTest**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/DisabledTest.java)
jbudoricka2d64d12016-08-22 22:10:00124unconditionally disables a test.
125```java
126@DisabledTest(
127 // Describes why the test is disabled. Typically includes a crbug link.
128 message = ""
129)
130```
jbudorick5a9b37f52016-08-17 00:36:43131
John Palmera8515fca2021-05-20 03:35:32132[**@FlakyTest**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/FlakyTest.java)
jbudoricka2d64d12016-08-22 22:10:00133marks a test as flaky. This also unconditionally disables the test, though
134tests marked with **@FlakyTest** are explicitly run on some bots.
135```java
136@FlakyTest(
137 // Describes why the test is marked flaky. Typically includes a crbug link.
138 message = ""
139)
140```
jbudorick5a9b37f52016-08-17 00:36:43141
jbudoricka2d64d12016-08-22 22:10:00142Note that there are Android versions of **@DisabledTest** and **@FlakyTest**
143that do not allow message specification. These are no longer used in Chromium.
144
145As alluded to above, tests marked with either **@DisabledTest** or
146**@FlakyTest** can be explicitly run via the test runner's
147[-A/--annotation](/testing/android/docs/todo.md)
148flag. For example, this would run only the tests marked as flaky in
149`chrome_public_test_apk`:
150
151```bash
152./out/Debug/bin/run_chrome_public_test_apk -A FlakyTest
153```
jbudorick5a9b37f52016-08-17 00:36:43154
155##### Conditional disabling
156
157There are two primary annotation categories that conditionally disable tests:
158**@DisableIf** and **@Restriction**. The **@DisableIf** annotations are intended
159to temporarily disable a test in certain scenarios where it *should* work but
160doesn't. In contrast, the **@Restriction** annotation is intended to
161permanently limit a test to specific configurations. It signifies that the test
162was not, is not, and will not be intended to run beyond those configurations.
163In both cases, conditional disabling manifests as a skipped test.
164
John Palmera8515fca2021-05-20 03:35:32165[**@DisableIf.Build**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/DisableIf.java#25)
jbudoricka2d64d12016-08-22 22:10:00166allows for conditional test disabling based on values in
jbudorick5a9b37f52016-08-17 00:36:43167[`android.os.Build`](https://developer.android.com/reference/android/os/Build.html):
168
169```java
170@DisableIf.Build(
171
172 // Describes why the test is disabled.
173 message = "",
174
175 // Disables the test on SDK levels that match the given conditions.
176 // Checks against Build.VERSION.SDK_INT.
177 sdk_is_greater_than = 0,
178 sdk_is_less_than = Integer.MAX_VALUE,
179
180 // Disables the test on devices that support the given ABI
181 // (e.g. "arm64-v8a"). Checks against:
182 // - Build.SUPPORTED_ABIS on L+
183 // - Build.CPU_ABI and Build.CPU_ABI2 otherwise
184 supported_abis_includes = "",
185
186 // Disables the test on devices with hardware that matches the given
187 // value. Checks against Build.HARDWARE.
188 hardware_is = "",
189
190 // Disables the test on devices with product names that contain the
191 // given value. Checks against Build.PRODUCT.
192 product_name_includes = "",
193
194)
195```
196
John Palmera8515fca2021-05-20 03:35:32197[**@DisableIf.Device**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/DisableIf.java#40)
jbudoricka2d64d12016-08-22 22:10:00198allows for conditional test disabling based on whether
jbudorick5a9b37f52016-08-17 00:36:43199a device is a phone, a tablet, or a "large tablet" as determined by
John Palmera8515fca2021-05-20 03:35:32200[org.chromium.ui.base.DeviceFormFactor](https://chromium.googlesource.com/chromium/src/+/main/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java).
Shenghua Zhangcac866d2017-08-29 01:30:55201This is available to tests in
John Palmera8515fca2021-05-20 03:35:32202[//ui](https://chromium.googlesource.com/chromium/src/+/main/ui/)
Shenghua Zhangcac866d2017-08-29 01:30:55203or code that uses //ui.
jbudorick5a9b37f52016-08-17 00:36:43204
205```java
206@DisableIf.Device(
207 // Disables the test on devices that match the given type(s) as described
208 // above.
209 type = {}
210)
211```
212
John Palmera8515fca2021-05-20 03:35:32213[**@Restriction**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/Restriction.java)
jbudoricka2d64d12016-08-22 22:10:00214currently allows for conditional test disabling based on device
jbudorick5a9b37f52016-08-17 00:36:43215type, device performance, internet connectivity, whether Google Play Services is
216up to date, and whether the build was an official one.
217
218```java
219@Restriction(
220 // Possible values include:
221 //
Michael Thiessen6bafbf02020-05-25 20:49:35222 // base:
jbudorick5a9b37f52016-08-17 00:36:43223 // - Restriction.RESTRICTION_TYPE_LOW_END_DEVICE
224 // Restricts the test to low-end devices as determined by SysUtils.isLowEndDevice().
225 //
226 // - Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE
227 // Restricts the test to non-low-end devices as determined by SysUtils.isLowEndDevice().
228 //
229 // - Restriction.RESTRICTION_TYPE_INTERNET
230 // Restricts the test to devices that have an internet connection.
231 //
232 // chrome:
233 // - ChromeRestriction.RESTRICTION_TYPE_GOOGLE_PLAY_SERVICES
234 // Restricts the test to devices with up-to-date versions of Google Play Services.
235 //
jbudorick5a9b37f52016-08-17 00:36:43236 // - ChromeRestriction.RESTRICTION_TYPE_OFFICIAL_BUILD
237 // Restricts the test to official builds as determined by ChromeVersionInfo.isOfficialBuild().
Shenghua Zhangcac866d2017-08-29 01:30:55238 //
239 // ui:
240 // - UiRestriction.RESTRICTION_TYPE_PHONE
241 // Restricts the test to phones as determined by DeviceFormFactor.
242 //
243 // - UiRestriction.RESTRICTION_TYPE_TABLET
244 // Restricts the test to tablets as determined by DeviceFormFactor.
jbudorick5a9b37f52016-08-17 00:36:43245 value = {}
246)
247```
248
John Palmera8515fca2021-05-20 03:35:32249[**@MinAndroidSdkLevel**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/MinAndroidSdkLevel.java)
jbudoricka2d64d12016-08-22 22:10:00250is similar to **@Restriction** in purpose in that it's
jbudorick5a9b37f52016-08-17 00:36:43251intended to permanently limit a test to only recent versions of Android.
252
253```java
254@MinAndroidSdkLevel(
255 // The minimum SDK level at which this test should be executed. Checks
256 // against Build.VERSION.SDK_INT.
257 value = 0
258)
259```
260
261#### Annotations that affect how a test is run
262
263Several annotations affect how a test is run in interesting or nontrivial ways.
264
John Palmera8515fca2021-05-20 03:35:32265[**@CommandLineFlags.Add**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java#46)
jbudoricka2d64d12016-08-22 22:10:00266and
John Palmera8515fca2021-05-20 03:35:32267[**@CommandLineFlags.Remove**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java#58)
jbudoricka2d64d12016-08-22 22:10:00268manipulate Chrome's
jbudorick5a9b37f52016-08-17 00:36:43269command-line flags on a per-test basis (i.e., the flags handled by
John Palmera8515fca2021-05-20 03:35:32270[`org.chromium.base.CommandLine`](https://chromium.googlesource.com/chromium/src/+/main/base/android/java/src/org/chromium/base/CommandLine.java) and
271[`base::CommandLine`](https://chromium.googlesource.com/chromium/src/+/main/base/command_line.h)).
jbudorick5a9b37f52016-08-17 00:36:43272
273```java
274@CommandLineFlags.Add(
275 // The flags to add to the command line for this test. These can be
276 // anything and typically should include the leading dashes (e.g. "--foo").
277 value = {}
278)
279
280@CommandLineFlags.Remove(
281 // The flags to remove from the command line for this test. These can only
282 // be flags added via @CommandLineFlags.Add. Flags already present in the
283 // command-line file on the device are only present in the native
284 // CommandLine object and cannot be manipulated.
285 value = {}
286)
287```
288
289#### Feature annotations
290
John Palmera8515fca2021-05-20 03:35:32291[**@Feature**](https://chromium.googlesource.com/chromium/src/+/main/base/test/android/javatests/src/org/chromium/base/test/util/Feature.java)
jbudoricka2d64d12016-08-22 22:10:00292has been used inconsistently in Chromium to group tests across
jbudorick5a9b37f52016-08-17 00:36:43293test cases according to the feature they're testing.
294
295```java
296@Feature(
297 // The features associated with this test. These can be anything.
298 value = {}
299)
300```
301
302@Feature doesn't have an inherent function, but it can be used to filter tests
303via the test runner's
304[-A/--annotation](/testing/android/docs/todo.md) and
305[-E/--exclude-annotation](/testing/android/docs/todo.md) flags. For example,
306this would run only the tests with @Feature annotations containing at least
307"Sync" in `chrome_public_test_apk`:
308
309```bash
310out/Debug/bin/run_chrome_public_test_apk -A Feature=Sync
311```
jbudorick2d4f26892017-01-09 16:51:06312
313## Advanced
314
315 - [Creating a component for use in instrumentation tests.](/testing/android/docs/components_for_testing.md)