On this page
UI tests verify what your user actually sees and taps: that a button enables when the form is valid, that a list updates after a refresh, and that a dialog appears at the right moment. Android gives you a mature toolchain for this, but the tools only pay off if the tests are written to stay fast and reliable. This guide covers which tool to reach for and how to structure the suite around it.
Know the tools before you choose one
Android's UI testing options fall into a few clear categories, and picking the wrong one is the most common reason a suite becomes slow or flaky.
| Tool | Runs where | Best for |
|---|---|---|
| Espresso | On device or emulator, inside your app process | Fast, deterministic tests of your own app's screens |
| UI Automator | On device or emulator, across apps | System dialogs, permission prompts, notifications, other apps |
| Compose UI test | On device or emulator, with the Compose test rule | Finding and acting on composables in Jetpack Compose screens |
| Robolectric | On the local JVM | Quick UI logic checks in unit tests without an emulator |
Writing Espresso tests that hold up
Espresso synchronizes with the main thread before it interacts, which is why well-written Espresso tests rarely need waits. The habits below keep it that way.
- Match on stable identifiers: give important views content descriptions or test tags instead of relying on display text that changes with translation.
- Never sleep: replace Thread.sleep calls with IdlingResource for network and background work the framework cannot see.
- Assert on outcome, not on clicks: the test should verify the state the user ends up in, such as a success message or a navigated screen.
- One behavior per test: short tests pinpoint failures, while long scenario scripts turn one broken step into an unreadable error.
- Reset state between tests: use test rules to clear app data so the suite passes the same way whether run alone or in full.
When UI Automator is the right call
Espresso cannot touch anything outside your app process. That is exactly where UI Automator comes in: granting permissions through system dialogs, pulling down the notification shade, opening Settings, or verifying a share sheet. A practical split is to keep the bulk of your suite in Espresso and use UI Automator only for the few flows that cross the app boundary.
Cover the states, not just the happy path
A UI suite that only walks the happy path misses the screens users screenshot and post about. Add cases for rotation with state restoration, dark theme, large font scale, the soft keyboard covering a submit button, offline empty states, and back navigation from every depth. Many of these are cheap to add and catch the layout bugs that generate one-star reviews.
Where humans still beat scripts
Automation asserts what you thought to check. Exploratory testers notice copy that reads oddly, spacing that looks off, and flows that make sense to the team but not to anyone else. The strongest Android teams pair a green UI suite with a human exploratory pass on real devices, which is the combination AppsTestLab builds into its functional testing workflow.
Sources & references
Official Google documentation- Espresso testingdeveloper.android.com
- UI Automatordeveloper.android.com
- Android testing guidesdeveloper.android.com
These links open Google's official Play Console Help pages used to verify this guide. AppsTestLab guidance is independent and not affiliated with Google.
Get help doing this
