-
Notifications
You must be signed in to change notification settings - Fork 6.3k
UI Testing with Espresso
Espresso is a UI test framework (part of the Android Testing Support Library) that allows you to create automated UI tests for your Android app. Espresso tests run on actual device or emulator (they are instrumentation based tests) and behave as if an actual user is using the app (i.e. if a particular view is off screen, the test won't be able to interact with it).
Espresso's simple and extensible API, automatic synchronization of test actions with the UI of the app under test, and rich failure information make it a great choice for UI testing. In many circles Espresso is considered to be a full replacement for Robotium (see this stack overflow post that compares Robotium to Espresso).
There are several steps needed to setup Espresso with Android Studio:
-
First, let's change to the
Projectperspective in theProject Window. This will show us a full view of everything contained in the project. The default setting (theAndroidperspective) hides certain folders: -
Next, open the
Build Variantswindow and make sure theTest Artifactis set toAndroid Instrumentation Tests. Without this, our tests won't be included in the build. -
Make sure you have an
app/src/androidTest/javafolder. This is the default location for instrumentation tests. -
You'll also need to make sure you have the
Android Support Repositoryversion 15+ installed. -
It's recommended to turn off system animations on the device or emulator we will be using. Since Espresso is a UI testing framework, system animations can introduce flakiness in our tests. Under
Settings=>Developer optionsdisable the following 3 settings and restart the device: -
Finally, we need to pull in the Espresso dependencies and set the test runner in our app build.gradle:
// build.gradle
...
android {
...
defaultConfig {
...
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
dependencies {
...
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2') {
// Necessary if your app targets Marshmallow (since Espresso
// hasn't moved to Marshmallow yet)
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestCompile('com.android.support.test:runner:0.3') {
// Necessary if your app targets Marshmallow (since the test runner
// hasn't moved to Marshmallow yet)
exclude group: 'com.android.support', module: 'support-annotations'
}
}That's all the setup needed. Now let's move on to writing some actual tests.
The code below shows a simple Espresso test that enters some text into an EditText and then verifies the text entered. It's based off the standard new project template which has a single MainActivity that contains a TextView with the text "Hello world!".
- Add an
EditTexttoMainActivitythat hasid=R.id.etInput. - Create a new class
MainActivityInstrumentationTestinside of the default instrumentation tests directory (src/androidTest/java). The best practice is to mimic the same package structure with your tests as your product code. This has the benefit of giving your tests access topackage-privatefields in your product code. For this example, we'll be creatingMainActivityInstrumentationTestatsrc/androidTest/java/com.codepath.espressodemo.MainActivityInstrumentationTest.
// MainActivityInstrumentationTest.java
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
// Tests for MainActivity
public class MainActivityInstrumentationTest {
// Preferred JUnit 4 mechanism of specifying the activity to be launched before each test
@Rule
public ActivityTestRule<MainActivity> activityTestRule =
new ActivityTestRule<>(MainActivity.class);
// Looks for an EditText with id = "R.id.etInput"
// Types the text "Hello" into the EditText
// Verifies the EditText has text "Hello"
@Test
public void validateEditText() {
onView(withId(R.id.etInput)).perform(typeText("Hello")).check(matches(withText("Hello")));
}
}When writing Espresso tests, you'll be using a lot of static imports. This makes the code easier to read, but can make it more difficult to understand when you are first learning Espresso. Let's dive into the parts of the above test:
-
Espresso – This is the entry point. Mostly of the time you'll be using
onView(...)to specify you want to interact with a view. -
ViewMatchers – This is how we find views.
ViewMatcherscontains a collection of hamcrest matchers that allow you to find specific views in your view hierarchy. Above, we've usedwithId(R.id.etInput)to specify we are looking for anEditTextwithid=R.id.etInput. -
ViewActions – This is how we interact with views. Above we've used the
typeText(...)method to typeHellointo ourEditText. -
ViewAssertions – This is our validation. We use
ViewAssertionsto validate specific properties of views. Most of the time you'll be usingViewAssertionsthat are powered byViewMatchersunderneath. In our example above thewithText(...)method is actually returning aViewMatcherwhich we've converted into aViewAssertionusing thematches(...)method.
The standard pattern for an Espresso test is to find a view (ViewMatchers), do something to that view (ViewActions), and then validate some view properties (ViewAssertions). There's a handy [cheat sheet] (https://github.com/googlesamples/android-testing/blob/master/downloads/Espresso%20Cheat%20Sheet%20Master.pdf) that's a great reference to see what's available in each of these classes.
There are 2 ways to run your tests:
- Run a single test through Android Studio:
-
Right click on the test class and select
Run: -
Note: If you are presented with two options as in the diagram below, make sure to select the first one (designating to use the Gradle Test Runner instead of the JUnit Test Runner). Android Studio will cache your selection for future runs.
-
View the results in the
Consoleoutput. You may need to enableShow Passedas in the diagram below to see the full results.
- Run all the tests through Gradle:
-
Open the Gradle window and find
connectedDebugAndroidTestunderTasks=>verification. -
Right click and select
Run -
This will generate an html test result report at
app/build/reports/androidTests/connected/index.html -
Note: You can also run the tests on the command line using:
./gradlew connectedDebugAndroidTest
Created by CodePath with much help from the community. Contributed content licensed under cc-wiki with attribution required. You are free to remix and reuse, as long as you attribute and use a similar license.
Finding these guides helpful?
We need help from the broader community to improve these guides, add new topics and keep the topics up-to-date. See our contribution guidelines here and our topic issues list for great ways to help out.
Check these same guides through our standalone viewer for a better browsing experience and an improved search. Follow us on twitter @codepath for access to more useful Android development resources.









