jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 1 | --- |
| 2 | layout: documentation |
| 3 | title: Android Instrumentation Tests |
| 4 | --- |
| 5 | |
| 6 | # Android Instrumentation Tests |
| 7 | |
| 8 | _If you're new to Bazel, please start with the [Building Android with |
| 9 | Bazel](https://docs.bazel.build/versions/master/tutorial/android-app.html) |
| 10 | tutorial._ |
| 11 | |
| 12 |  |
| 13 | |
| 14 | [`android_instrumentation_test`](https://docs.bazel.build/versions/master/be/android.html#android_instrumentation_test) |
| 15 | allows developers to test their apps on Android emulators and devices. |
| 16 | It utilizes real Android framework APIs and the Android Test Library. |
| 17 | |
| 18 | For hermeticity and reproducibility, Bazel creates and launches Android |
| 19 | emulators in a sandbox, ensuring that tests always run from a clean state. Each |
| 20 | test gets an isolated emulator instance, allowing tests to run in parallel |
| 21 | without passing states between them. |
| 22 | |
| 23 | For more information on Android instrumentation tests, check out the [Android |
| 24 | developer |
| 25 | documentation](https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html). |
| 26 | |
| 27 | The current state is __experimental__ as of Bazel 0.12.0. Please file issues in |
| 28 | the [GitHub issue tracker](https://github.com/bazelbuild/bazel/issues). |
| 29 | |
| 30 | **Table of Contents** |
| 31 | |
| 32 | - [How it works](#how-it-works) |
| 33 | - [Prerequisites](#prerequisites) |
| 34 | - [Getting started](#getting-started) |
| 35 | - [`BUILD` file](#build-file) |
| 36 | - [`WORKSPACE` dependencies](#workspace-dependencies) |
| 37 | - [Maven dependencies](#maven-dependencies) |
| 38 | - [Choosing an `android_device` target](#choosing-an-android_device-target) |
| 39 | - [Running tests](#running-tests) |
| 40 | - [Headless testing](#headless-testing) |
| 41 | - [GUI testing](#gui-testing) |
| 42 | - [Testing with a local emulator or device](#testing-with-a-local-emulator-or-device) |
| 43 | - [Sample projects](#sample-projects) |
| 44 | - [Tips](#tips) |
| 45 | - [Reading test logs](#reading-test-logs) |
| 46 | - [Testing against multiple API levels](#testing-against-multiple-api-levels) |
| 47 | - [Known issues](#known-issues) |
| 48 | - [Planned features](#planned-features) |
| 49 | |
| 50 | # How it works |
| 51 | |
| 52 | When you run `bazel test` on an `android_instrumentation_test` target for the |
| 53 | first time, Bazel performs the following steps: |
| 54 | |
| 55 | 1. Builds the test APK, APK under test, and their transitive dependencies |
| 56 | 2. Creates, boots, and caches clean emulator states |
| 57 | 3. Starts the emulator |
| 58 | 4. Installs the APKs |
| 59 | 5. Runs tests utilizing the [Android Test Orchestrator](https://developer.android.com/training/testing/junit-runner.html#using-android-test-orchestrator) |
| 60 | 6. Shuts down the emulator |
| 61 | 7. Reports the results |
| 62 | |
| 63 | In subsequent test runs, Bazel boots the emulator from the clean, cached state |
| 64 | created in step 2, so there are no leftover states from previous runs. Caching |
| 65 | emulator state also speeds up test runs. |
| 66 | |
| 67 | # Prerequisites |
| 68 | |
| 69 | Ensure your enivornment satisfies the following prerequisites: |
| 70 | |
| 71 | - **Linux**. Tested on Ubuntu 14.04 and 16.04. |
| 72 | |
| 73 | - **Bazel 0.12.0** or later. Verify the version by running `bazel info release`. |
| 74 | |
| 75 | ``` |
| 76 | $ bazel info release |
| 77 | release 0.12.0 |
| 78 | ``` |
| 79 | |
| 80 | - **KVM**. Bazel requires emulators to have [hardware |
| 81 | acceleration](https://developer.android.com/studio/run/emulator-acceleration.html#accel-check) |
| 82 | with KVM on Linux. You can follow these |
| 83 | [installation instructions](https://help.ubuntu.com/community/KVM/Installation) |
| 84 | for Ubuntu. Run `apt-get install cpu-checker && kvm-ok` to verify that KVM has |
| 85 | the correct configuration. If it prints the following message, you're good to |
| 86 | go: |
| 87 | |
| 88 | ``` |
| 89 | $ kvm-ok |
| 90 | INFO: /dev/kvm exists |
| 91 | KVM acceleration can be used |
| 92 | ``` |
| 93 | |
| 94 | - **Xvfb**. To run headless tests (for example, on CI servers), Bazel requires |
| 95 | the [X virtual framebuffer](https://www.x.org/archive/X11R7.6/doc/man/man1/Xvfb.1.xhtml). |
| 96 | Install it by running `apt-get install xvfb`. Verify that `Xvfb` is installed |
| 97 | correctly by running `which Xvfb` and ensure that it's installed at |
| 98 | `/usr/bin/Xvfb`: |
| 99 | |
| 100 | ``` |
| 101 | $ which Xvfb |
| 102 | /usr/bin/Xvfb |
| 103 | ``` |
| 104 | |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 105 | # Getting started |
| 106 | |
| 107 | Here is a typical target dependency graph of an `android_instrumentation_test`: |
| 108 | |
| 109 |  |
| 110 | |
| 111 | ## `BUILD` file |
| 112 | |
| 113 | The graph translates into a `BUILD` file like this: |
| 114 | |
| 115 | ```python |
| 116 | load("@gmaven_rules//:defs.bzl", "gmaven_artifact") |
| 117 | |
| 118 | android_instrumentation_test( |
| 119 | name = "my_test", |
| 120 | test_app = ":my_test_app", |
| 121 | target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2", |
| 122 | ) |
| 123 | |
| 124 | # Test app and library |
| 125 | android_binary( |
| 126 | name = "my_test_app", |
| 127 | instruments = ":my_app", |
| 128 | manifest = "AndroidTestManifest.xml", |
| 129 | deps = [":my_test_lib"], |
| 130 | # ... |
| 131 | ) |
| 132 | |
| 133 | android_library( |
| 134 | name = "my_test_lib", |
| 135 | srcs = glob(["javatest/**/*.java"]), |
| 136 | deps = [ |
| 137 | ":my_app_lib", |
| 138 | gmaven_artifact("com.android.support.test.espresso:espresso_core:aar:3.0.1"), |
| 139 | ], |
| 140 | # ... |
| 141 | ) |
| 142 | |
| 143 | # Target app and library under test |
| 144 | android_binary( |
| 145 | name = "my_app", |
| 146 | manifest = "AndroidManifest.xml", |
| 147 | deps = [":my_app_lib"], |
| 148 | # ... |
| 149 | ) |
| 150 | |
| 151 | android_library( |
| 152 | name = "my_app_lib", |
| 153 | srcs = glob(["java/**/*.java"]), |
| 154 | deps = [ |
| 155 | gmaven_artifact("com.android.support:design:aar:27.0.2"), |
| 156 | gmaven_artifact("com.android.support:support_annotations:jar:27.0.2"), |
| 157 | ] |
| 158 | # ... |
| 159 | ) |
| 160 | ``` |
| 161 | |
| 162 | The main attributes of the rule `android_instrumentation_test` are: |
| 163 | |
| 164 | - `test_app`: An `android_binary` target. This target contains test code and |
| 165 | dependencies like Espresso and UIAutomator. The selected `android_binary` |
| 166 | target is required to specify an `instruments` attribute pointing to another |
| 167 | `android_binary`, which is the app under test. |
| 168 | |
| 169 | - `target_device`: An `android_device` target. This target describes the |
| 170 | specifications of the Android emulator which Bazel uses to create, launch and |
| 171 | run the tests. See the [section on choosing an Android |
| 172 | device](#choosing-an-android_device) for more information. |
| 173 | |
| 174 | ## `WORKSPACE` dependencies |
| 175 | |
| 176 | In order to use this rule, your project needs to depend on these external |
| 177 | repositories: |
| 178 | |
| 179 | - `@androidsdk`: The Android SDK. Download this through Android Studio. |
| 180 | |
| 181 | - `@android_test_support`: Hosts the test runner, emulator launcher, and |
| 182 | `android_device` targets. |
| 183 | |
| 184 | - `@gmaven_rules`: Defines the `maven_jar` and `maven_aar` targets available on |
| 185 | the [Google Maven repository](https://maven.google.com). |
| 186 | |
| 187 | You can enable these dependencies by adding the following lines to your |
| 188 | `WORKSPACE` file: |
| 189 | |
| 190 | ```python |
| 191 | # Android SDK |
| 192 | android_sdk_repository( |
| 193 | name = "androidsdk", |
| 194 | path = "/path/to/sdk", # or set ANDROID_HOME |
| 195 | ) |
| 196 | |
| 197 | # Android Test Support |
| 198 | ATS_COMMIT = "$COMMIT_HASH" |
| 199 | http_archive( |
| 200 | name = "android_test_support", |
jingwen | c251ead | 2018-05-16 15:07:25 -0700 | [diff] [blame] | 201 | strip_prefix = "android-test-%s" % ATS_COMMIT", |
| 202 | urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_COMMIT], |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 203 | ) |
| 204 | load("@android_test_support//:repo.bzl", "android_test_repositories") |
| 205 | android_test_repositories() |
| 206 | |
| 207 | # Google Maven Repository |
jingwen | a5876cd | 2018-04-16 09:05:05 -0700 | [diff] [blame] | 208 | GMAVEN_TAG = "0.1.0" |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 209 | http_archive( |
| 210 | name = "gmaven_rules", |
jingwen | a5876cd | 2018-04-16 09:05:05 -0700 | [diff] [blame] | 211 | strip_prefix = "gmaven_rules-%s" % GMAVEN_TAG, |
| 212 | urls = ["https://github.com/bazelbuild/gmaven_rules/archive/%s.tar.gz" % GMAVEN_TAG], |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 213 | ) |
| 214 | load("@gmaven_rules//:gmaven.bzl", "gmaven_rules") |
| 215 | gmaven_rules() |
| 216 | ``` |
| 217 | |
| 218 | # Maven dependencies |
| 219 | |
| 220 | Use the |
| 221 | [maven_jar](https://docs.bazel.build/versions/master/be/workspace.html#maven_jar) |
| 222 | repository rule for Maven dependencies not hosted on Google Maven. For example, |
| 223 | to use JUnit 4.12 and Hamcrest 2, add the following lines to your `WORKSPACE`: |
| 224 | |
| 225 | ``` |
| 226 | maven_jar( |
| 227 | name = "junit_junit", |
| 228 | artifact = "junit:junit:4.12", |
| 229 | ) |
| 230 | |
| 231 | maven_jar( |
| 232 | name = "org_hamcrest_java_hamcrest", |
| 233 | artifact = "org.hamcrest:java-hamcrest:2.0.0.0", |
| 234 | ) |
| 235 | ``` |
| 236 | |
| 237 | Then, you can depend on them in your `BUILD` files: |
| 238 | |
| 239 | ```python |
| 240 | java_library( |
| 241 | name = "test_deps", |
| 242 | visibility = ["//visibility:public"], |
| 243 | exports = [ |
| 244 | "@junit_junit//jar", |
| 245 | "@org_hamcrest_java_hamcrest//jar", |
| 246 | ], |
| 247 | ) |
| 248 | |
| 249 | android_library( |
| 250 | name = "my_test_lib", |
| 251 | srcs = [..], |
| 252 | deps = [":test_deps"], |
| 253 | ) |
| 254 | ``` |
| 255 | |
| 256 | [`bazel-deps`](https://github.com/johnynek/bazel-deps) is another useful tool |
| 257 | for managing Maven dependencies using [a `YAML` |
| 258 | file](https://github.com/johnynek/bazel-deps/blob/master/dependencies.yaml). |
| 259 | |
jingwen | a5876cd | 2018-04-16 09:05:05 -0700 | [diff] [blame] | 260 | For dependencies hosted on [Google's Maven |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 261 | repository](https://maven.google.com), [`@gmaven_rules`](https://github.com/bazelbuild/gmaven_rules) |
| 262 | provides a simple way to fetch dependencies hosted with `gmaven_artifact`. |
| 263 | |
| 264 | `gmaven_artifact` is a macro that maps an artifact's coordinate to the actual |
| 265 | generated target in |
| 266 | [`gmaven.bzl`](https://raw.githubusercontent.com/bazelbuild/gmaven_rules/master/gmaven.bzl) |
| 267 | (warning: big file!). The packaging type defaults to `jar` if it isn't |
| 268 | specified. |
| 269 | |
| 270 | Load the `gmaven_artifact` macro at the beginning of your `BUILD` file to use |
| 271 | it: |
| 272 | |
| 273 | ```python |
| 274 | load("@gmaven_rules//:defs.bzl", "gmaven_artifact") |
| 275 | |
| 276 | android_library( |
| 277 | name = "my_app_lib", |
| 278 | srcs = glob(["java/**/*.java"]), |
| 279 | deps = [ |
| 280 | gmaven_artifact("com.android.support:design:aar:27.0.2"), |
| 281 | gmaven_artifact("com.android.support:support_annotations:jar:27.0.2"), |
| 282 | ] |
| 283 | # ... |
| 284 | ) |
| 285 | ``` |
| 286 | |
| 287 | # Choosing an android_device target |
| 288 | |
| 289 | `android_instrumentation_test.target_device` specifies which Android device to |
| 290 | run the tests on. These `android_device` targets are defined in |
| 291 | [`@android_test_support`](https://github.com/google/android-testing-support-library/tree/master/tools/android/emulated_devices). |
| 292 | |
| 293 | ```python |
| 294 | $ bazel query --output=build @android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2 |
| 295 | # .../external/android_test_support/tools/android/emulated_devices/generic_phone/BUILD:43:1 |
| 296 | android_device( |
| 297 | name = "android_23_x86_qemu2", |
| 298 | visibility = ["//visibility:public"], |
| 299 | tags = ["requires-kvm"], |
| 300 | generator_name = "generic_phone", |
| 301 | generator_function = "make_device", |
| 302 | generator_location = "tools/android/emulated_devices/generic_phone/BUILD:43", |
| 303 | vertical_resolution = 800, |
| 304 | horizontal_resolution = 480, |
| 305 | ram = 2048, |
| 306 | screen_density = 240, |
| 307 | cache = 32, |
| 308 | vm_heap = 256, |
| 309 | system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_qemu2_images", |
| 310 | default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_23_x86_qemu2_props", |
| 311 | ) |
| 312 | ``` |
| 313 | |
| 314 | The device target names use this template: |
| 315 | |
| 316 | ``` |
| 317 | @android_test_support//tools/android/emulated_devices/${device_type}:${system}_${api_level}_x86_qemu2 |
| 318 | ``` |
| 319 | |
| 320 | In order to launch an `android_device`, the `system_image` for the selected API |
| 321 | level is required. To download the system image, use Android SDK's |
| 322 | `tools/bin/sdkmanager`. For example, to download the system image for |
| 323 | `generic_phone:android_23_x86_qemu2`, run `$sdk/tools/bin/sdkmanager |
| 324 | "system-images;android-23;default;x86"`. |
| 325 | |
| 326 | To see the full list of supported `android_device` targets in |
| 327 | `@android_test_support`, run the following command: |
| 328 | |
| 329 | ``` |
| 330 | bazel query 'filter("x86_qemu2$", kind(android_device, @android_test_support//tools/android/emulated_devices/...:*))' |
| 331 | ``` |
| 332 | |
| 333 | Bazel currently supports x86-based emulators only. For better performance, |
| 334 | we also recommend using `QEMU2` `android_device` targets instead of `QEMU` ones. |
| 335 | |
| 336 | # Running tests |
| 337 | |
| 338 | To run tests, add these lines to your project's `tools/bazel.rc` file. |
| 339 | |
| 340 | ``` |
| 341 | # Configurations for testing with Bazel |
| 342 | # Select a configuration by running |
| 343 | # `bazel test //my:target --config={headless, gui, local_device}` |
| 344 | |
| 345 | # Headless instrumentation tests |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 346 | test:headless --test_arg=--enable_display=false |
| 347 | |
| 348 | # Graphical instrumentation tests. Ensure that $DISPLAY is set. |
| 349 | test:gui --test_env=DISPLAY |
| 350 | test:gui --test_arg=--enable_display=true |
| 351 | |
| 352 | # Testing with a local emulator or device. Ensure that `adb devices` lists the |
| 353 | # device. |
| 354 | # Run tests serially. |
| 355 | test:local_device --test_strategy=exclusive |
| 356 | # Use the local device broker type, as opposed to WRAPPED_EMULATOR. |
| 357 | test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER |
| 358 | # Uncomment and set $device_id if there is more than one connected device. |
| 359 | # test:local_device --test_arg=--device_serial_number=$device_id |
| 360 | ``` |
| 361 | |
| 362 | Then, use one of the configurations to run tests: |
| 363 | |
| 364 | - `bazel test //my/test:target --config=headless` |
| 365 | - `bazel test //my/test:target --config=gui` |
| 366 | - `bazel test //my/test:target --config=local_device` |
| 367 | |
| 368 | Use __only one configuration__ or tests will fail. |
| 369 | |
| 370 | ## Headless testing |
| 371 | |
jingwen | b083de8 | 2018-04-30 07:53:09 -0700 | [diff] [blame] | 372 | With `Xvfb`, it is possible to test with emulators without the graphical |
| 373 | interface, also known as headless testing. To disable the graphical interface |
| 374 | when running tests, pass the test argument `--enable_display=false` to Bazel: |
| 375 | |
| 376 | ``` |
| 377 | bazel test //my/test:target --test_arg=--enable_display=false |
| 378 | ``` |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 379 | |
| 380 | ## GUI testing |
| 381 | |
jingwen | b083de8 | 2018-04-30 07:53:09 -0700 | [diff] [blame] | 382 | If the `$DISPLAY` environment variable is set, it's possible to enable the |
| 383 | graphical interface of the emulator while the test is running. To do this, pass |
| 384 | these test arguments to Bazel: |
| 385 | |
| 386 | ``` |
| 387 | bazel test //my/test:target --test_arg=--enable_display --test_env=DISPLAY |
| 388 | ``` |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 389 | |
| 390 | ## Testing with a local emulator or device |
| 391 | |
| 392 | Bazel also supports testing directly on a locally launched emulator or connected |
| 393 | device. Pass the flags |
| 394 | `--test_strategy=exclusive` and |
| 395 | `--test_arg=--device_broker_type=LOCAL_ADB_SERVER` to enable local testing mode. |
| 396 | If there is more than one connected device, pass the flag |
| 397 | `--test_arg=--device_serial_number=$device_id` where `$device_id` is the id of |
| 398 | the device/emulator listed in `adb devices`. |
| 399 | |
| 400 | # Sample projects |
| 401 | |
| 402 | If you are looking for canonical project samples, see the [Android testing |
| 403 | samples](https://github.com/googlesamples/android-testing#experimental-bazel-support) |
| 404 | for projects using Espresso and UIAutomator. |
| 405 | |
| 406 | ``` |
| 407 | $ git clone https://github.com/googlesamples/android-testing && cd android-testing |
| 408 | # Set path to Android SDK in WORKSPACE |
| 409 | $ bazel test //ui/... --config=headless |
| 410 | INFO: Analysed 45 targets (1 packages loaded). |
| 411 | INFO: Found 36 targets and 9 test targets... |
| 412 | |
| 413 | ... |
| 414 | |
| 415 | INFO: Elapsed time: 195.665s, Critical Path: 195.22s |
| 416 | INFO: Build completed successfully, 417 total actions |
| 417 | //ui/espresso/BasicSample:BasicSampleInstrumentationTest PASSED in 103.7s |
| 418 | //ui/espresso/CustomMatcherSample:CustomMatcherSampleInstrumentationTest PASSED in 113.2s |
| 419 | //ui/espresso/DataAdapterSample:DataAdapterSampleInstrumentationTest PASSED in 110.2s |
| 420 | //ui/espresso/IdlingResourceSample:IdlingResourceSampleInstrumentationTest PASSED in 102.3s |
| 421 | //ui/espresso/IntentsAdvancedSample:IntentsAdvancedSampleInstrumentationTest PASSED in 98.3s |
| 422 | //ui/espresso/IntentsBasicSample:IntentsBasicSampleInstrumentationTest PASSED in 103.3s |
| 423 | //ui/espresso/MultiWindowSample:MultiWindowSampleInstrumentationTest PASSED in 108.3s |
| 424 | //ui/espresso/RecyclerViewSample:RecyclerViewSampleInstrumentationTest PASSED in 102.9s |
| 425 | //ui/uiautomator/BasicSample:BasicSampleInstrumentationTest PASSED in 122.6s |
| 426 | ``` |
| 427 | |
| 428 | # Tips |
| 429 | |
| 430 | ## Reading test logs |
| 431 | |
| 432 | Use `--test_output=errors` to print logs for failing tests, or |
| 433 | `--test_output=all` to print all test output. If you're looking for an |
| 434 | individual test log, go to |
| 435 | `$PROJECT_ROOT/bazel-testlogs/path/to/InstrumentationTestTargetName`. |
| 436 | |
| 437 | For example, the test logs for `BasicSample` canonical project are in |
| 438 | `bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest`: |
| 439 | |
| 440 | ``` |
| 441 | $ tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest |
| 442 | . |
| 443 | ├── adb.409923.log |
| 444 | ├── broker_logs |
| 445 | │ ├── aapt_binary.10.ok.txt |
| 446 | │ ├── aapt_binary.11.ok.txt |
| 447 | │ ├── adb.12.ok.txt |
| 448 | │ ├── adb.13.ok.txt |
| 449 | │ ├── adb.14.ok.txt |
| 450 | │ ├── adb.15.fail.txt |
| 451 | │ ├── adb.16.ok.txt |
| 452 | │ ├── adb.17.fail.txt |
| 453 | │ ├── adb.18.ok.txt |
| 454 | │ ├── adb.19.fail.txt |
| 455 | │ ├── adb.20.ok.txt |
| 456 | │ ├── adb.21.ok.txt |
| 457 | │ ├── adb.22.ok.txt |
| 458 | │ ├── adb.23.ok.txt |
| 459 | │ ├── adb.24.fail.txt |
| 460 | │ ├── adb.25.ok.txt |
| 461 | │ ├── adb.26.fail.txt |
| 462 | │ ├── adb.27.ok.txt |
| 463 | │ ├── adb.28.fail.txt |
| 464 | │ ├── adb.29.ok.txt |
| 465 | │ ├── adb.2.ok.txt |
| 466 | │ ├── adb.30.ok.txt |
| 467 | │ ├── adb.3.ok.txt |
| 468 | │ ├── adb.4.ok.txt |
| 469 | │ ├── adb.5.ok.txt |
| 470 | │ ├── adb.6.ok.txt |
| 471 | │ ├── adb.7.ok.txt |
| 472 | │ ├── adb.8.ok.txt |
| 473 | │ ├── adb.9.ok.txt |
| 474 | │ ├── android_23_x86_qemu2.1.ok.txt |
| 475 | │ └── exec-1 |
| 476 | │ ├── adb-2.txt |
| 477 | │ ├── emulator-2.txt |
| 478 | │ └── mksdcard-1.txt |
| 479 | ├── device_logcat |
| 480 | │ └── logcat1635880625641751077.txt |
| 481 | ├── emulator_itCqtc.log |
| 482 | ├── outputs.zip |
| 483 | ├── pipe.log.txt |
| 484 | ├── telnet_pipe.log.txt |
| 485 | └── tmpuRh4cy |
| 486 | ├── watchdog.err |
| 487 | └── watchdog.out |
| 488 | |
| 489 | 4 directories, 41 files |
| 490 | ``` |
| 491 | |
jingwen | b083de8 | 2018-04-30 07:53:09 -0700 | [diff] [blame] | 492 | ## Reading emulator logs |
| 493 | |
| 494 | The emulator logs for `android_device` targets are stored in the `/tmp/` |
| 495 | directory with the name `emulator_xxxxx.log`, where `xxxxx` is a |
| 496 | randomly-generated sequence of characters. |
| 497 | |
| 498 | Use this command to find the latest emulator log: |
| 499 | |
| 500 | ``` |
| 501 | ls -1t /tmp/emulator_*.log | head -n 1 |
| 502 | ``` |
| 503 | |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 504 | ## Testing against multiple API levels |
| 505 | |
| 506 | If you would like to test against multiple API levels, you can use a list |
| 507 | comprehension to create test targets for each API level. For example: |
| 508 | |
| 509 | ```python |
| 510 | API_LEVELS = [ |
| 511 | "19", |
| 512 | "20", |
| 513 | "21", |
| 514 | "22", |
| 515 | ] |
| 516 | |
| 517 | [android_instrumentation_test( |
| 518 | name = "my_test_%s" % API_LEVEL, |
| 519 | test_app = ":my_test_app", |
| 520 | target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_%s_x86_qemu2" % API_LEVEL, |
| 521 | ) for API_LEVEL in API_LEVELS] |
| 522 | ``` |
| 523 | |
| 524 | # Known issues |
| 525 | |
| 526 | - [Forked adb server processes are not terminated after |
| 527 | tests](https://github.com/bazelbuild/bazel/issues/4853) |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 528 | - While APK building works on all platforms (Linux, macOS, Windows), testing |
| 529 | only works on Linux. |
| 530 | - Even with `--config=local_adb`, users still need to specify |
| 531 | `android_instrumentation_test.target_device`. |
| 532 | - If using a local device or emulator, Bazel does not uninstall the APKs after |
| 533 | the test. Clean the packages by running this command: `adb shell pm list |
| 534 | packages com.example.android.testing | cut -d ':' -f 2 | tr -d '\r' | xargs |
| 535 | -L1 -t adb uninstall` |
| 536 | |
| 537 | # Planned features |
| 538 | |
jingwen | 2f96327 | 2018-04-11 20:18:44 -0700 | [diff] [blame] | 539 | - Code coverage collection |
| 540 | - macOS support |
| 541 | - Windows support |
| 542 | - Improved external dependency management |
| 543 | - Remote test caching and execution |
Jingwen Chen | b8a7184 | 2018-04-12 10:22:30 -0700 | [diff] [blame] | 544 | |
| 545 | We are planning to rewrite the Android rules in [Skylark](https://docs.bazel.build/versions/master/skylark/concepts.html). |
| 546 | The `android_instrumentation_test` rule will be part of the rewrite, however, |
| 547 | its usage will remain unchanged from the end-user perspective. |