6.1: Use Espresso to test your UI

Contents:

When you, as a developer, test user interactions within your app, it helps to ensure that your app's users don't encounter unexpected results or have a poor experience when interacting with your app.

You can test the user interface for a complex app manually by running the app and trying the user interface. But you can't possibly cover all permutations of user interactions and all of the app's functionality. You would also have to repeat these manual tests on many different device configurations in an emulator, and on many different hardware devices.

When you automate tests of UI interactions, you free yourself up for other work. You can use suites of automated tests to perform all of the UI interactions automatically, which makes it easier to run tests for different device configurations. It is a good idea to get into the habit of creating user interface (UI) tests as you code to verify that the UI of your app is functioning correctly.

Espresso is a testing framework for Android that makes it easy to write reliable user interface (UI) tests for an app. The framework, which is part of the Android Support Repository, provides APIs for writing UI tests to simulate user interactions within the app—everything from clicking buttons and navigating views to choosing menu selections and entering data.

What you should already KNOW

You should be able to:

  • Create and run apps in Android Studio.
  • Create and edit UI elements using the Layout Editor, entering XML code directly, and accessing UI elements from your Java code.
  • Add onClick functionality to a button.
  • Build the TwoActivities app from a previous lesson.
  • Build the PhoneNumberSpinner app from a previous lesson.
  • Build the RecyclerView app from a previous lesson.

What you will LEARN

During this practical, you will learn to:

  • Set up Espresso in your app project.
  • Write an Espresso test that tests for user input and checks for the correct output.
  • Write an Espresso test to find a spinner, click one of its items, and check for the correct output.
  • Use the Record Espresso Test function in Android Studio.

What you will DO

In this practical application you will:

  • Modify a project to create Espresso tests.
  • Test the app's text input and output.
  • Test clicking a spinner item and check its output.
  • Record an Espresso test of a RecyclerView.

App Overview

You will modify the TwoActivities project to set up Espresso in the project for testing. You will then test the app’s functionality, which enables a user to enter text into a text field and click the Send button, as shown on the left side of the figure below, and view that text in a second activity, as shown on the right side of the figure below. Entering Text and Clicking Send (left) - Receiving the Message in the Second Activity (right)

Tip: For an introduction to testing Android apps, see Test Your App.

Android Studio project: TwoActivities

Task 1: Set up Espresso in your project

To use Espresso, you must already have the Android Support Repository installed with Android Studio. You must also configure Espresso in your project.

In this task you check to see if the repository is installed. If it is not, you will install it. You then will configure Espresso in the TwoActivities project created previously.

1.1 Check for the Android Support Repository

  1. Start Android Studio, and choose Tools > Android > SDK Manager.
  2. Click the SDK Tools tab, and look for the Support Repository.

    • If "Installed" appears in the Status column, you're all set. Click Cancel.
    • If "Not installed" appears, or an update is available:

      1. Click the checkbox next to Android Support Repository. A download icon should appear next to the checkbox.

      2. Click one of the following:

        • Apply to start installing the repository and remain in SDK Manager to make other changes.
        • OK to install the repository and quit the SDK Manager.

1.2 Configure Espresso for the project

When you start a project for the phone and tablet form factor using API 15: Android 4.0.3 (Ice Cream Sandwich) as the minimum SDK, Android Studio version 2.2 and newer automatically includes the dependencies you need to use Espresso.To execute tests, Espresso and UI Automator use JUnit as their testing framework. JUnit is the most popular and widely-used unit testing framework for Java. Your test class using Espresso or UI Automator should be written as a JUnit 4 test class. If you do not have JUnit, you can get it at http://junit.org/junit4/.

Note: The most current Junit revision is JUnit 5. However for the purposes of using Espresso or UI Automator, version 4.12 is recommended.

