6.1: Use Espresso to test your UI
Contents:
- What you should already KNOW
- What you will LEARN
- What you will DO
- App Overview
- Task 1: Set up Espresso in your project
- Task 2: Test for switching activities and entering text
- Task 3: Test the display of spinner selections
- Task 4: Record a test of a RecyclerView
- Coding challenge
- Summary
- Related concept
- Learn more
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.
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
- Start Android Studio, and choose Tools > Android > SDK Manager.
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:
Click the checkbox next to Android Support Repository. A download icon should appear next to the checkbox.
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/.
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:
- 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.
Open your build.gradle (Module: app) file.
Note: Do not make changes to the build.gradle (Project: yourappname) file.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 thedependencies
section.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 thedefaultConfig
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.
- 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:
- Match a view: Find a view.
- Perform an action: Perform a click or other action that triggers an event with the view.
- 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:
- Use a ViewMatcher to find a view:
onView(withId(R.id.my_view))
- Use a ViewAction to perform an action:
.perform(click())
- 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:
- Expand com.example.android.twoactivities (androidTest), and open ExampleInstrumentedTest.
- To make the test more understandable and describe what it does, rename the class from
ExampleInstrumentedTest
to the following:public class ActivityInputOutputTest
- 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 anActivityTestRule
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 thebutton_main
button for switching to theSecond
activity and thetext_header_reply
view that serves as a text heading for theMain
activity.Second
: Includes thebutton_second
button for switching to theMain
activity and thetext_header
view that serves as a text heading for theSecond
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
:
Add an
activityLaunch()
method toActivityInputOutputTest
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 thepublic 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.Add a combined ViewMatcher and ViewAction expression to the
activityLaunch()
method to locate the view containing thebutton_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, thebutton_main
view. The.perform(click())
expression is a ViewAction expression that performs a click on the view.- In the above
onView
statement,onView
,withID
, andclick
may turn red at first, but then Android Studio adds import statements foronView
,withID
, andclick
. Add another ViewMatcher expression to the
activityLaunch()
method to find thetext_header
view (which is in theSecond
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 thetext_header
view for theSecond
activity and check to see if it is displayed after clicking thebutton_main
view.- In the above
onView
statement, thecheck()
method may turn red at first, but then Android Studio adds animport
statement for it. - Add similar statements to test whether clicking the
button_second
button in theSecond
activity switches to theMain
activity:onView(withId(R.id.button_second)).perform(click()); onView(withId(R.id.text_header_reply)).check(matches(isDisplayed()));
- Review the
activityLaunch()
method you just created in theActivityInputOutputTest
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())); }
- 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
.
Add another
@Test
annotation and a newtextInputOutput()
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 thebutton_main
button, and another ViewAction to click the button.- Add a ViewMatcher to locate the
Second
activity'stext_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.")));
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.
- 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.")));
- 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.
Android Studio Project: PhoneNumberSpinner
3.1 Create the test method
- 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.
- Configure Espresso in your project as described previously.
- Expand com.example.android.phonenumberspinner (androidTest), and open ExampleInstrumentedTest.
- Rename
ExampleInstrumentedTest
toSpinnerSelectionTest
in the class definition, and add the following:@RunWith(AndroidJUnit4.class) public class SpinnerSelectionTest { @Rule public ActivityTestRule mActivityRule = new ActivityTestRule<>( MainActivity.class); }
- Create the
iterateSpinnerItems()
method aspublic
returningvoid
.
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?
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 thegetActivity()
method of the ActivityTestRule class, and getting a resources instance in the application's package usinggetResources()
.- Assign the length of the array to
size
, and construct afor
loop using thesize
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
Add an
onView()
statement within thefor
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.
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)
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 resultingtext_phonelabel
matches the spinner item specified bymyArray[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)
- 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
- 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.
- Configure Espresso in your project as described previously.
- 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
- Choose Run > Record Espresso Test, select your deployment target (an emulator or a device), and click OK.
- 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").
- 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.
- 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.
- Click Save Assertion, and then click Complete Recording.
- In the dialog that appears, edit the name of the test to RecyclerViewTest so that it is easy to understand the test's purpose.
- Android Studio may display a request to add more dependencies to your Gradle Build file. Click Yes to add the dependencies.
- 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 customMatcher
: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.
- The
...
// 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
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.
- Using the
- 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 usinggetResources()
. - 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.
- Using the
- 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.
Related concept
The related concept documentation is in Android Developer Fundamentals: Concepts.
Learn more
Android Studio Documentation:
Android Developer Documentation:
- Best Practices for Testing
- Getting Started with Testing
- Testing UI for a Single App
- Building Instrumented Unit Tests
- Espresso Advanced Samples
- The Hamcrest Tutorial
- Hamcrest API and Utility Classes
- Test Support APIs
Android Testing Support Library:
Videos
- Android Testing Support - Android Testing Patterns #1 (introduction)
- Android Testing Support - Android Testing Patterns #2 (onView view matching)
- Android Testing Support - Android Testing Patterns #3 (onData and adapter views)
Other:
- Google Testing Blog: Android UI Automated Testing
- Atomic Object: "Espresso – Testing RecyclerViews at Specific Positions"
- Stack Overflow: "How to assert inside a RecyclerView in Espresso?"
- GitHub: Android Testing Samples
- Google Codelabs: Android Testing Codelab