Sep 22, 2015
Android apps fail for a number of reasons other than simple logic errors. At its most basic the app may not install correctly, or there may be a problem when you move from landscape to portrait and back again. Because of fragmentation the layout might not work on any number of devices that you haven’t had the time to test it on or it could hang if the network is down.
It’s just not possible to test for these conditions using unit testing. We’re going to have to use another testing tool to test our GUIs or activities. And unfortunately it also means we’re back to using devices and emulators to do our testing again.
There are lots of options out there, such as UIAutomator, Calabash, Robotium and Selenium. Until recently I’ve been using Calabash because of its Given/When/Then writing format which works great with business users. However there are significant advantages to using Espresso which are too hard to resist.
All of these other products are third party products whereas Espresso is a Google first party product. Normally this wouldn’t be any sort of advantage but because of Espresso’s ability to hook into the Android lifecycle it does a wonderful job of knowing exactly when the activity is ready to perform your tests. GUI tests in Android are typically full of sleep() commands to ensure that the Activity is ready to accept your data. With Espresso there is simply no need for any waiting or sleeping, it just fires the test when the app is ready to accept the input data. This synchronization between the UI thread and Espresso means that tests run much more reliably than with the other tools. If a test fails then it’s because there’s an error in your code rather than you need to add more time to the sleep command.
onView
While we already looked at the Espresso in in our earlier blog Android Testing it makes sense to go back to basics and do a real Hello World Espresso test.
In the last post we showed how to setup the Espresso environment as follows
Prerequisites – Intall the Android Support Repository
Test classes are in the src/androidTest/java folders
Add Espresso dependency in build.gradle (app) file
Choose Android Test Instrumentation Test Artifact in Build Variant
Create GUI tests
Right click on tests to run tests
Instead of jUnit or Hamcrest assertions Espresso uses the OnView format which uses a ViewMatcher to find the element in the activity we’re testing, ViewAction performs the action e.g. click, and matches is the assertion which makes sure the text matches and the test passes.123
Listing 1 shows the code for the standard Android Hello World app
Listing 1. Hello World
Figure 1 shows the app running on the emulator. Our simple Espresso test is going to find the text and make sure it’s really saying Hello world!
Figure 1. Hello World!
The code for the simple test is in Listing 2. The test is annotated as a @LargeTest
because we need the emulator to run Espresso tests. We’re using a jUnit4 rule to launch the Main Activity, see the @Rule
annotation.
Once we have access to the Activity we use the onView code to find our Hello World text and a .check
to see if the text is what it was defined as in the strings.xml file. In this case there is no need for the perform step so that is omitted.
Listing 2. Hello World Espresso test
The test passes and the results are shown in Android Studio similar to the unit test output, see Figure 2.
Figure 2. Hello World Espresso test results
Adding Buttons
Next let’s add a button to our Hello World code. We do this by adding the following code to our activity_main.xml file, see Listing 3. The button_label string will also need to be added to the strings.xml file. Note that the button is enabled by default.12
Listing 3. Adding Hello World button
Figure 3 shows our modified app with the new button.
Figure 3. Hello World with button
We want to make sure the button is on or enabled. The test code is now shown in Listing 4. This time we’re using the perform action to click the button.
Listing 4. onView button test
The test successfully runs as everything is green, see Figure 4.
Figure 4. Hello World test results
Table 1. ViewMatcher
ViewActions
Table 2 shows the available ViewAction options.
Table 2. ViewAction
ViewAssertions
Table 3 shows the available ViewAssertion options.
Table 3. ViewAssertion
OnData
onView won’t be able to find the data when we’re using any AdapterViews such as ListView, Gridview or Spinner. For AdapterViews we have to use onData in conjunction with the onView to locate and test the item as follows.
The OnData format is as follows:
The DataOptions available are inAdapterView, atPosition or onChildView.
To Do List
To see how this works lets look at how to test To Do List application which has a ListView adapter, see Figure 5.
Figure 5. ToDoList application
Our application uses a ListView Adapter. The code can be found in Listing 5.
Listing 5. To Do List code
A simple test to make sure everything is working ok would be to pick something on the To Do List, such as “go to the gym”. The code to is shown in Listing 6. We’re telling the test to look at position [4] in the AdapterView in the onData code and then passing that to the onView so that it can check that the text does indeed say “go to the gym”
Listing 6. onData test code
Run the test once again using the emulator or on a device.
Espresso Tests in Jenkins
To run the Espresso tests in Jenkins, click on Add Build Step->Invoke Gradle Script and add the connectedCheck task, see figure 6.
Figure 6. Adding Espresso tests in Jenkins
Espresso needs an emulator to perform its tests, so you also need to install the Android Emulator Plugin. You can choose to let Jenkins use an existing emulator or create a new one, see Figure 7.
Listing 7. Using an existing emulator
Summary
In this blog we’ve looked at a number of Espresso tests using both onView and onData. Finally if you’re wondering how many Espresso tests we should have in our suite of tests, then go back to our Agile testing pyramid in our earlier blog Android Testing and you should see we should always have a lot more unit tests than Espresso tests.
Note a complete set of these testing blogs have been compiled together into an Agile Android mini-book, published by Apress and available from AmazonThis is Part 4 of 6, the remaining blogs can be found below.
Part 1 – Agile Testing on Android
Part 3 – Hamcrest, JaCoCo, Mockito, and Jenkins for Android
Part 4 – Espresso Testing on Android