If you have created your project in a previous version of Android Studio, you may have to add the dependencies and instrumentation yourself. To add the dependencies yourself, follow these steps:

  1. Open the TwoActivities project, or if you prefer, make a copy of the project first and then open the copy. See Copy and rename a project in the Appendix for instructions.
  2. Open your build.gradle (Module: app) file.

    Note: Do not make changes to the build.gradle (Project: yourappname) file.
  3. Check if the following is included (along with other dependencies) in the dependencies section of the project's build.gradle (Module: app) file:

    androidTestCompile
     ('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        })
    testCompile 'junit:junit:4.12'
    
    Note: If the file doesn't include the above dependency statements, enter them into the dependencies section.
  4. Android Studio 2.2 also adds the following instrumentation statement to the end of the defaultConfig section of a new project:

    testInstrumentationRunner
                 "android.support.test.runner.AndroidJUnitRunner"
    
    Note: If the file doesn't include the above instrumentation statement, enter it at the end of the defaultConfig section.

    Instrumentation is a set of control methods, or hooks, in the Android system. These hooks control an Android component independently of the component's normal lifecycle. They also control how Android loads apps. Using instrumentation makes it possible for tests to invoke methods in the app, and modify and examine fields in the app, independently of the app's normal lifecycle.

  5. If you modified the build.gradle (Module: app) file, click the Sync Now link in the notification about Gradle files in top right corner of the window.

1.3 Turn off animations on your test device

To let Android Studio communicate with your device, you must first turn on USB Debugging on your device, as described in an earlier chapter.

Android phones and tablets display animations when moving between apps and screens. The animations are attractive when using the device, but they slow down performance, and may also cause unexpected results or may lead your test to fail. So it's a good idea to turn off animations on your physical device. To turn off animations on your test device, tap on the Settings icon on your physical device. Look for Developer Options. Now look for the Drawing section. In this section, turn off the following options:

  • Window animation scale
  • Transition animation scale
  • Animator duration scale

Tip: You should also keep in mind that instrumenting a system, such as in executing unit tests, can alter the timing of specific functions. For this reason, it is useful to keep unit testing and actual debugging separate. Unit testing uses an API based Espresso Framework with hooks for instrumentation. Debugging uses breakpoints and other methods in the actual coding statements within your app's code, as described in a previous lesson. </div>

Task 2: Test for switching activities and entering text

You write Espresso tests based on what a user might do while interacting with your app. The Espresso tests are classes that are separate from your app's code. You can create as many tests as you need, in order to interact with the views in your UI that you want to test.

The Espresso test is like a robot that must be told what to do. It must find the view you want it to find on the screen, and it must interact with it, such as clicking the view, and checking the contents of the view. If it fails to do any of these things properly, or if the result is not what you expected, the test fails.

With Espresso, you create what is essentially a script of actions to take on each view and check against expected results. The key concepts are locating and then interacting with UI elements. These are the basic steps:

  1. Match a view: Find a view.
  2. Perform an action: Perform a click or other action that triggers an event with the view.
  3. Assert and verify the result: Check the view's state to see if it reflects the expected state or behavior defined by the assertion.

Hamcrest (an anagram of "matchers") is a framework that assists writing software tests in Java. To create a test, you create a method within the test class that uses Hamcrest expressions.

Tip: For more information about the Hamcrest matchers, see The Hamcrest Tutorial.

With Espresso you use the following types of Hamcrest expressions to help find views and interact with them:

  • ViewMatchers: Hamcrest matcher expressions in the ViewMatchers class that lets you find a view in the current view hierarchy so that you can examine something or perform some action.
  • ViewActions: Hamcrest action expressions in the ViewActions class that lets you perform an action on a view found by a ViewMatcher.
  • ViewAssertions: Hamcrest assertion expressions in the ViewAssertions class that lets you assert or check the state of a view found by a ViewMatcher.

The following shows how all three expressions work together:

  1. Use a ViewMatcher to find a view:
    onView(withId(R.id.my_view))
    
  2. Use a ViewAction to perform an action:
    .perform(click())
    
  3. Use a ViewAssertion to check if the result of the action matches an assertion:
    .check(matches(isDisplayed()));
    

The following shows how the above expressions are used together in a statement:

onView(withId(R.id.my_view))
        .perform(click())
        .check(matches(isDisplayed()));

2.1 Define a class for a test and set up the activity

Android Studio creates a blank Espresso test class for you in the src/androidTest/java/com.example.package folder:

  1. Expand com.example.android.twoactivities (androidTest), and open ExampleInstrumentedTest.
  2. To make the test more understandable and describe what it does, rename the class from ExampleInstrumentedTest to the following:
    public class ActivityInputOutputTest
    
  3. Change the class definition to the following:
    @RunWith(AndroidJUnit4.class)
    public class ActivityInputOutputTest {
       @Rule
       public ActivityTestRule mActivityRule = new ActivityTestRule<>(
                         MainActivity.class);
    }
    

The class definition now includes several annotations:

  • @RunWith: To create an instrumented JUnit 4 test class, add the @RunWith(AndroidJUnit4.class) annotation at the beginning of your test class definition.
  • @Rule: The @Rule annotation lets you add or redefine the behavior of each test method in a reusable way, using one of the test rule classes that the Android Testing Support Library provides, such as ActivityTestRule or ServiceTestRule. The rule above uses an ActivityTestRule object, which provides functional testing of a single Activity—in this case, MainActivity.class. During the duration of the test you will be able to manipulate your Activity directly, using ViewMatchers, ViewActions, and ViewAssertions.

In the above statement, ActivityTestRule may turn red at first, but then Android Studio adds the following import statement automatically:

import android.support.test.rule.ActivityTestRule;

2.2 Test switching activities

The TwoActivities app has two activities:

  • Main: Includes the button_main button for switching to the Second activity and the text_header_reply view that serves as a text heading for the Main activity.
  • Second: Includes the button_second button for switching to the Main activity and the text_header view that serves as a text heading for the Second activity.

When you have an app that switches activities, you should test that capability. The Two Activities app provides a text entry field and a Send button (the button_main id). Clicking Send launches the Second activity with the entered text shown in the text_header view of the Second activity.

But what happens if no text is entered? Will the Second activity still appear?

The ActivityInputOutputTest class of tests will show that the views appear regardless of whether text is entered. Follow these steps to add your tests to ActivityInputOutputTest:

  1. Add an activityLaunch() method to ActivityInputOutputTest to test whether the views appear when clicking the buttons, and include the @Test notation on a line immediately above the method:

    @Test
    public void activityLaunch() { … }
    

    The @Test annotation tells JUnit that the public void method to which it is attached can be run as a test case. A test method begins with the @Test annotation and contains the code to exercise and verify a single function in the component that you want to test.

  2. Add a combined ViewMatcher and ViewAction expression to the activityLaunch() method to locate the view containing the button_main button, and include a ViewAction expression to perform a click:

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

    The onView() method lets you use ViewMatcher arguments to find views. It searches the view hierarchy to locate a corresponding View instance that meets some given criteria—in this case, the button_main view. The .perform(click()) expression is a ViewAction expression that performs a click on the view.

  3. In the above onView statement, onView, withID, and click may turn red at first, but then Android Studio adds import statements for onView, withID, and click.
  4. Add another ViewMatcher expression to the activityLaunch() method to find the text_header view (which is in the Second activity), and a ViewAction expression to perform a check to see if the view is displayed:

    onView(withId(R.id.text_header)).check(matches(isDisplayed()));
    

    This statement uses the onView() method to locate the text_header view for the Second activity and check to see if it is displayed after clicking the button_main view.

  5. In the above onView statement, the check() method may turn red at first, but then Android Studio adds an import statement for it.
  6. Add similar statements to test whether clicking the button_second button in the Second activity switches to the Main activity:
    onView(withId(R.id.button_second)).perform(click());
    onView(withId(R.id.text_header_reply)).check(matches(isDisplayed()));
    
  7. Review the activityLaunch() method you just created in the ActivityInputOutputTest class. It should look like this:
    @Test
    public void activityLaunch() {
       onView(withId(R.id.button_main)).perform(click());
       onView(withId(R.id.text_header)).check(matches(isDisplayed()));
       onView(withId(R.id.button_second)).perform(click());
       onView(withId(R.id.text_header_reply)).check(matches(isDisplayed()));
    }
    
  8. To run the test, right-click (or Control-click) ActivityInputOutputTest and choose Run ActivityInputOutputTest from the pop-up menu. You can then choose to run the test on the emulator or on your device.

As the test runs, watch the test automatically start the app and click the button. The Second activity's view appears. The test then clicks the Second activity's button, and the Main activity view appears.

The Run window (the bottom pane of Android Studio) shows the progress of the test, and when finishes, it displays "Tests ran to completion." In the left column Android Studio displays "All Tests Passed".

2.3 Test text input and output

Write a test for text input and output. The TwoActivities app uses the editText_main view for input, the button_main button for sending the input to the Second activity, and the Second activity view that shows the output in the field with the id text_message.

  1. Add another @Test annotation and a new textInputOutput() method to the ApplicationTest class to test text input and output:

    @Test
    public void textInputOutput() {
       onView(withId(R.id.editText_main)).perform(typeText("This is a test."));
       onView(withId(R.id.button_main)).perform(click());
    }
    

    The above method uses a ViewMatcher to locate the view containing the editText_main view, and a ViewAction to enter the text "This is a test." It then uses another ViewMatcher to find the view with the button_main button, and another ViewAction to click the button.

  2. Add a ViewMatcher to locate the Second activity's text_message view, and a ViewAssertion to see if the output matches the input to test that the message was correctly sent:
    onView(withId(R.id.text_message)).check(matches(withText("This is a test.")));
    
  3. Run the test.

    As the test runs, the app starts and the text is automatically entered as input; the button is clicked, and the text appears on the second activity's screen.

    The bottom pane of Android Studio shows the progress of the test, and when finished, it displays "Tests ran to completion." In the left column Android Studio displays "All Tests Passed". You have successfully tested the text input field, the Send button, and the text output field.

Solution code:

Android Studio Project: TwoActivitiesEspressoTest

See ActivityInputOutputTest.java.

2.4 Introduce an error to show a test failing

Introduce an error in the test to see what a failed test looks like.

  1. Change the match check on the text_message view from "This is a test." to "This is a failing test.":
    onView(withId(R.id.text_message)).check(matches(withText("This is a failing test.")));
    
  2. Run the test again. This time you will see the message in red, "1 test failed", above the bottom pane, and a red exclamation point next to textInputOutput in the left column. Scroll the bottom pane to the message "Test running started" and see that all of the results after that point are in red. The very next statement after "Test running started" is:
    android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with text: is "This is a failing test."' doesn't match the selected view.
    Expected: with text: is "This is a failing test."
    Got: "AppCompatTextView{id=2131427417, res-name=text_message ...
    

Other fatal error messages appear after the above, due to the cascading effect of a failure leading to other failures. You can safely ignore them and fix the test itself.

Task 3: Test the display of spinner selections

The Espresso onView() method finds a view that you can test. This method will find a view in the current view hierarchy. But you need to be careful—in an AdapterView such as a spinner, the view is typically dynamically populated with child views at runtime. This means there is a possibility the view that you want to test may not be in the view hierarchy at that time.

The Espresso API handles this problem by providing a separate onData() entry point, which is able to first load the adapter item and bring it into focus prior to locating and performing actions on any of its children.

PhoneNumberSpinner is an app from a previous lesson that shows a spinner, with the id label_spinner, for choosing the label of a phone number (Home, Work, Mobile, and Other). The app displays the choice in a text field, concatenated with the entered phone number.

The goal of this test is to open the spinner, click each item, and then verify that the TextView text_phonelabel contains the item. The test demonstrates that the code retrieving the spinner selection is working properly, and the code displaying the text of the spinner item is also working properly. You will write the test using string resources and iterate through the spinner items so that the test works no matter how many items are in the spinner, or how those items are worded; for example, the words could be in a different language. Spinner

Android Studio Project: PhoneNumberSpinner

3.1 Create the test method

  1. Open the PhoneNumberSpinner project, or if you prefer, make a copy of the project first and then open the copy. See Copy and rename a project in the Appendix for instructions.
  2. Configure Espresso in your project as described previously.
  3. Expand com.example.android.phonenumberspinner (androidTest), and open ExampleInstrumentedTest.
  4. Rename ExampleInstrumentedTest to SpinnerSelectionTest in the class definition, and add the following:
    @RunWith(AndroidJUnit4.class)
    public class SpinnerSelectionTest {
       @Rule
       public ActivityTestRule mActivityRule = new ActivityTestRule<>(
                         MainActivity.class);
    }
    
  5. Create the iterateSpinnerItems() method as public returning void.

3.2 Access the array used for the spinner items

You want the test to click each item in the spinner based on the number of elements in the array. But how do you access the array?

  1. Assign the array used for the spinner items to a new array to use within the iterateSpinnerItems() method:

    public void iterateSpinnerItems() {
       String[] myArray =
             mActivityRule.getActivity().getResources()
             .getStringArray(R.array.labels_array);
    }
    

    In the statement above, the test accesses the application's array (with the id labels_array) by establishing the context with the getActivity() method of the ActivityTestRule class, and getting a resources instance in the application's package using getResources().

  2. Assign the length of the array to size, and construct a for loop using the size as the maximum number for a counter.
    int size = myArray.length;
        for (int i=0; i<size; i++) {
    }
    

3.3 Locate spinner items and click on them

  1. Add an onView() statement within the for loop to find the spinner and click on it:

    // Find the spinner and click on it.
    onView(withId(R.id.label_spinner)).perform(click());
    

    A user must click the spinner itself in order click any item in the spinner, so your test must also click the spinner first before clicking the item.

  2. Write an onData() statement to find and click a spinner item:

    // Find the spinner item and click on it.
    onData(is(myArray[i])).perform(click());
    

    The above statement matches if the object is a specific item in the spinner, as specified by the myArray[i] array element.

    If onData appears in red, click the word, and then click the red light bulb icon that appears in the left margin. Choose the following in the pop-up menu:

    Static import method 'android.support.test.espresso.Espresso.onData'

    If is appears in red, click the word, and then click the red light bulb icon that appears in the left margin. Choose the following in the pop-up menu:

    Static import method…> Matchers.is (org.hamcrest)

  3. Add two more onView() statements to the for loop:

    // Find the Submit button and click on it.
    onView(withId(R.id.button_main)).perform(click());
    // Find the text view and check that the spinner item
    // is part of the string.
    onView(withId(R.id.text_phonelabel))
               .check(matches(withText(containsString(myArray[i]))));
    

    The first statement locates the button_main and clicks it. The second statement checks to see if the resulting text_phonelabel matches the spinner item specified by myArray[i].

    If containsString appears in red, click the word, and then click the red light bulb icon that appears in the left margin. Choose the following in the pop-up menu:

    Static import method…> Matchers.containsString (org.hamcrest)

  4. To run the test, right-click (or Control-click) SpinnerSelectionTest and choose Run SpinnerSelectionTest from the pop-up menu. You can then choose to run the test on the emulator or on your device.

The test runs the app, clicks the spinner, and "exercises" the spinner—it clicks each spinner item from top to bottom, checking to see if the item appears in the text field. It doesn't matter how many spinner items are defined in the array, or what language is used for the spinner's items—the test performs all of them and checks their output against the array.

The bottom pane of Android Studio shows the progress of the test, and when finished, it displays "Tests ran to completion." In the left column Android Studio displays "All Tests Passed".

Solution code:

Android Studio project: PhoneNumberSpinnerEspressoTest

See SpinnerSelectionTest.java.

Task 4: Record a test of a RecyclerView

You learned how to create a RecyclerView in a previous chapter. Like an AdapterView (such as a spinner), a RecyclerView dynamically populates child views at runtime. But a RecyclerView is not an AdapterView, so you can't use onData() to interact with list items as you did in the previous task with a spinner. What makes a RecyclerView complicated from the point of view of Espresso is that onView() can't find the child view if it is off the screen.

Fortunately, you have two handy tools to circumvent these complications:

  • A class called RecyclerViewActions that exposes a small API to operate on a RecyclerView.
  • An Android Studio feature (in version 2.2 and newer) that lets you record an Espresso test. Use your app as a normal user. As you click through the app UI, editable test code is generated for you. You can also add assertions to check if a view holds a certain value.

Recording Espresso tests, rather than coding the tests by hand, ensures that your app gets UI test coverage on areas that might take too much time or be too difficult to code by hand.

Solution code:

Android Studio project: RecyclerView

4.1 Open and run the app

  1. Open the RecyclerView project, or if you prefer, make a copy of the project first and then open the copy. See Copy and rename a project in the Appendix for instructions.
  2. Configure Espresso in your project as described previously.
  3. Run the app to ensure that it runs properly. You can use the emulator or an Android device.

The app lets you scroll a list of words. When you click on a word such as Word 15 the word in the list changes to "Clicked! Word 15".

4.2 Record the test

  1. Choose Run > Record Espresso Test, select your deployment target (an emulator or a device), and click OK.
  2. Scroll the word list in the app on the emulator or device, and tap on Word 15. The Record Your Test window shows the action that was recorded ("Tap RecyclerView with element position 15"). Recording a Click for an Espresso Test
  3. Click Add Assertion in the Record Your Test window. A screenshot of the app's UI appears in a pane on the right side of the window. Select Clicked! Word 15 in the screenshot as the UI element you want to check. Adding an Assertion to the Recording
  4. Choose text is from the second drop-down menu. The text you expect to see is already entered in the field below the drop-down menu. Adding an Assertion to the Recording
  5. Click Save Assertion, and then click Complete Recording. Completing the Recording
  6. In the dialog that appears, edit the name of the test to RecyclerViewTest so that it is easy to understand the test's purpose.
  7. Android Studio may display a request to add more dependencies to your Gradle Build file. Click Yes to add the dependencies.
  8. Expand com.example.android.recyclerview (androidTest) to see the test, and run the test. It should pass.

The following is the test, as recorded in the RecyclerViewTest.java file:

@RunWith(AndroidJUnit4.class)
public class RecyclerViewTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule =
            new ActivityTestRule<>(MainActivity.class);

    @Test
    public void recyclerViewTest() {
        ViewInteraction recyclerView = onView(
                allOf(withId(R.id.recyclerview), isDisplayed()));
        recyclerView.perform(actionOnItemAtPosition(15, click()));

        ViewInteraction textView = onView(
                allOf(withId(R.id.word), withText("Clicked! Word 15"),
                        childAtPosition(
                                childAtPosition(
                                        withId(R.id.recyclerview),
                                        11),
                                0),
                        isDisplayed()));
        textView.check(matches(withText("Clicked! Word 15")));

    }

    private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
           @Override
           public void describeTo(Description description) {
             description.appendText("Child at position " + position + " in parent ");
             parentMatcher.describeTo(description);
           }

           @Override
           public boolean matchesSafely(View view) {
             ViewParent parent = view.getParent();
             return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
           }
        };
    }
}

