This tutorial describes how to write instrumentation tests for your Android application. It covers the usage of Espresso to write UI tests and how to run these tests via Android studio.
Writing and maintaining a good test suite containing different types of tests requires a good amount of time and discipline on the part of the developer. However, the benefits that comes with doing this includes the following:
- Helps to ensure the correctness of the app features.
- Helps to implement new features with confidence that the new changes will not break existing working code.
- Facilitates building of app features in modules and iterations especially when tests are first written [TDD], then codes are written to validate the test.
Categories of Android unit tests
Local unit tests: These are tests that runs on the JVM. They do not require any native Android library to run. They are found in
app/src/test/javafolder in the Project perspective. Unit test should amount to about 60-70% of the test code base.
Integration test: Tests more than one individual module working together that implements a complete functional part of an app. Integration test are located in the
app/src/androidTest/javafolder and requires the Android system to run. Should amount to about 20% of the test code base.
Espresso is a testing framework contained in the Android Testing Support Library. It provides APIs to simulate user interactions and write functional UI tests.
Espresso tests are written based on what user might do while interacting with your app. Basically, you:
- Locate the desired UI element
- Interact with the UI element or check its state.
Android Instrumentation tests are located in the
and this is the location where you will be writing your tests.
Espresso tests are composed of three major components which are:
ViewMatchers: These are collection of objects used to find the desired view in the current view hierarchy. They are passed to the
onViewmethod to locate and return the desired UI element.
ViewActions: They are used to perform actions such
clickon views. They are passed to the
ViewAssertions: They are used to assert the state of the currently selected view. They can be passed to the
Setting up Espresso in your project
- Download the latest Android Support Repository via the SDK Manager or Android Studio
- Open your app’s build.gradle file, the one located in
app/build.gradleand add the following lines inside dependencies:
- To that same
android.defaultConfig, add the following:
Sample build.gradle file
Set up your device for Espresso tests
To ensure that espresso works as expected on your test device or emulator, turn off animations on your device. Navigate to Settings -> Developer Options and turn all the following off under Drawing
- Window animation scale
- Transition animation scale
- Animator duration scale
A sample app showing a SignUp and Login screen will be used to demonstrate the
basic concepts of Espresso. To follow through with the snippets in the following
section, please clone this git repository.
git clone email@example.com:mayojava/espressoUIIntegrationTest.git
Now let’s dive in
The sample code has a main screen with a Login and SignUp button. The first test we
will be looking at, is to check that the SignUp screen shows up when the SignUp button
is clicked. In the
androidTest folder, open the
app/src/androidTest/java/.../mainscreen/MainScreenTest.java file. The first
thing to notice here are the annotations:
@RunWith(AndroidJUnit4.class): Tags the class as an Android JUnit4 class. Espresso unit test should be written as a JUnit 4 test class.
@LargeTest: Qualifies a test to run in >2s execution time, makes use of all platform resources, including external communications. Other test qualifiers are
ServiceTestRuleare JUnit rules part of the Android Testing Support Library and they provide more flexibility and reduce the boilerplate code required in tests. These rules provides functional testing of a single activity or service respectively.
@Test: Each functionality to be tested must be annotated with this. The activity under test will be launched before each of the test annotated with
To test that the Signup screen shows up when the Signup button is clicked, we do the following:
- Locate the Signup button using the
- Perform a
click()action on the button.
- Assert that the Signup screen is displayed.
The code for the steps above is shown in the snippets below:
Next open the
SignUpScreenTest.java file under
app/src/androidTest/java/.../signup/SignUpScreenTest.java. Here we want to test that
on filling the signup form and clicking the Signup button, the Success screen is displayed with the signup success text, when the signup is complete.
The code for the test above, follow the following steps:
- Locate each of the sign up form text fields using the
typeText()action on each, to type in the text for that field.
- Locate sign up button and perform the
click()action on the button to submit the form.
- On sign up completion, assert that the sign up success screen is displayed with the success text.
The code for the steps above is shown below:
For a list of possible
ViewAssertions check out the
Espresso Cheat Sheet
Running Espresso tests
To run a single test class, right click on the test class file and select the ‘Run [TestFileName]’ option.
To run many different tests at the same time, you will need to create a build configuration. This can be done easily in Android Studio by right clicking on the
package name under
androidTest /java/.. and select “Create Tests in [package name]”
Select the new run configuration from the run configuration menu and select run. Tests results are displayed in the run panel at the bottom of the screen.
References and further readings:
- Espresso Documentation
- Espresso Intents
- Android Testing Support Library
- Android Testing Codelab
- Hamcrest Matchers
The sample code for this post can be found in this github repo.