blob: dd047b00762ea6420c58d49851031328f9f27bdb [file] [log] [blame] [view]
Andrew Grieveb5b3bb32023-10-04 13:55:511# Android Testing in Chromium
andybons3322f762015-08-24 21:37:092
Andrew Grieveb5b3bb32023-10-04 13:55:513[TOC]
4
5## Test Types
6
7- **[gtests]**: For writing unit tests in C++. Most tests are cross-platform.
8- **Browser Tests**: Built on top of gtest. Used to write integration tests.
9- **[Robolectric]**: JUnit tests that run on the host machine by emulating (or
10 mocking) Android APIs.
11- **[Instrumentation Tests]**: JUnit tests that run on devices / emulators.
12 - **Unit Instrumentation Tests**: Unit tests that do not require
Ted Choca4550c642024-11-19 19:59:3013 initializing the Content layer. These use [BaseActivityTestRule] often
14 using [BlankUiTestActivity].
Andrew Grieveb5b3bb32023-10-04 13:55:5115 - **Integration Instrumentation Tests**: Instrumentation tests that require
16 initializing the Content layer to test a certain feature in the end-to-end
17 flow. These typically use more specialized test rules such as
18 [ContentShellActivityTestRule] or [ChromeActivityTestRule].
19
20[gtests]: android_gtests.md
21[Robolectric]: android_robolectric_tests.md
22[Instrumentation Tests]: android_instrumentation_tests.md
23[BaseActivityTestRule]: https://source.chromium.org/chromium/chromium/src/+/main:base/test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java
Ted Choca4550c642024-11-19 19:59:3024[BlankUiTestActivity]: https://source.chromium.org/chromium/chromium/src/+/main:ui/android/javatests/src/org/chromium/ui/test/util/BlankUiTestActivity.java
Andrew Grieveb5b3bb32023-10-04 13:55:5125[ContentShellActivityTestRule]: https://source.chromium.org/chromium/chromium/src/+/main:content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java
26[ChromeActivityTestRule]: https://source.chromium.org/chromium/chromium/src/+/main:chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
27
28## Device Setup
29
30### Physical Device Setup
31
32#### Root Access
33
34Running tests requires root access, which requires using a userdebug build on
35your device.
36
37To use a userdebug build, see
38[Running Builds](https://source.android.com/setup/build/running.html). Googlers
39can refer to [this page](https://goto.google.com/flashdevice).
40
41If you can't run "adb root", you will get an error when trying to install
42the test APKs like "adb: error: failed to copy" and
43"remote secure_mkdirs failed: Operation not permitted" (use "adb unroot" to
44return adb to normal).
45
46#### ADB Debugging
47
48The adb executable exists within the Android SDK:
49
50```shell
51third_party/android_sdk/public/platform-tools/adb
52```
53
54In order to allow the ADB to connect to the device, you must enable USB
55debugging:
56
57* Developer options are hidden by default. To unhide them:
58 * Go to "About phone"
59 * Tap 10 times on "Build number"
60 * The "Developer options" menu will now be available.
61 * Check "USB debugging".
62 * Un-check "Verify apps over USB".
63
64#### Screen
65
66You **must** ensure that the screen stays on while testing: `adb shell svc power
67stayon usb` Or do this manually on the device: Settings -> Developer options ->
68Stay Awake.
69
70If this option is greyed out, stay awake is probably disabled by policy. In that
71case, get another device or log in with a normal, unmanaged account (because the
72tests will break in exciting ways if stay awake is off).
73
74#### Disable Verify Apps
75
76You may see a dialog like [this
77one](http://www.samsungmobileusa.com/simulators/ATT_GalaxyMega/mobile/screens/06-02_12.jpg),
78which states, _Google may regularly check installed apps for potentially harmful
79behavior._ This can interfere with the test runner. To disable this dialog, run:
80
81```shell
82adb shell settings put global package_verifier_enable 0
83```
84
85### Using Emulators
86
87Running tests on emulators is the same as [on device](#Running-Tests). Refer to
88[android_emulator.md](/docs/android_emulator.md) for setting up emulators.
89
90## Building Tests
91
92If you're adding a new test file, you'll need to explicitly add it to a gn
93target. If you're adding a test to an existing file, you won't need to make gn
94changes, but you may be interested in where your test winds up. In either case,
95here are some guidelines for where a test belongs:
96
97### C++
98
99C++ test files typically belong in `<top-level directory>_unittests` (e.g.
100`base_unittests` for `//base`). There are a few exceptions -- browser tests are
101typically their own target (e.g. `content_browsertests` for `//content`, or
102`browser_tests` for `//chrome`), and some unit test suites are broken at the
103second directory rather than the top-level one.
104
105### Java
106
107Java test files vary a bit more widely than their C++ counterparts:
108
109- Instrumentation test files -- i.e., tests that will run on a device --
110 typically belong in either `<top-level directory>_javatests` or `<top-level
111 directory>_test_java`. Regardless, they'll wind up getting packaged into one
112 of a few test APKs:
113 - `webview_instrumentation_test_apk` for anything in `//android_webview`
114 - `content_shell_test_apk` for anything in `//content` or below
115 - `chrome_public_test_apk` for most things in `//chrome`
116- JUnit or Robolectric test files -- i.e., tests that will run on the host --
117 typically belong in `<top-level directory>_junit_tests` (e.g.
118 `base_junit_tests` for `//base`), though here again there are cases
119 (particularly in `//components`) where suites are split at the second
120 directory rather than the top-level one.
121
122Once you know what to build, just do it like you normally would build anything
123else, e.g.: `ninja -C out/Release chrome_public_test_apk`
124
125### Determining Test Target
126
127If you do not know what target a test file belongs to, you can use
128`//tools/autotest.py` to figure it out fo you:
129
130```sh
131# Builds relevant test target and then runs the test:
132tools/autotest.py -C <output directory> TestClassName
133```
134
135## Running Tests
136
137All functional tests should be runnable via the wrapper scripts generated at
138build time:
139
140```sh
141<output directory>/bin/run_<target_name> [options]
142```
143
144Note that tests are sharded across all attached devices unless explicitly told
145to do otherwise by `-d/--device`.
146
147The commands used by the buildbots are printed in the logs. Look at
148https://build.chromium.org/ to duplicate the same test command as a particular
149builder.
150
151### Listing Available Tests
152
153Use `--list-tests` to list what tests are available.
154
155```sh
156# Prints out all available tests:
157<output directory>/bin/run_<target_name> --list-tests
158
159# Prints out all available tests that match a filter:
160<output directory>/bin/run_<target_name> --list-tests -f "*MyFilter*"
161```
162
163### INSTALL\_FAILED\_CONTAINER\_ERROR or INSTALL\_FAILED\_INSUFFICIENT\_STORAGE
164
165If you see this error when the test runner is attempting to deploy the test
166binaries to the AVD emulator, you may need to resize your userdata partition
167with the following commands:
168
169```shell
170# Resize userdata partition to be 1G
171resize2fs android_emulator_sdk/sdk/system-images/android-25/x86/userdata.img 1G
172
173# Set filesystem parameter to continue on errors; Android doesn't like some
174# things e2fsprogs does.
175tune2fs -e continue android_emulator_sdk/sdk/system-images/android-25/x86/userdata.img
176```
177
178### AdbCommandFailedError: failed to stat remote object
179
180There's a known issue (https://crbug.com/1094062) where the unit test binaries can fail on
181Android R and later: if you see this error, try rerunning on an Android version
182with API level <= 29 (Android <= Q).
183
184## Symbolizing Crashes
185
186Crash stacks are logged and can be viewed using `adb logcat`. To symbolize the
187traces, define `CHROMIUM_OUTPUT_DIR=$OUTDIR` where `$OUTDIR` is the argument you
188pass to `ninja -C`, and pipe the output through
189`third_party/android_platform/development/scripts/stack`. If
190`$CHROMIUM_OUTPUT_DIR` is unset, the script will search `out/Debug` and
191`out/Release`. For example:
192
193```shell
194# If you build with
195ninja -C out/Debug chrome_public_test_apk
196# You can run:
197adb logcat -d | third_party/android_platform/development/scripts/stack
198
199# If you build with
200ninja -C out/android chrome_public_test_apk
201# You can run:
202adb logcat -d | CHROMIUM_OUTPUT_DIR=out/android third_party/android_platform/development/scripts/stack
203# or
204export CHROMIUM_OUTPUT_DIR=out/android
205adb logcat -d | third_party/android_platform/development/scripts/stack
206```
207
208## Robolectric Tests
209
210JUnit tests are Java unittests running on the host instead of the target device.
211They are faster to run and therefore are recommended over instrumentation tests
212when possible.
213
214The JUnits tests are usually following the pattern of *target*\_junit\_tests,
215for example, `content_junit_tests` and `chrome_junit_tests`.
216
217When adding a new JUnit test, the associated `BUILD.gn` file must be updated.
218For example, adding a test to `chrome_junit_tests` requires to update
219`chrome/android/BUILD.gn`.
220
221```shell
222# Build the test suite.
223ninja -C out/Default chrome_junit_tests
224
225# Run the test suite.
226out/Default/bin/run_chrome_junit_tests
227
228# Run a subset of tests. You might need to pass the package name for some tests.
229out/Default/bin/run_chrome_junit_tests -f "org.chromium.chrome.browser.media.*"
230```
231
232### Debugging
233
234Similar to [debugging apk targets](/docs/android_debugging_instructions.md#debugging-java):
235
236```shell
237out/Default/bin/run_chrome_junit_tests --wait-for-java-debugger
238out/Default/bin/run_chrome_junit_tests --wait-for-java-debugger # Specify custom port via --debug-socket=9999
239```
240
241## Gtests
242
243```shell
244# Build a test suite
245ninja -C out/Release content_unittests
246
247# Run a test suite
248out/Release/bin/run_content_unittests [-vv]
249
250# Run a subset of tests and enable some "please go faster" options:
251out/Release/bin/run_content_unittests --fast-local-dev -f "ByteStreamTest.*"
252```
253
254## Instrumentation Tests
255
256In order to run instrumentation tests, you must leave your device screen ON and
257UNLOCKED. Otherwise, the test will timeout trying to launch an intent.
258Optionally you can disable screen lock under Settings -> Security -> Screen Lock
259-> None.
260
261Next, you need to build the app, build your tests, and then run your tests
262(which will install the APK under test and the test APK automatically).
263
264Examples:
265
266ContentShell tests:
267
268```shell
269# Build the tests:
270ninja -C out/Release content_shell_test_apk
271
272# Run the test suite:
273out/Release/bin/run_content_shell_test_apk [-vv]
274
275# Run a subset of tests and enable some "please go faster" options:
276out/Release/bin/run_content_shell_test_apk --fast-local-dev -f "*TestClass*"
277```
278
279Android WebView tests:
280
281See [WebView's instructions](/android_webview/docs/test-instructions.md).
282
283In order to run a subset of tests, use -f to filter based on test class/method
284or -A/-E to filter using annotations.
285
286More Filtering examples:
287
288```shell
289# Run a specific test class
290out/Debug/bin/run_content_shell_test_apk -f "AddressDetectionTest.*"
291
292# Run a specific test method
293out/Debug/bin/run_content_shell_test_apk -f AddressDetectionTest#testAddressLimits
294
295# Run a subset of tests by size (Smoke, SmallTest, MediumTest, LargeTest,
296# EnormousTest)
297out/Debug/bin/run_content_shell_test_apk -A Smoke
298
299# Run a subset of tests by annotation, such as filtering by Feature
300out/Debug/bin/run_content_shell_test_apk -A Feature=Navigation
301```
302
303You might want to add stars `*` to each as a regular expression, e.g.
304`*`AddressDetectionTest`*`
305
306### Debugging
307
308Similar to [debugging apk targets](/docs/android_debugging_instructions.md#debugging-java):
309
310```shell
311out/Debug/bin/run_content_shell_test_apk --wait-for-java-debugger
312```
313
314### Deobfuscating Java Stacktraces
315
316If running with `is_debug=false`, Java stacks from logcat need to be fixed up:
317
318```shell
319build/android/stacktrace/java_deobfuscate.py out/Release/apks/ChromePublicTest.apk.mapping < stacktrace.txt
320```
321
322Any stacks produced by test runner output will already be deobfuscated.
323
324
325## Running Blink Web Tests
326
327See [Web Tests](web_tests.md).
328
329## Running Telemetry (Perf) Tests
330
331See [Telemetry](https://chromium.googlesource.com/catapult/+/HEAD/telemetry/README.md).
332
333## Running GPU tests
334
335(e.g. the "Android Debug (Nexus 7)" bot on the chromium.gpu waterfall)
336
337See https://www.chromium.org/developers/testing/gpu-testing for details. Use
338`--browser=android-content-shell`. Examine the stdio from the test invocation on
339the bots to see arguments to pass to `src/content/test/gpu/run_gpu_test.py`.