The test uses a RecyclerView object of the ViewInteraction class, which is the primary interface for performing actions or assertions on views, providing both check() and perform() methods. Examine the test code to see how it works:

  • Perform: The code below uses the perform() method and the actionOnItemAtPosition() method of the RecyclerViewActions class to scroll to the position (15) and click the item:
      ViewInteraction recyclerView = onView(
           allOf(withId(R.id.recyclerview), isDisplayed()));
     recyclerView.perform(actionOnItemAtPosition(15, click()));
    
  • Check whether it matches the assertion: The code below checks to see if the clicked item matches the assertion that it should be "Clicked! Word 15":

      ViewInteraction textView = onView(
            allOf(withId(R.id.word), withText("Clicked! Word 15"),
                 childAtPosition(
                         childAtPosition(
                                 withId(R.id.recyclerview),
                                 11),
                         0),
                 isDisplayed()));
      textView.check(matches(withText("Clicked! Word 15")));
    

    The code above uses a method called childAtPosition(), which is defined as a custom Matcher:

      private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {
         // TypeSafeMatcher() returned
         ...
         }
    
  • Implement a custom matcher: The custom matcher extends the abstract TypeSaveMatcher class and requires that you implement the following:

    • The matchesSafely() method, shown below, to define how to check for a view in a RecyclerView.
    • The describeTo() method, shown below, to define how Espresso describes the output's matcher in the Run pane at the bottom of Android Studio if a failure occurs.
      ...
      // TypeSafeMatcher() returned
      return new TypeSafeMatcher<View>() {
         @Override
         public void describeTo(Description description) {
            description.appendText("Child at position "
                                           + position + " in parent ");
            parentMatcher.describeTo(description);
         }

         @Override
         public boolean matchesSafely(View view) {
            ViewParent parent = view.getParent();
            return parent instanceof ViewGroup &&
                                     parentMatcher.matches(parent)
                                     && view.equals(((ViewGroup)
                                     parent).getChildAt(position));
         }
      };
   }
}

