Testing User Interactions with Espresso

Espresso is a testing framework which provides the facility to write the tests for user interactions and unitary tests. Since the release of its version 2 it is now a part of Android Testing Support Library.

The android apps we build at FOSSASIA follow rigorous testing methods. See this simple UI test  in the Phimp.me app using espresso to check if button and bottom navigation are displayed in an activity. You can also find our other tests related to API and databases in the Open Event Android App.

In this blog we learn how to add this facility to your app and write a test for a simple app that takes the name of from the user and prints it on the other screen on button click.

Adding espresso support

  • Install android support repository if not already present. You do it by following Tools -> Android -> SDK Manager
Tools you need to download for testing
  • Add the following dependencies to your app’s build.gradle file
dependencies {
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support.test:rules:0.5'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

}
  • Specify the test instrumentation runner in default config
android {

    defaultConfig {

        // ....

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

}

Before we begin with writing our tests knowing some basic components will help in understanding the code better. Writing tests with espresso is easy as its construction is similar to English language.

The three major components are 

  • ViewActions        : Allows you to interact with views
  • ViewAssertions   : Allows you to assert the state of a view.
  • ViewMatchers     : Allows you to locate a view in the current view hierarchy.

Suppose we want to test if text is displayed in the view, we can do it by

onView(withId(R.id.textView))                              //ViewMatcher

 .perform(click())                                         //ViewAction

 .check(matches(isDisplayed()));                           //ViewAssertion

Example

Consider an app which takes a name from the user and displays it on the next screen on clicking the button.

To perform this kind of test we will write

//Locate the view with id "name" and type the text "Natalie"

onView(withId(R.id.name)).perform(typeText("Natalie"));

//Locate the view with id "next" and click on it

onView(withId(R.id.next)).perform(click());

//Locate the view with id "new_name" and check its text is equal with "Natalie"

onView(withId(R.id.new_name)).check(matches(withText("Natalie")));

You can run tests by right clicking on the class and selecting the “run test” option. If the interaction is not as expected then the message will be displayed.

Up until now unit test were in main focus but as we move towards the more complex apps where user interaction plays an essential role, UI testing becomes equally necessary.

References: