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 | |
| 10 | ## Adding tests {#adding} |
| 11 | |
| 12 | For an example of how to set up simple unit and integration tests in a new |
| 13 | module, see |
| 14 | [aosp/1189799](https://android-review.googlesource.com/c/platform/frameworks/support/+/1189799). |
| 15 | For an example of how to set up Espresso-powered integration tests, see the |
| 16 | `preference` library's |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 17 | [`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] | 18 | and |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 19 | [`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] | 20 | files. |
| 21 | |
| 22 | The currently allowed test runners for on-device tests are |
| 23 | [`AndroidJUnitRunner`](https://developer.android.com/training/testing/junit-runner) |
| 24 | and |
| 25 | [`Parameterized`](https://junit.org/junit4/javadoc/4.12/org/junit/runners/Parameterized.html). |
| 26 | |
AndroidX Core Team | 03b4da3 | 2021-03-10 23:20:41 +0000 | [diff] [blame] | 27 | NOTE For best practices on writing libraries in a way that makes it easy for end |
| 28 | users -- and library developers -- to write tests, see the |
| 29 | [Testability](testability.md) guide. |
| 30 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 31 | ### What gets tested, and when |
| 32 | |
| 33 | We use the |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 34 | [AffectedModuleDetector](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt) |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 35 | to determine what projects have changed since the last merge. |
| 36 | |
| 37 | In presubmit, "affected" modules will run all host and device tests regardless |
| 38 | of size. Modules that _depend_ on affected modules will run all host tests, but |
| 39 | will only run device tests annotated with `@SmallTest` or `@MediumTest`. |
| 40 | |
| 41 | When changes are made that can't be associated with a module, are in the root of |
| 42 | the checkout, or are within `buildSrc`, then all host tests and all device tests |
| 43 | annotated with `@SmallTest` or `@MediumTest` will be run for all modules. |
| 44 | |
| 45 | Presubmit tests represent only a subset of the devices on which our tests run. |
| 46 | The remaining devices are tested only in postsubmit. In postsubmit, all host and |
| 47 | device tests are run for all modules. |
| 48 | |
| 49 | ### Test annotations |
| 50 | |
| 51 | #### Test size |
| 52 | |
| 53 | All device tests *should* be given a size annotation, which is one of: |
| 54 | |
| 55 | * [`@SmallTest`](https://developer.android.com/reference/androidx/test/filters/SmallTest) |
| 56 | * [`@MediumTest`](https://developer.android.com/reference/androidx/test/filters/MediumTest) |
| 57 | * [`@LargeTest`](https://developer.android.com/reference/androidx/test/filters/LargeTest) |
| 58 | |
| 59 | If a device test is _not_ annotated with its size, it will be considered a |
| 60 | `@LargeTest` by default. Host tests do not need to be annotated with their size, |
| 61 | as all host tests are run regardless of size. |
| 62 | |
| 63 | This annotation can occur at either the class level or individual test level. |
| 64 | After API level 27, timeouts are enforced based on this annotation. |
| 65 | |
| 66 | Annotation | Max duration | Timeout after |
| 67 | ------------- | ------------ | ------------- |
| 68 | `@SmallTest` | 200ms | 300ms |
| 69 | `@MediumTest` | 1000ms | 1500ms |
| 70 | `@LargeTest` | 100000ms | 120000ms |
| 71 | |
| 72 | Small tests should be less than 200ms, and the timeout is set to 300ms. Medium |
| 73 | tests should be less than 1000ms, and the timeout is set to 1500ms. Large tests |
| 74 | have a timeout of 120000ms, which should cover any remaining tests. |
| 75 | |
| 76 | The exception to this rule is when using a runner other than |
| 77 | [`AndroidJUnitRunner`](https://developer.android.com/training/testing/junit-runner). |
| 78 | Since these runners do not enforce timeouts, tests that use them must not use a |
| 79 | size annotation. They will run whenever large tests would run. |
| 80 | |
| 81 | Currently the only allowed alternative is the |
| 82 | [`Parameterized`](https://junit.org/junit4/javadoc/4.12/org/junit/runners/Parameterized.html) |
| 83 | runner. If you need to use a different runner for some reason, please reach out |
| 84 | to the team and we can review/approve the use. |
| 85 | |
| 86 | #### Disabling tests |
| 87 | |
| 88 | To disable a device-side test in presubmit testing only -- but still have it run |
| 89 | in postsubmit -- use the |
| 90 | [`@FlakyTest`](https://developer.android.com/reference/androidx/test/filters/FlakyTest) |
| 91 | annotation. There is currently no support for presubmit-only disabling of |
| 92 | host-side tests. |
| 93 | |
| 94 | If you need to stop a host- or device-side test from running entirely, use |
| 95 | JUnit's [`@Ignore`](http://junit.sourceforge.net/javadoc/org/junit/Ignore.html) |
| 96 | annotation. Do *not* use Android's `@Suppress` annotation, which only works with |
| 97 | Android test runners and will *not* work for host-side tests. |
| 98 | |
| 99 | #### Filtering devices |
| 100 | |
| 101 | To restrict a test to a range of SDKs, use |
| 102 | [`@SdkSuppress`](https://developer.android.com/reference/androidx/test/filters/SdkSuppress) |
| 103 | which allows specifying a range with `minSdkVersion` and `maxSdkVersion`. This |
| 104 | annotation also supports targeting a specific pre-release SDK with the |
| 105 | `codeName` parameter. |
| 106 | |
| 107 | ```java |
| 108 | // Target SDKs 17 through 19, inclusive |
| 109 | @SdkSuppress(minSdkVersion = 17, maxSdkVersion = 19) |
| 110 | |
| 111 | // Target pre-release SDK R only |
| 112 | @SdkSuppress(minSdkVersion = Build.VERSION_CODES.R, isCodeName = "R") |
| 113 | ``` |
| 114 | |
| 115 | You may also gate portions of test implementation code using `SDK_INT` or |
| 116 | [`BuildCompat.isAtLeast`](https://developer.android.com/reference/androidx/core/os/BuildCompat) |
| 117 | methods. |
| 118 | |
| 119 | To restrict to only phsyical devices, use |
| 120 | [`@RequiresDevice`](https://developer.android.com/reference/androidx/test/filters/RequiresDevice). |
| 121 | |
AndroidX Core Team | 5c914c4 | 2021-02-08 17:22:57 +0000 | [diff] [blame] | 122 | NOTE [Cuttlefish](https://source.android.com/setup/create/cuttlefish) is not |
| 123 | affected by this annotation, only e.g. Studio emulators. If Cuttlefish is |
| 124 | displaying behavior that differs from a physical device, they are considering |
| 125 | that a bug in Cuttlefish, so please file those bugs instead of only looking for |
| 126 | a workaround. |
| 127 | |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 128 | ### Animations in tests |
| 129 | |
| 130 | Animations are disabled for tests by default. This helps avoid flakes due to |
| 131 | timing and also makes tests faster. |
| 132 | |
| 133 | In rare cases, like testing the animations themselves, you may want to enable |
| 134 | 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] | 135 | [`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] | 136 | |
| 137 | ## Using the emulator {#emulator} |
| 138 | |
| 139 | You can use the emulator or a real device to run tests. If you wish to use the |
| 140 | emulator, you will need to access the AVD Manager (and your downloaded emulator |
| 141 | images) using a separate "normal" instance of Android Studio. "Normal" means a |
| 142 | non-Canary build of Studio that you would use for regular app development -- the |
| 143 | important part being that it points to the Android SDK where your downloaded |
| 144 | emulator images reside. You will need to open a project to get the Tools menu -- |
| 145 | do NOT open the AndroidX project in the "normal" instance of Android Studio; |
| 146 | instead, open a normal app or create a blank project using the app wizard. |
| 147 | |
| 148 | ## Debugging with platform SDK sources {#sources} |
| 149 | |
| 150 | The platform SDK sources that are checked into the development branch may not |
| 151 | match up with the build of Android present on the emulator or your physical |
| 152 | device. As a result, the line numbers reported by the debugger may not match up |
| 153 | the actual code being run. |
| 154 | |
| 155 | If you have a copy of the sources for the build against which you are debugging, |
| 156 | you can manually specify your platform SDK source path: |
| 157 | |
| 158 | 1. Click on a module (e.g. `appcompat`) in the `Project` view |
| 159 | 1. Press `Ctrl-Shift-A` and type "Module Settings", then run the action |
| 160 | 1. In the `Project Structure` dialog, navigate to `SDKs > Android API 29 |
| 161 | Platform > Sourcepath` |
| 162 | 1. Use the `-` button to remove any paths that are present, then use the `+` |
| 163 | button to add the desired source path, ex. `<android checkout |
| 164 | root>/frameworks/base` if you are debugging against a locally-built system |
| 165 | image |
| 166 | |
| 167 | NOTE The `Project Structure` dialog reachable via `File > Project Structure` is |
| 168 | **not** the same as the `Project Structure` dialog that will allow you to |
| 169 | specify the SDK source path. You must use the "Module Settings" action as |
| 170 | directed above. |
| 171 | |
| 172 | ## Running unit and integration tests {#running} |
| 173 | |
| 174 | From Android Studio, right-click can be used to run most test targets, including |
| 175 | source files, classes within a file, or individual test methods but **not** |
| 176 | entire modules. To run a supported test target, right-click on the test target |
| 177 | and then click `Run <name of test target>`. |
| 178 | |
| 179 | To run tests for an entire module such as `appcompat`, use `Run -> Edit |
| 180 | configurations...` and use the `+` button to create a new `Android Instrumented |
| 181 | Tests` configuration. Specify the module to be tested, give it a reasonable name |
| 182 | (not "All Tests") and click `OK`, then use the `Run` menu to run the |
| 183 | configuration. |
| 184 | |
| 185 |  |
| 186 | |
| 187 | NOTE If you receive the error `JUnit version 3.8 or later expected` this means |
| 188 | that Android Studio generated an Android JUnit configuration when you actually |
| 189 | needed an Android Instrumented Tests configuration. Open the `Run -> Edit |
| 190 | configurations...` dialog and delete the configuration from Android JUnit, then |
| 191 | manually add a configuration in Android Instrumented Tests. |
| 192 | |
| 193 | ### From the command line {#running-from-shell} |
| 194 | |
| 195 | Following a successful build, tests may be run against a particular AndroidX |
| 196 | module using `gradlew`. |
| 197 | |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 198 | To run all unit or integration tests in a specific project, run the following |
| 199 | from `framework/support`: |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 200 | |
| 201 | ```shell |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 202 | # Run instrumentation tests on a connected device |
| 203 | ./gradlew <project-name>:connectedAndroidTest --info --daemon |
| 204 | |
| 205 | # Run local unit tests |
| 206 | ./gradlew <project-name>:test --info --daemon |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 207 | ``` |
| 208 | |
| 209 | substituting the Gradle project name (ex. `core`). |
| 210 | |
| 211 | To run all integration tests in the specific project and test class you're |
| 212 | working on, run |
| 213 | |
| 214 | ```shell |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 215 | ./gradlew <project-name>:connectedAndroidTest --info --daemon \ |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 216 | -Pandroid.testInstrumentationRunnerArguments.class=<fully-qualified-class>[\#testName] |
| 217 | ``` |
| 218 | |
| 219 | substituting the Gradle project name (ex. `viewpager`) and fully-qualified class |
| 220 | name (ex. `androidx.viewpager.widget.ViewPagerTest`) of your test file, |
| 221 | optionally followed by `\#testName` if you want to execute a single test in that |
AndroidX Core Team | 408c27b | 2020-12-15 15:57:00 +0000 | [diff] [blame] | 222 | file. Substitute `test` for `connectedAndroidTest` to run local unit tests. |
AndroidX Core Team | 2e416b2 | 2020-12-03 22:58:07 +0000 | [diff] [blame] | 223 | |
| 224 | If you see some weird compilation errors such as below, run `./gradlew clean` |
| 225 | first: |
| 226 | |
| 227 | ``` |
| 228 | Unknown source file : UNEXPECTED TOP-LEVEL EXCEPTION: |
| 229 | Unknown source file : com.android.dex.DexException: Multiple dex files define Landroid/content/pm/ParceledListSlice$1; |
| 230 | ``` |
| 231 | |
| 232 | ## Test apps {#testapps} |
| 233 | |
| 234 | Library developers are strongly encouraged to write test apps that exercise |
| 235 | their library's public API surface. Test apps serve multiple purposes: |
| 236 | |
| 237 | * Integration testing and validation of API testability, when paired with |
| 238 | tests |
| 239 | * Validation of API usability and developer experience, when paired with a use |
| 240 | case or critical user journey |
| 241 | * Sample documentation, when embedded into API reference docs using the |
| 242 | [`@sample` and `@Sampled` annotations](api_guidelines.md#sample-usage) |
| 243 | |
| 244 | ### Legacy test apps {#testapps-legacy} |
| 245 | |
| 246 | We have a set of legacy sample Android applications in projects suffixed with |
| 247 | `-demos`. These applications do not have tests and should not be used as test |
| 248 | apps for new APIs, but they may be useful for manual regression testing. |
| 249 | |
| 250 | 1. Click `Run/Debug Configuration` on the top of the window. |
| 251 | 1. Select the app you want to run. |
| 252 | 1. Click 'Run' button. |
| 253 | |
| 254 |  |
| 255 | |
| 256 | ## Benchmarking {#benchmarking} |
| 257 | |
| 258 | AndroidX supports benchmarking - locally with Studio/Gradle, and continuously in |
| 259 | post-submit. For more information on how to create and run benchmarks, see |
| 260 | [Benchmarking](benchmarking.md). |