Mobile application testing has changed significantly over the years. As development teams move toward Agile, DevOps, and continuous delivery, the need for fast and reliable automated testing has become more important than ever. In this guide, we will learn about Android Mobile Test Automation using Espresso.
What Is Espresso Android Testing?

Espresso is a UI testing framework for Android applications. It is designed to help developers and QA engineers write reliable automated tests for native Android user interfaces.
Espresso tests run alongside the Android application and interact directly with the application’s UI components.
A typical Espresso test follows a simple pattern:
- Find a UI element
- Perform an action
- Verify the result
For example:
onView(withId(R.id.loginButton)) .perform(click());onView(withId(R.id.welcomeMessage)) .check(matches(isDisplayed()));
This makes Espresso tests relatively easy to read and understand, particularly for engineers who already have some knowledge of Java or Kotlin.
Why Use Espresso for Android UI Automation?
The mobile testing landscape has become increasingly focused on fast feedback.
Modern teams often need to:
- Run tests as part of CI/CD pipelines
- Detect defects earlier in the development lifecycle
- Reduce flaky UI tests
- Receive feedback quickly after code changes
- Test the application before distributing an APK to wider QA teams
This is where native Android UI automation frameworks such as Espresso can be particularly useful.
Appium Is Not Always the Best Choice for Every Android Test
Appium remains a valuable tool for mobile automation. However, depending on the application and testing requirements, teams may encounter challenges such as:
1. Additional Test Infrastructure
Traditional Appium setups typically involve additional components such as:
- Appium Server
- Client libraries
- Platform-specific drivers
- Desired capabilities or modern capability configuration
- Device and emulator configuration
This can introduce additional setup and maintenance overhead.
2. Potential UI Test Flakiness
Mobile UI automation can become flaky when tests depend heavily on:
- Timing
- Animations
- Network responses
- Application state
- Device performance
- Synchronisation between the test and application
Espresso was designed specifically for Android and provides built-in synchronisation mechanisms that help reduce many timing-related issues.
3. The Need for Faster Feedback
Modern development teams cannot always wait for a complete end-to-end testing cycle before receiving feedback.
Developers and QA engineers increasingly want to test the application during the development process itself.
The earlier a defect is discovered, the cheaper and faster it is to fix.
This creates the need for a testing layer between:
- Unit tests, which test small pieces of code
- Full end-to-end tests, which test complete user journeys
This middle layer is where instrumented tests become important.
What Are Instrumented Tests?
Instrumented tests run on an Android device or emulator.
Unlike local unit tests, which run directly on the JVM, instrumented tests run in an Android environment and can interact with Android framework components.
This makes them suitable for testing:
- Activities
- Fragments
- Views
- User interactions
- Android UI components
- Application behaviour on a real device or emulator
A simplified Android testing structure looks like this:
app/└── src/ ├── main/ │ └── java/ │ └── Application Code │ ├── test/ │ └── java/ │ └── Local Unit Tests │ └── androidTest/ └── java/ └── Instrumented and UI Tests
The main directories are:
src/main
This contains the application source code.
src/test
This contains local unit tests that generally run on the JVM.
src/androidTest
This contains instrumented tests that run on an Android emulator or connected physical device.
Espresso tests are commonly placed inside the src/androidTest source set.
Key Features of Espresso
1. Native Android Integration
Espresso is designed specifically for Android applications.
It integrates directly with the Android testing ecosystem and works naturally with Android Studio and Gradle-based Android projects.
This means there is no need to build an entirely separate automation ecosystem around the application.
2. Automatic Synchronisation
One of Espresso’s most important features is its synchronisation mechanism.
UI automation tests can become unreliable when the test attempts to interact with an element before the application is ready.
For example:
Test starts ↓Application loads ↓Network request runs ↓UI is updated ↓Test attempts to click
If the test clicks before the UI is ready, the test may fail.
Espresso helps address this problem by synchronising test actions with the application’s UI thread and registered asynchronous operations.
In simple terms, Espresso generally waits for the application to become idle before performing the next action.
This reduces the need for manually adding arbitrary waits such as:
Thread.sleep(3000);
Avoiding unnecessary hard waits can make tests faster and more reliable.
3. No Separate Appium Server
Espresso tests do not require a separate Appium server to communicate with the application.
The tests run using Android’s testing infrastructure and interact with the application within the Android environment.
This can simplify the test setup for teams focused exclusively on native Android applications.
4. Java and Kotlin Support
Android applications are commonly developed using:
- Java
- Kotlin
Espresso supports writing tests using both languages.
For beginners, some Espresso test code can be relatively easy to understand because it follows a natural pattern:
Find the view ↓Perform an action ↓Verify the result
For example:
onView(withId(R.id.loginButton)) .perform(click());onView(withId(R.id.homeScreen)) .check(matches(isDisplayed()));
Of course, some programming knowledge is required. A basic understanding of Java or Kotlin is recommended.
5. Gradle-Based Android Projects
Android projects typically use Gradle as their build automation tool.
If you are coming from an Appium framework built with Maven, the syntax and project structure may look different.
For example, a Maven project commonly uses:
pom.xml
An Android project typically uses Gradle configuration files such as:
build.gradle
or:
build.gradle.kts
The tools are different, but the purpose is similar: manage dependencies, configure the project, and execute build and test tasks.
Getting Started with Espresso Android Testing
Let’s now look at the basic steps required to create an Espresso test.
Step 1: Open an Android Project
First, you need access to an Android application project.
The project may come from:
- Your development team
- GitHub
- GitLab
- Bitbucket
- A sample Android project
Open the project in Android Studio and allow Gradle to synchronise the project.
Step 2: Understand the Project Structure
Locate the src directory inside the Android project.
A typical structure looks like this:
src/├── main/├── test/└── androidTest/
The purpose of each directory is:
| Directory | Purpose |
|---|---|
main | Application source code |
test | Local unit tests |
androidTest | Instrumented and UI tests |
Espresso tests are generally created under:
src/androidTest
Step 3: Add Espresso Dependencies
The required testing dependencies are added to the Gradle configuration of the Android application module.
A typical configuration may look like this:
dependencies { androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'}
The exact versions may change over time, so always check the current official Android documentation when starting a new project.
You will also need an Android test runner, commonly based on the AndroidX testing framework.
For example:
android { defaultConfig { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }}
The exact configuration can vary depending on your Android project and Gradle setup.
Writing Your First Espresso Test
Now let’s look at the basic structure of an Espresso test.
A typical test performs three core operations:
1. Locate a View
Use a View Matcher to find the required UI element.
onView(withId(R.id.loginButton))
Here:
withId(R.id.loginButton)
locates the view using its resource ID.
2. Perform an Action
Once the element has been located, perform an action.
.perform(click())
The complete statement becomes:
onView(withId(R.id.loginButton)) .perform(click());
This means:
Find the view with the ID
loginButtonand click it.
3. Verify the Result
After performing an action, verify the expected result.
onView(withId(R.id.welcomeMessage)) .check(matches(isDisplayed()));
This verifies that the welcomeMessage view is displayed.
The Three Core Components of Espresso
Most Espresso tests are built around three important concepts.
View Matchers
View matchers locate UI elements.
Examples include:
withId(R.id.loginButton)
withText("Login")
withContentDescription("Settings")
isDisplayed()
View Actions
View actions interact with UI elements.
Examples include:
click()
typeText("username")
clearText()
scrollTo()
Example:
onView(withId(R.id.username)) .perform(typeText("testuser"));
View Assertions
View assertions validate the expected state of a UI element.
Examples include:
matches(isDisplayed())
matches(withText("Welcome"))
doesNotExist()
Example:
onView(withId(R.id.welcomeMessage)) .check(matches(withText("Welcome")));
Complete Espresso Test Example
The following example demonstrates a simple login flow:
@Testpublic void userCanLoginSuccessfully() { onView(withId(R.id.username)) .perform(typeText("testuser")); onView(withId(R.id.password)) .perform(typeText("password123")); onView(withId(R.id.loginButton)) .perform(click()); onView(withId(R.id.homeScreen)) .check(matches(isDisplayed()));}
The test follows a simple pattern:
Arrange ↓Interact with the UI ↓Verify the result
In this example, the test:
- Enters a username
- Enters a password
- Clicks the login button
- Verifies that the home screen is displayed
Espresso Test Cheat Sheet
The official Android documentation provides extensive information about:
- View matchers
- View actions
- View assertions
- RecyclerView testing
- Intents
- Idling resources
- Custom views
- Android UI testing
The Espresso API contains many useful methods for different testing scenarios.
When you start writing Espresso tests, it is useful to keep a cheat sheet nearby and gradually learn the most commonly used matchers, actions, and assertions.
Link to Espresso Testing Cheatsheet
Espresso vs Appium: Which Should You Choose?
The answer depends on your application and testing strategy.
| Requirement | Espresso | Appium |
|---|---|---|
| Native Android UI testing | Excellent | Excellent |
| Android-specific testing | Excellent | Good |
| Android and iOS cross-platform testing | No | Yes |
| Direct Android integration | Yes | No |
| Separate server required | No | Typically yes |
| Java support | Yes | Yes |
| Kotlin support | Yes | Possible |
| Native Android test ecosystem | Excellent | External automation layer |
If you are testing a native Android application and want close integration with the Android development ecosystem, Espresso is a strong option.
If your organisation needs a single automation approach across Android and iOS, Appium may be a better choice.
The important point is that Espresso and Appium are not simply competitors where one universally replaces the other. The right tool depends on the application’s technology, the team’s skills, the required platforms, and the overall test strategy.
Final Thoughts
Espresso is a powerful framework for Android UI automation testing.
Its biggest advantages include:
- Native Android integration
- Built-in synchronisation
- Direct integration with Android Studio
- Support for Java and Kotlin
- Integration with Gradle
- Compatibility with Android instrumented testing
- No separate Appium server requirement
The basic Espresso testing approach is simple:
Find the view ↓Perform an action ↓Assert the result
Once you understand View Matchers, View Actions, and View Assertions, you can start creating reliable automated UI tests for native Android applications.
For Android-focused testing, Espresso remains an important framework to understand, particularly when the development and QA teams want faster feedback directly within the Android development lifecycle.
Frequently Asked Questions About Espresso Android Testing
What is Espresso in Android testing?
Espresso is a native Android UI testing framework used to automate and validate interactions with Android application interfaces.
Is Espresso better than Appium?
Neither tool is universally better. Espresso is particularly suitable for native Android applications, while Appium is useful when teams need cross-platform mobile automation across Android and iOS.
Does Espresso support Java?
Yes. Espresso tests can be written using Java and Kotlin.
Where are Espresso tests stored?
Espresso tests are typically stored in the Android project’s src/androidTest source set.
Does Espresso require an Appium server?
No. Espresso does not require a separate Appium server to execute Android UI tests.
What are the three main parts of an Espresso test?
The three core concepts are:
- View Matchers – locate UI elements
- View Actions – interact with UI elements
- View Assertions – verify the expected result
Can Espresso tests run on real devices?
Yes. Instrumented Espresso tests can run on Android emulators and connected physical Android devices.
- Small and lightweight API that is easy to set up and live happily beside the developer’s code. It also becomes part of the whole product package.
- The code looks like English that makes sense. It doesn’t mean it can be implemented by a non-technical person. It requires knowledge of Java or Kotlin languages but at a minimum.
- Java and Kotlin are the two languages of Android App development and is the same for Espresso.
- Gradle and Android Studio are required and their knowledge. No Maven, but Gradle which is another build tool to do the same stuff as Maven in Appium test frameworks.
- Automatic Synchronisation is provided by Espresso for elements and test actions. It automatically detects when the main thread is idle and accordingly runs test commands at the appropriate time. As a result, Espresso is faster and more stable. Unlike Appium, it does not involve any server communication. This is the most powerful feature of using Espresso.
- Part of Jetpack SDK from Google as it is an Android Native framework provided and maintained by Google. Dedicated support from the detailed documentation available from the Google community.
Discover more from Rotebit
Subscribe to get the latest posts sent to your email.