You can record multiple interactions with the UI in one recording session. You can also record multiple tests, and edit the tests to perform more actions, using the recorded code as a snippet to copy, paste, and edit.

Solution code

Android Studio project: RecyclerViewEspressoTest

Coding challenge

Note: All coding challenges are optional and are not prerequisites for later lessons.

Challenge: Write an Espresso text for the Scorekeeper app from a previous lesson that tests whether the Day Mode button appears after clicking Night Mode, and whether the Night Mode button appears after clicking Day Mode.

Summary

In this practical, you learned how to do the following:

  • Set up Espresso to test an Android Studio project:
    • Checking for and Installing the Android Support Repository.
    • Adding instrumentation and dependencies to the build.gradle (Module: app) file.
    • Turning off animations in your test device.
    • Defining the test class.
  • Test to see whether an activity is launched:
    • Using the onView() method with ViewMatcher arguments to find views.
    • Using a ViewAction expression to perform a click.
    • Using a ViewAssertion expression to check if the view is displayed.
    • Using a ViewAssertion expression to see if the output matches the input.
  • Test a spinner and its selections:
    • Using the onData() method with a view that is dynamically populated by an adapter at runtime.
    • Getting items from an app's array by establishing the context with getActivity() and getting a resources instance using getResources().
    • Using an onData() statement to find and click each spinner item.
    • Using the onView() method with a ViewAction and ViewAssertion to check if the output matches the selected spinner item.
  • Record a test of a RecyclerView:
    • Using the RecyclerViewActions class that exposes methods to operate on a RecyclerView.
    • Recording an Espresso test to automatically generate the test code.

The related concept documentation is in Android Developer Fundamentals: Concepts.

Learn more

Android Studio Documentation:

Android Developer Documentation:

Android Testing Support Library:

Videos

Other:

results matching ""

    No results matching ""