AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 1 | # Testing |
| 2 | |
| 3 | [TOC] |
| 4 | |
| 5 | AndroidX contains unit and integration tests that are run automatically when a |
| 6 | change is uploaded. It also contains a number of sample applications that are |
| 7 | useful for demonstrating how to use features as well as performing manual |
| 8 | testing. |
| 9 | |
AndroidX Core Team | aa5f657 | 2023-11-28 08:39:09 -0800 | [diff] [blame] | 10 | ## Motivation |
| 11 | |
| 12 | Jetpack libraries are developed with the intention that they are functionally |
| 13 | stable and production-ready as of the first public `alpha01` release, and that |
| 14 | they remain production-ready at tip-of-tree thereafter. |
| 15 | |
| 16 | For this reason, we emphasize that continuous integration testing -- both pre- |
| 17 | and post-submit -- is the ultimate source of truth for library correctness. If |
| 18 | tests are failing at head, the library is not only at risk of blocking public |
| 19 | releases but at risk of breaking production Google apps that rely on its |
| 20 | tip-of-tree builds. |
| 21 | |
| 22 | ### API level coverage in CI |
| 23 | |
| 24 | Generally, we aim to test Jetpack libraries against (1) the earliest supported |
| 25 | API level, (2) the latest stable API level, (3) API levels with major changes, |
| 26 | (4) API levels with high concentration of devices in the field, and (5) the next |
| 27 | pre-release API level. |
| 28 | |
| 29 | In practice, this is limited by device and emulator availability and |
AndroidX Core Team | 0311522 | 2025-01-21 14:03:19 -0800 | [diff] [blame] | 30 | reliability. As of January 2025, we run tests on the following API levels: |
AndroidX Core Team | aa5f657 | 2023-11-28 08:39:09 -0800 | [diff] [blame] | 31 | |
| 32 | - API level 21: the lowest API level supported by Firebase Test Lab (FTL) |
| 33 | - API level 26: the lowest supported ARM-based emulator FTL runner, which has |
| 34 | much greater performance and stability |
AndroidX Core Team | 0311522 | 2025-01-21 14:03:19 -0800 | [diff] [blame] | 35 | - API levels 30, 33, 34, 35: the latest supported API levels, which represent |
| 36 | the majority of devices in the field |
AndroidX Core Team | aa5f657 | 2023-11-28 08:39:09 -0800 | [diff] [blame] | 37 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 38 | ## Adding tests {#adding} |
| 39 | |
| 40 | For an example of how to set up simple unit and integration tests in a new |
| 41 | module, see |
| 42 | [aosp/1189799](https://android-review.googlesource.com/c/platform/frameworks/support/+/1189799). |
| 43 | For an example of how to set up Espresso-powered integration tests, see the |
| 44 | `preference` library's |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 45 | [`build.gradle`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:preference/preference/build.gradle) |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 46 | and |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 47 | [`EditTextPreferenceTest.java`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:preference/preference/src/androidTest/java/androidx/preference/tests/EditTextPreferenceTest.java) |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 48 | files. |
| 49 | |
| 50 | The currently allowed test runners for on-device tests are |
| 51 | [`AndroidJUnitRunner`](https://developer.android.com/training/testing/junit-runner) |
| 52 | and |
| 53 | [`Parameterized`](https://junit.org/junit4/javadoc/4.12/org/junit/runners/Parameterized.html). |
| 54 | |
AndroidX Core Team | b5ba61d | 2021-06-08 09:20:36 -0700 | [diff] [blame] | 55 | NOTE All package/class/method combinations must be unique. Multiple copies of |
| 56 | the same class/method can be included e.g. under different directories, but must |
| 57 | be distinguishable by their packages. |
| 58 | |
AndroidX Core Team | 03b4da3 | 2021-03-10 23:20:41 +0000 | [diff] [blame] | 59 | NOTE For best practices on writing libraries in a way that makes it easy for end |
| 60 | users -- and library developers -- to write tests, see the |
Ian Baker | 186108e | 2023-11-20 06:54:36 -0800 | [diff] [blame] | 61 | [Testability](/docs/testability.md) guide. |
AndroidX Core Team | 03b4da3 | 2021-03-10 23:20:41 +0000 | [diff] [blame] | 62 | |
AndroidX Core Team | e11d093 | 2023-09-08 09:43:38 -0700 | [diff] [blame] | 63 | ### Adding screenshots tests using scuba library |
| 64 | |
| 65 | #### Prerequisites |
| 66 | |
| 67 | Golden project: Make sure that you have the golden directory in your root |
| 68 | checkout (sibling of frameworks directory). If not re-init your repo to fetch |
| 69 | the latest manifest file: |
| 70 | |
| 71 | ``` |
| 72 | $ repo init -u sso://android/platform/manifest \ |
| 73 | -b androidx-main && repo sync -c -j8 |
| 74 | ``` |
| 75 | |
| 76 | Set up your module: If your module is not using screenshot tests yet, you need |
| 77 | to do the initial setup. |
| 78 | |
| 79 | 1. Modify your gradle file: Add dependency on the diffing library into your |
| 80 | gradle file: |
| 81 | |
| 82 | ``` |
| 83 | androidTestImplementation project(“:test:screenshot:screenshot”) |
| 84 | ``` |
| 85 | |
| 86 | Important step: Add golden asset directory to be linked to your test apk: |
| 87 | |
| 88 | ``` |
| 89 | android { |
| 90 | sourceSets.androidTest.assets.srcDirs += |
| 91 | // For androidx project (not in ui dir) use "/../../golden/project" |
| 92 | project.rootDir.absolutePath + "/../../golden/compose/material/material" |
| 93 | } |
| 94 | ``` |
| 95 | |
| 96 | This will bundle the goldens into your apk so they can be retrieved during |
| 97 | the test. |
| 98 | |
| 99 | 2. Create directory and variable: In the golden directory, create a new |
| 100 | directory for your module (the directory that you added to your gradle file, |
| 101 | which in case of material was “compose/material/material”). |
| 102 | |
| 103 | In your test module, create a variable pointing at your new directory: |
| 104 | |
| 105 | ``` |
| 106 | const val GOLDEN_MATERIAL = "compose/material/material" |
| 107 | ``` |
| 108 | |
| 109 | #### Adding a screenshot test |
| 110 | |
| 111 | Here is an example of a minimal screenshot test for compose material. |
| 112 | |
| 113 | ``` |
| 114 | @LargeTest |
| 115 | @RunWith(JUnit4::class) |
| 116 | @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O) |
| 117 | class CheckboxScreenshotTest { |
| 118 | @get:Rule val composeTestRule = createComposeRule() |
| 119 | @get:Rule val screenshotRule = AndroidXScreenshotTestRule(GOLDEN_MATERIAL) |
| 120 | |
| 121 | @Test |
| 122 | fun checkBoxTest_checked() { |
| 123 | composeTestRule.setMaterialContent { |
| 124 | Checkbox(Modifier.wrapContentSize(Alignment.TopStart), |
| 125 | checked = true, |
| 126 | onCheckedChange = {} |
| 127 | ) |
| 128 | } |
| 129 | find(isToggleable()) |
| 130 | .captureToBitmap() |
| 131 | .assertAgainstGolden(screenshotRule, "checkbox_checked") |
| 132 | } |
| 133 | } |
| 134 | ``` |
| 135 | |
| 136 | NOTE: The string “checkbox_checked” is the unique identifier of your golden in |
| 137 | your module. We use that string to name the golden file so avoid special |
| 138 | characters. Please avoid any substrings like: golden, image etc. as there is no |
| 139 | need - instead just describe what the image contains. |
| 140 | |
| 141 | #### Guidance around diffing |
| 142 | |
| 143 | Try to take the smallest screenshot possible. This will reduce interference from |
| 144 | other elements. |
| 145 | |
| 146 | By default we use a MSSIM comparer. This one is based on similarity. However we |
| 147 | have quite a high bar currently which is 0.98 (1 is an exact match). You can |
| 148 | provide your own threshold or even opt into a pixel perfect comparer for some |
| 149 | reason. |
| 150 | |
| 151 | Note: The bigger screenshots you take the more you sacrifice in the precision as |
| 152 | you can aggregate larger diffing errors, see the examples below. |
| 153 | |
| 154 |  |
| 155 | |
| 156 | #### Generating your goldens in CI (Gerrit) |
| 157 | |
| 158 | Upload your CL to gerrit and run presubmit. You should see your test fail. |
| 159 | |
| 160 | Step 1: Click on the “Test” button below: |
| 161 | |
| 162 |  |
| 163 | |
| 164 | Step 2: Click on the “Update scuba goldens” below: |
| 165 |  |
| 166 | |
AndroidX Core Team | adb5807 | 2024-07-18 11:08:51 -0700 | [diff] [blame] | 167 | Step 3: Select the tests for which you want to update the golden images. Confirm |
| 168 | the images look correct and click on “Approve Changes” |
AndroidX Core Team | e11d093 | 2023-09-08 09:43:38 -0700 | [diff] [blame] | 169 |  |
| 170 | |
AndroidX Core Team | adb5807 | 2024-07-18 11:08:51 -0700 | [diff] [blame] | 171 | Step 4: In the Approve changes dialog box, enter the following details and click |
| 172 | on Approve: \ |
| 173 | Select gerrit host as shown in image below \ |
| 174 | Repo: platform/frameworks/support-golden \ |
| 175 | Branch: androidx-main |
| 176 |  |
| 177 | |
| 178 | Step 5: Link your original CL with the new goldens CL by setting the same Topic |
AndroidX Core Team | e11d093 | 2023-09-08 09:43:38 -0700 | [diff] [blame] | 179 | field in both CLs (any arbitrary string will do). This tells Gerrit to submit |
| 180 | the CLs together, effectively providing a reference from the original CL to the |
| 181 | new goldens. And re-run presubmit. Your tests should now pass! |
AndroidX Core Team | adb5807 | 2024-07-18 11:08:51 -0700 | [diff] [blame] | 182 |  |
AndroidX Core Team | e11d093 | 2023-09-08 09:43:38 -0700 | [diff] [blame] | 183 | |
| 184 | #### Running manually / debugging |
| 185 | |
| 186 | Screenshot tests can be run locally using pixel 2 api33 emulator. Start the |
| 187 | emulator using [these](#emulator) steps. |
| 188 | |
| 189 | Wait until the emulator is running and run the tests as you would on a regular |
| 190 | device. |
| 191 | |
| 192 | ``` |
| 193 | $ ./gradlew <module>:cAT -Pandroid.testInstrumentationRunnerArguments.class=<class> |
| 194 | ``` |
| 195 | |
| 196 | If the test passes, the results are limited to a .textproto file for each |
| 197 | screenshot test. If the test fails, the results will also contain the actual |
| 198 | screenshot and, if available, the golden reference image and the diff between |
| 199 | the two. Note that this means that if you want to regenerate the golden image, |
| 200 | you have to remove the golden image before running the test. |
| 201 | |
| 202 | To get the screenshot related results from the device onto your workstation, you |
| 203 | can run |
| 204 | |
| 205 | ``` |
| 206 | $ adb pull /sdcard/Android/data/<test-package>/cache/androidx_screenshots |
| 207 | ``` |
| 208 | |
| 209 | where test-package is the identifier of you test apk, e.g. |
| 210 | androidx.compose.material.test |
| 211 | |
| 212 | #### Locally updating the golden images |
| 213 | |
| 214 | After you run a screenshot test and pull the results to a desired location, |
| 215 | verify that the actual images are the correct ones and copy them to the golden |
| 216 | screenshots directory (the one you use to create the AndroidXScreenshotTestRule |
| 217 | with) using this script. |
| 218 | |
| 219 | ``` |
| 220 | androidx-main/frameworks/support/development/copy_screenshots_to_golden_repo.py \ |
| 221 | --input-dir=/tmp/androidx_screenshots/ --output-dir=androidx-main/golden/<test>/ |
| 222 | ``` |
| 223 | |
| 224 | Repeat for all screenshots, then create and upload a CL in the golden |
| 225 | repository. |
| 226 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 227 | ### What gets tested, and when {#affected-module-detector} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 228 | |
AndroidX Core Team | 3da6263 | 2022-10-03 11:29:25 -0700 | [diff] [blame] | 229 | With over 45000 tests executed on every CI run, it is necessary for us to run |
| 230 | only a subset of our instrumentation tests in presubmit. We use the |
AndroidX Core Team | 4cc85fa | 2021-11-23 15:58:34 +0000 | [diff] [blame] | 231 | [AffectedModuleDetector](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt) |
AndroidX Core Team | 3da6263 | 2022-10-03 11:29:25 -0700 | [diff] [blame] | 232 | to determine what projects have changed since the last merge. In turn, we only |
| 233 | generate apks and test configurations for those changed modules and their |
| 234 | dependencies. |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 235 | |
| 236 | When changes are made that can't be associated with a module, are in the root of |
| 237 | the checkout, or are within `buildSrc`, then all host tests and all device tests |
| 238 | annotated with `@SmallTest` or `@MediumTest` will be run for all modules. |
| 239 | |
| 240 | Presubmit tests represent only a subset of the devices on which our tests run. |
| 241 | The remaining devices are tested only in postsubmit. In postsubmit, all host and |
| 242 | device tests are run for all modules. |
| 243 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 244 | ### Test annotations {#annotations} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 245 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 246 | #### Test size and runners {#test-size} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 247 | |
| 248 | All device tests *should* be given a size annotation, which is one of: |
| 249 | |
| 250 | * [`@SmallTest`](https://developer.android.com/reference/androidx/test/filters/SmallTest) |
| 251 | * [`@MediumTest`](https://developer.android.com/reference/androidx/test/filters/MediumTest) |
| 252 | * [`@LargeTest`](https://developer.android.com/reference/androidx/test/filters/LargeTest) |
| 253 | |
alanv | 37fed3a2 | 2021-09-17 07:46:47 -0700 | [diff] [blame] | 254 | If a device test is *not* annotated with its size, it will be run as if it were |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 255 | `@LargeTest` by default. Host tests do not need to be annotated with their size, |
| 256 | as all host tests are run regardless of size. |
| 257 | |
| 258 | This annotation can occur at either the class level or individual test level. |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 259 | |
AndroidX Core Team | b5ba61d | 2021-06-08 09:20:36 -0700 | [diff] [blame] | 260 | Annotation | Max duration |
| 261 | ------------- | ------------ |
| 262 | `@SmallTest` | 200ms |
| 263 | `@MediumTest` | 1000ms |
| 264 | `@LargeTest` | 100000ms |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 265 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 266 | #### Disabling tests {#disabling-tests} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 267 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 268 | If you need to stop a host- or device-side test from running entirely, use |
| 269 | JUnit's [`@Ignore`](http://junit.sourceforge.net/javadoc/org/junit/Ignore.html) |
| 270 | annotation. Do *not* use Android's `@Suppress` annotation, which only works with |
| 271 | Android test runners and will *not* work for host-side tests. |
| 272 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 273 | #### Filtering devices {#filtering-devices} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 274 | |
| 275 | To restrict a test to a range of SDKs, use |
| 276 | [`@SdkSuppress`](https://developer.android.com/reference/androidx/test/filters/SdkSuppress) |
| 277 | which allows specifying a range with `minSdkVersion` and `maxSdkVersion`. This |
| 278 | annotation also supports targeting a specific pre-release SDK with the |
| 279 | `codeName` parameter. |
| 280 | |
| 281 | ```java |
| 282 | // Target SDKs 17 through 19, inclusive |
| 283 | @SdkSuppress(minSdkVersion = 17, maxSdkVersion = 19) |
| 284 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 285 | // Target pre-release SDK T only |
| 286 | @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu") |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 287 | ``` |
| 288 | |
| 289 | You may also gate portions of test implementation code using `SDK_INT` or |
| 290 | [`BuildCompat.isAtLeast`](https://developer.android.com/reference/androidx/core/os/BuildCompat) |
AndroidX Core Team | 25bc933 | 2021-08-10 11:11:26 -0700 | [diff] [blame] | 291 | methods. s To restrict to only physical devices, use |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 292 | [`@RequiresDevice`](https://developer.android.com/reference/androidx/test/filters/RequiresDevice). |
| 293 | |
AndroidX Core Team | 5c914c4 | 2021-02-08 17:22:57 +0000 | [diff] [blame] | 294 | NOTE [Cuttlefish](https://source.android.com/setup/create/cuttlefish) is not |
| 295 | affected by this annotation, only e.g. Studio emulators. If Cuttlefish is |
| 296 | displaying behavior that differs from a physical device, they are considering |
| 297 | that a bug in Cuttlefish, so please file those bugs instead of only looking for |
| 298 | a workaround. |
| 299 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 300 | ### Animations in tests {#animations} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 301 | |
| 302 | Animations are disabled for tests by default. This helps avoid flakes due to |
| 303 | timing and also makes tests faster. |
| 304 | |
| 305 | In rare cases, like testing the animations themselves, you may want to enable |
| 306 | animations for a particular test or test class. For those cases, you can use the |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 307 | [`AnimationDurationScaleRule`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationDurationScaleRule.kt). |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 308 | |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 309 | ### Robolectric {#robolectric} |
alanv | f21d4ab | 2021-08-18 07:43:40 -0700 | [diff] [blame] | 310 | |
| 311 | Robolectric tests are supported in AndroidX; however, if you targeting a |
| 312 | pre-release version of the Android SDK then you may see an error like |
| 313 | |
| 314 | ``` |
alanv | 9102ecc | 2022-08-26 07:46:41 -0700 | [diff] [blame] | 315 | java.lang.IllegalArgumentException: Package targetSdkVersion=31 > maxSdkVersion=30 |
alanv | f21d4ab | 2021-08-18 07:43:40 -0700 | [diff] [blame] | 316 | at org.robolectric.plugins.DefaultSdkPicker.configuredSdks(DefaultSdkPicker.java:118) |
| 317 | at org.robolectric.plugins.DefaultSdkPicker.selectSdks(DefaultSdkPicker.java:69) |
| 318 | ``` |
| 319 | |
| 320 | You can force Robolectric to run using an earlier version of the platform SDK by |
| 321 | creating a `<project>/src/test/resources/robolectric.properties` file with the |
| 322 | following contents: |
| 323 | |
| 324 | ``` |
alanv | 9102ecc | 2022-08-26 07:46:41 -0700 | [diff] [blame] | 325 | # Robolectric currently doesn't support API 31, so we have to explicitly specify 30 as the target |
alanv | f21d4ab | 2021-08-18 07:43:40 -0700 | [diff] [blame] | 326 | # sdk for now. Remove when no longer necessary. |
alanv | 9102ecc | 2022-08-26 07:46:41 -0700 | [diff] [blame] | 327 | sdk=30 |
alanv | f21d4ab | 2021-08-18 07:43:40 -0700 | [diff] [blame] | 328 | ``` |
| 329 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 330 | ## Using the emulator {#emulator} |
| 331 | |
| 332 | You can use the emulator or a real device to run tests. If you wish to use the |
| 333 | emulator, you will need to access the AVD Manager (and your downloaded emulator |
| 334 | images) using a separate "normal" instance of Android Studio. "Normal" means a |
| 335 | non-Canary build of Studio that you would use for regular app development -- the |
| 336 | important part being that it points to the Android SDK where your downloaded |
| 337 | emulator images reside. You will need to open a project to get the Tools menu -- |
| 338 | do NOT open the AndroidX project in the "normal" instance of Android Studio; |
| 339 | instead, open a normal app or create a blank project using the app wizard. |
| 340 | |
AndroidX Core Team | 4cc85fa | 2021-11-23 15:58:34 +0000 | [diff] [blame] | 341 | NOTE You can reuse the emulator and system images from a "normal" installation |
| 342 | of Android Studio by linking the `emulator` and `system_images` directories to a |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 343 | standard Android SDK path and restarting Android Studio. **This is set up |
| 344 | automatically by `studiow` on Google-managed devices with a standard Android SDK |
| 345 | path.** In other cases, it may be set up manually with something like: `cd |
AndroidX Core Team | 4cc85fa | 2021-11-23 15:58:34 +0000 | [diff] [blame] | 346 | prebuilts/fullsdk-darwin ln -s ~/Library/Android/sdk/emulator emulator ln -s |
AndroidX Core Team | 21ccf65 | 2022-04-01 14:53:07 +0000 | [diff] [blame] | 347 | ~/Library/Android/sdk/system-images system-images` (substituting `fullsdk-linux` |
| 348 | and your local SDK path as appropriate) |
AndroidX Core Team | 4cc85fa | 2021-11-23 15:58:34 +0000 | [diff] [blame] | 349 | |
AndroidX Core Team | 9b7c30e | 2024-12-05 09:56:33 -0800 | [diff] [blame] | 350 | ## Debugging tests |
| 351 | |
| 352 | ### Using custom platform SDK sources {#sources} |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 353 | |
| 354 | The platform SDK sources that are checked into the development branch may not |
| 355 | match up with the build of Android present on the emulator or your physical |
| 356 | device. As a result, the line numbers reported by the debugger may not match up |
| 357 | the actual code being run. |
| 358 | |
| 359 | If you have a copy of the sources for the build against which you are debugging, |
| 360 | you can manually specify your platform SDK source path: |
| 361 | |
| 362 | 1. Click on a module (e.g. `appcompat`) in the `Project` view |
| 363 | 1. Press `Ctrl-Shift-A` and type "Module Settings", then run the action |
| 364 | 1. In the `Project Structure` dialog, navigate to `SDKs > Android API 29 |
| 365 | Platform > Sourcepath` |
| 366 | 1. Use the `-` button to remove any paths that are present, then use the `+` |
| 367 | button to add the desired source path, ex. `<android checkout |
| 368 | root>/frameworks/base` if you are debugging against a locally-built system |
| 369 | image |
| 370 | |
| 371 | NOTE The `Project Structure` dialog reachable via `File > Project Structure` is |
| 372 | **not** the same as the `Project Structure` dialog that will allow you to |
| 373 | specify the SDK source path. You must use the "Module Settings" action as |
| 374 | directed above. |
| 375 | |
AndroidX Core Team | 9b7c30e | 2024-12-05 09:56:33 -0800 | [diff] [blame] | 376 | ### Accessing FTL outputs |
| 377 | |
| 378 | When we run tests on Firebase Test Lab devices, we transfer the results and |
| 379 | logcat output back to Android's test result infrastructure; however, FTL also |
| 380 | captures screen recordings of the entire test run. |
| 381 | |
| 382 | To access these videos from the Android Test Investigate page for a failed test |
| 383 | run: |
| 384 | |
| 385 | - For the failing test, go to `Artifacts tab` in the Android Test Investigate |
| 386 | page |
| 387 | - Disable `Hide empty folders` (if enabled) by clicking on it |
| 388 | - Under `Run artifacts`, click on "i" icon next to the test module to open the |
| 389 | Information tab |
| 390 | - In the Information tab to the right, click on the link next to the `logs` |
| 391 | property |
| 392 | |
| 393 | The full logcat output and screen recording are available from the `Devices` tab |
| 394 | by clicking on the test device under `Device details` and using the `Logs` and |
| 395 | `Video` tabs, respectively. |
| 396 | |
| 397 | Per-test logcat output and videos are available from the `Test cases` tab. |
| 398 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 399 | ## Running unit and integration tests {#running} |
| 400 | |
| 401 | From Android Studio, right-click can be used to run most test targets, including |
| 402 | source files, classes within a file, or individual test methods but **not** |
| 403 | entire modules. To run a supported test target, right-click on the test target |
| 404 | and then click `Run <name of test target>`. |
| 405 | |
| 406 | To run tests for an entire module such as `appcompat`, use `Run -> Edit |
| 407 | configurations...` and use the `+` button to create a new `Android Instrumented |
| 408 | Tests` configuration. Specify the module to be tested, give it a reasonable name |
| 409 | (not "All Tests") and click `OK`, then use the `Run` menu to run the |
| 410 | configuration. |
| 411 | |
| 412 |  |
| 413 | |
| 414 | NOTE If you receive the error `JUnit version 3.8 or later expected` this means |
| 415 | that Android Studio generated an Android JUnit configuration when you actually |
| 416 | needed an Android Instrumented Tests configuration. Open the `Run -> Edit |
| 417 | configurations...` dialog and delete the configuration from Android JUnit, then |
| 418 | manually add a configuration in Android Instrumented Tests. |
| 419 | |
| 420 | ### From the command line {#running-from-shell} |
| 421 | |
| 422 | Following a successful build, tests may be run against a particular AndroidX |
| 423 | module using `gradlew`. |
| 424 | |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 425 | To run all unit or integration tests in a specific project, run the following |
| 426 | from `framework/support`: |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 427 | |
| 428 | ```shell |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 429 | # Run instrumentation tests on a connected device |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 430 | ./gradlew <project-name>:connectedAndroidTest --info |
| 431 | |
| 432 | # Run instrumentation tests in Firebase Test Lab (remote) |
| 433 | ./gradlew <project-name>:ftlnexus4api21 |
| 434 | ./gradlew <project-name>:ftlpixel2api26 |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 435 | ./gradlew <project-name>:ftlpixel2api30 |
| 436 | ./gradlew <project-name>:ftlpixel2api33 |
AndroidX Core Team | 0311522 | 2025-01-21 14:03:19 -0800 | [diff] [blame] | 437 | ./gradlew <project-name>:ftlmediumphoneapi34 |
| 438 | ./gradlew <project-name>:ftlmediumphoneapi35 |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 439 | |
| 440 | # Run local unit tests |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 441 | ./gradlew <project-name>:test |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 442 | ``` |
| 443 | |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 444 | substituting the Gradle project name (ex. `:core:core`). |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 445 | |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 446 | To run a specific instrumentation test in a given project, run |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 447 | |
| 448 | ```shell |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 449 | # Run instrumentation tests on a connected device |
| 450 | ./gradlew <project-name>:connectedAndroidTest --info \ |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 451 | -Pandroid.testInstrumentationRunnerArguments.class=<fully-qualified-class>[\#testName] |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 452 | |
| 453 | # Run instrumentation tests on in Firebase Test Lab (remote) |
| 454 | ./gradlew <project-name>:ftlpixel2api30 --className=<fully-qualified-class> |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 455 | ``` |
| 456 | |
| 457 | substituting the Gradle project name (ex. `viewpager`) and fully-qualified class |
| 458 | name (ex. `androidx.viewpager.widget.ViewPagerTest`) of your test file, |
| 459 | optionally followed by `\#testName` if you want to execute a single test in that |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 460 | file |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 461 | |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 462 | If you want to run a specific unit test, you can do it using |
AndroidX Core Team | a200cb8 | 2023-03-28 15:23:28 -0700 | [diff] [blame] | 463 | [`--tests` filtering](https://docs.gradle.org/current/userguide/java_testing.html#test_filtering): |
| 464 | |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 465 | ```shell |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 466 | # Run a test for an Android library on a connected device |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 467 | ./gradlew <project-name>:test --tests androidx.core.view.DisplayCompatTest |
| 468 | |
| 469 | # Run a test for a JVM library |
AndroidX Core Team | 8c9a1c0 | 2023-03-08 14:16:36 -0800 | [diff] [blame] | 470 | ./gradlew <project-name>:testDebugUnitTest --tests |
AndroidX Core Team | a200cb8 | 2023-03-28 15:23:28 -0700 | [diff] [blame] | 471 | androidx.core.view.DisplayCompatTest |
| 472 | ``` |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 473 | |
| 474 | ## Test apps {#testapps} |
| 475 | |
| 476 | Library developers are strongly encouraged to write test apps that exercise |
| 477 | their library's public API surface. Test apps serve multiple purposes: |
| 478 | |
| 479 | * Integration testing and validation of API testability, when paired with |
| 480 | tests |
| 481 | * Validation of API usability and developer experience, when paired with a use |
| 482 | case or critical user journey |
| 483 | * Sample documentation, when embedded into API reference docs using the |
Ian Baker | 186108e | 2023-11-20 06:54:36 -0800 | [diff] [blame] | 484 | [`@sample` and `@Sampled` annotations](/docs/api_guidelines/index.md#sample-usage) |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 485 | |
| 486 | ### Legacy test apps {#testapps-legacy} |
| 487 | |
| 488 | We have a set of legacy sample Android applications in projects suffixed with |
| 489 | `-demos`. These applications do not have tests and should not be used as test |
| 490 | apps for new APIs, but they may be useful for manual regression testing. |
| 491 | |
| 492 | 1. Click `Run/Debug Configuration` on the top of the window. |
| 493 | 1. Select the app you want to run. |
| 494 | 1. Click 'Run' button. |
| 495 | |
| 496 |  |
| 497 | |
| 498 | ## Benchmarking {#benchmarking} |
| 499 | |
| 500 | AndroidX supports benchmarking - locally with Studio/Gradle, and continuously in |
| 501 | post-submit. For more information on how to create and run benchmarks, see |
Ian Baker | 186108e | 2023-11-20 06:54:36 -0800 | [diff] [blame] | 502 | [Benchmarking](/docs/benchmarking.md). |