| page.title=Testing UI for a Single App | |
| page.tags=testing,espresso | |
| trainingnavtop=true | |
| @jd:body | |
| <!-- This is the training bar --> | |
| <div id="tb-wrapper"> | |
| <div id="tb"> | |
| <h2>Dependencies and Prerequisites</h2> | |
| <ul> | |
| <li>Android 2.2 (API level 8) or higher | |
| </li> | |
| <li> | |
| <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support | |
| Library</a> | |
| </li> | |
| </ul> | |
| <h2> | |
| This lesson teaches you to | |
| </h2> | |
| <ol> | |
| <li><a href="#setup">Set Up Espresso</a></li> | |
| <li><a href="#build">Create an Espresso Test Class</a></li> | |
| <li><a href="#run">Run Espresso Tests on a Device or Emulator</a></li> | |
| </ol> | |
| <h2> | |
| You should also read | |
| </h2> | |
| <ul> | |
| <li><a href="{@docRoot}reference/android/support/test/package-summary.html"> | |
| Espresso API Reference</a></li> | |
| </ul> | |
| <h2> | |
| Try it out | |
| </h2> | |
| <ul> | |
| <li> | |
| <a href="https://github.com/googlesamples/android-testing" | |
| class="external-link">Espresso Code Samples</a> | |
| </li> | |
| <li><a href="https://www.code-labs.io/codelabs/android-testing/index.html?index=..%2F..%2Findex#0" | |
| class="external-link">Android Testing Codelab</a></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <p> | |
| Testing user interactions | |
| within a single app helps to ensure that users do not | |
| encounter unexpected results or have a poor | |
| experience when interacting with your app. | |
| You should get into the habit of creating | |
| user interface (UI) tests if you need to verify | |
| that the UI of your app is functioning correctly. | |
| </p> | |
| <p> | |
| The Espresso testing framework, provided by the | |
| <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>, | |
| provides APIs for writing UI tests to simulate | |
| user interactions within a | |
| single target app. Espresso tests can run on | |
| devices running Android 2.3.3 (API level 10) and | |
| higher. A key benefit of using Espresso is | |
| that it provides automatic synchronization of test | |
| actions with the UI of the app you are testing. | |
| Espresso detects when the main thread is idle, | |
| so it is able to run your test commands | |
| at the appropriate time, improving the reliability of | |
| your tests. This capability also relieves you | |
| from having to add any timing workarounds, | |
| such as {@link java.lang.Thread#sleep(long) Thread.sleep()} | |
| in your test code. | |
| </p> | |
| <p> | |
| The Espresso testing framework is | |
| an instrumentation-based API and works with the | |
| <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code | |
| AndroidJUnitRunner}</a> test runner. | |
| </p> | |
| <h2 id="setup"> | |
| Set Up Espresso | |
| </h2> | |
| <p> | |
| Before building your UI test with Espresso, | |
| make sure to configure your test source code | |
| location and project dependencies, as described in | |
| <a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests">Getting Started with Testing</a>. | |
| </p> | |
| <p> | |
| In the {@code build.gradle} file of your Android app | |
| module, you must set a dependency | |
| reference to the Espresso library: | |
| </p> | |
| <pre> | |
| dependencies { | |
| // Other dependencies ... | |
| androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' | |
| } | |
| </pre> | |
| <p> | |
| Turn off animations on your test device — | |
| leaving system animations turned on in the test | |
| device might cause unexpected results or may | |
| lead your test to fail. Turn off animations from | |
| <em>Settings</em> by opening <em>Developer options</em> | |
| and turning all the following options off: | |
| </p> | |
| <p> | |
| <ul> | |
| <li> | |
| <strong>Window animation scale</strong> | |
| </li> | |
| <li> | |
| <strong>Transition animation scale</strong> | |
| </li> | |
| <li> | |
| <strong>Animator duration scale</strong> | |
| </li> | |
| </ul> | |
| </p> | |
| <p> | |
| If you want to set up your project to use Espresso | |
| features other than what the core API | |
| provides, see this | |
| <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html" | |
| class="external-link">resource</a>.</p> | |
| <!-- Section 2 --> | |
| <h2 id="build"> | |
| Create an Espresso Test Class | |
| </h2> | |
| <p> | |
| To create an Espresso test, create a Java | |
| class that follows this programming model: | |
| </p> | |
| <ol> | |
| <li> | |
| Find the UI component you want to test in | |
| an {@link android.app.Activity} (for example, a | |
| sign-in button in the app) by calling the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> | |
| {@code onView()}</a> method, or the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)"> | |
| {@code onData()}</a> method for {@link android.widget.AdapterView} controls. | |
| </li> | |
| <li> | |
| Simulate a specific user interaction to | |
| perform on that UI component, by calling the | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> | |
| or | |
| <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> | |
| method and passing in the user action | |
| (for example, click on the sign-in button). To sequence | |
| multiple actions on the same UI component, chain them using a comma-separated list in your | |
| method argument. | |
| </li> | |
| <li> | |
| Repeat the steps above as necessary, to simulate a user flow across multiple | |
| activities in the target app. | |
| </li> | |
| <li> | |
| Use the | |
| <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> | |
| methods to check that the UI reflects the expected | |
| state or behavior, after these user interactions are performed. | |
| </li> | |
| </ol> | |
| <p> | |
| These steps are covered in more detail in the sections below. | |
| </p> | |
| <p> | |
| The following code snippet shows how your test | |
| class might invoke this basic workflow: | |
| </p> | |
| <pre> | |
| onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher | |
| .perform(click()) // click() is a ViewAction | |
| .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion | |
| </pre> | |
| <!-- Section 2.1 --> | |
| <h3 id="espresso-atr"> | |
| Using Espresso with ActivityTestRule | |
| </h3> | |
| <p> | |
| The following section describes how to create a | |
| new Espresso test in the JUnit 4 style and use | |
| <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">{@code ActivityTestRule}</a> | |
| to reduce the amount of boilerplate code you need to write. By using | |
| <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">{@code ActivityTestRule}</a>, | |
| the testing framework launches the activity under test | |
| before each test method annotated with | |
| <code>@Test</code> and before any method annotated with | |
| <code>@Before</code>. The framework handles | |
| shutting down the activity after the test finishes | |
| and all methods annotated with <code>@After</code> are run. | |
| </p> | |
| <pre> | |
| package com.example.android.testing.espresso.BasicSample; | |
| import org.junit.Before; | |
| import org.junit.Rule; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import android.support.test.rule.ActivityTestRule; | |
| import android.support.test.runner.AndroidJUnit4; | |
| ... | |
| @RunWith(AndroidJUnit4.class) | |
| @LargeTest | |
| public class ChangeTextBehaviorTest { | |
| private String mStringToBetyped; | |
| @Rule | |
| public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>( | |
| MainActivity.class); | |
| @Before | |
| public void initValidString() { | |
| // Specify a valid string. | |
| mStringToBetyped = "Espresso"; | |
| } | |
| @Test | |
| public void changeText_sameActivity() { | |
| // Type text and then press the button. | |
| onView(withId(R.id.editTextUserInput)) | |
| .perform(typeText(mStringToBetyped), closeSoftKeyboard()); | |
| onView(withId(R.id.changeTextBt)).perform(click()); | |
| // Check that the text was changed. | |
| onView(withId(R.id.textToBeChanged)) | |
| .check(matches(withText(mStringToBetyped))); | |
| } | |
| } | |
| </pre> | |
| <!-- Section 2.2 --> | |
| <h3 id="accessing-ui-components"> | |
| Accessing UI Components | |
| </h3> | |
| <p> | |
| Before Espresso can interact with the app | |
| under test, you must first specify the UI component | |
| or <em>view</em>. Espresso supports the use of | |
| <a href="http://hamcrest.org/" class="external-link">Hamcrest matchers</a> | |
| for specifying views and adapters in your app. | |
| </p> | |
| <p> | |
| To find the view, call the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)">{@code onView()}</a> | |
| method and pass in a view matcher that | |
| specifies the view that you are targeting. This is | |
| described in more detail in | |
| <a href="#specifying-view-matcher">Specifying a View Matcher</a>. | |
| The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)">{@code onView()}</a> | |
| method returns a | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html">{@code ViewInteraction}</a> | |
| object that allows your test to interact with the view. | |
| However, calling the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> | |
| {@code onView()}</a> | |
| method may not work if you want to locate a view in | |
| an {@link android.support.v7.widget.RecyclerView} layout. | |
| In this case, follow the instructions in | |
| <a href="#locating-adpeterview-view">Locating a view in an AdapterView</a> | |
| instead. | |
| </p> | |
| <p class="note"> | |
| <strong>Note</strong>: | |
| The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)">{@code onView()}</a> | |
| method does not check if the view you specified is | |
| valid. Instead, Espresso searches only the | |
| current view hierarchy, using the matcher provided. | |
| If no match is found, the method throws a | |
| <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html">{@code NoMatchingViewException}</a>. | |
| </p> | |
| <p> | |
| The following code snippet shows how you might write a test that accesses an | |
| {@link android.widget.EditText} field, | |
| enters a string of text, closes the virtual keyboard, | |
| and then performs a button click. | |
| </p> | |
| <pre> | |
| public void testChangeText_sameActivity() { | |
| // Type text and then press the button. | |
| onView(withId(R.id.editTextUserInput)) | |
| .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); | |
| onView(withId(R.id.changeTextButton)).perform(click()); | |
| // Check that the text was changed. | |
| ... | |
| } | |
| </pre> | |
| <!-- Section 2.2.1 --> | |
| <h4 id="specifying-view-matcher"> | |
| Specifying a View Matcher | |
| </h4> | |
| <p> | |
| You can specify a view matcher by using these approaches: | |
| </p> | |
| <ul> | |
| <li>Calling methods in the | |
| <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html">{@code ViewMatchers}</a> | |
| class. For example, to find a view by looking for a text string it | |
| displays, you can call a method like this: | |
| <pre> | |
| onView(withText("Sign-in")); | |
| </pre> | |
| <p> | |
| Similarly you can call | |
| <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html#withId(int)">{@code withId()}</a> | |
| and providing the resource ID ({@code R.id}) of the view, | |
| as shown in the | |
| following example: | |
| </p> | |
| <pre> | |
| onView(withId(R.id.button_signin)); | |
| </pre> | |
| <p> | |
| Android resource IDs are not guaranteed to be unique. | |
| If your test attempts to match to a | |
| resource ID used by more than one view, Espresso throws an | |
| <a href="{@docRoot}reference/android/support/test/espresso/AmbiguousViewMatcherException.html">{@code AmbiguousViewMatcherException}</a>. | |
| </p> | |
| </li> | |
| <li> | |
| Using the Hamcrest | |
| <a href="http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html" | |
| class="external-link">{@code Matchers}</a> class. You can use the | |
| {@code allOf()} methods to combine multiple matchers, such as | |
| {@code containsString()} and {@code instanceOf()}. | |
| This approach allows you to | |
| filter the match results more narrowly, as shown in the following example: | |
| <pre> | |
| onView(allOf(withId(R.id.button_signin), withText("Sign-in"))); | |
| </pre> | |
| <p> | |
| You can use the {@code not} keyword to filter | |
| for views that don't correspond to the matcher, as | |
| shown in the following example: | |
| </p> | |
| <pre> | |
| onView(allOf(withId(R.id.button_signin), not(withText("Sign-out")))); | |
| </pre> | |
| <p> | |
| To use these methods in your test, | |
| import the {@code org.hamcrest.Matchers} package. To | |
| learn more about Hamcrest matching, see the | |
| <a href="http://hamcrest.org/" class="external-link">Hamcrest site</a>. | |
| </p> | |
| </li> | |
| </ul> | |
| <p> | |
| To improve the performance of your Espresso tests, | |
| specify the minimum matching information | |
| needed to find your target view. For example, | |
| if a view is uniquely identifiable by its | |
| descriptive text, you do not need to specify | |
| that it is also assignable from the | |
| {@link android.widget.TextView} instance. | |
| </p> | |
| <!-- Section 2.2.2 --> | |
| <h4 id="#locating-adpeterview-view"> | |
| Locating a view in an AdapterView | |
| </h4> | |
| <p> | |
| In an {@link android.widget.AdapterView} widget, | |
| the view is dynamically populated with child | |
| views at runtime. If the target view you want to test is inside an | |
| {@link android.widget.AdapterView} | |
| (such as a {@link android.widget.ListView}, | |
| {@link android.widget.GridView}, or | |
| {@link android.widget.Spinner}), the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)">{@code onView()}</a> | |
| method might not work because only a | |
| subset of the views may be loaded in the current view hierarchy. | |
| </p> | |
| <p> | |
| Instead, call the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> | |
| method to obtain a | |
| <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html">{@code DataInteraction}</a> | |
| object to access the target view element. | |
| Espresso handles loading the target view element | |
| into the current view hierarchy. Espresso | |
| also takes care of scrolling to the target element, | |
| and putting the element into focus. | |
| </p> | |
| <p class="note"> | |
| <strong>Note</strong>: The | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> | |
| method does not check if the item you | |
| specified corresponds with a view. Espresso searches | |
| only the current view hierarchy. If no match is found, the method throws a | |
| <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html">{@code NoMatchingViewException}</a>. | |
| </p> | |
| <p> | |
| The following code snippet shows how you can use the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> | |
| method together | |
| with Hamcrest matching to search for a specific | |
| row in a list that contains a given string. | |
| In this example, the {@code LongListActivity} class | |
| contains a list of strings exposed | |
| through a {@link android.widget.SimpleAdapter}. | |
| </p> | |
| <pre> | |
| onData(allOf(is(instanceOf(Map.class)), | |
| hasEntry(equalTo(LongListActivity.ROW_TEXT), is("test input"))); | |
| </pre> | |
| <!-- Section 2.3 --> | |
| <h3 id="perform-actions">Performing Actions</h3> | |
| <p> | |
| Call the | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> | |
| or | |
| <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> | |
| methods to | |
| simulate user interactions on the UI component. You must pass in one or more | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> | |
| objects as arguments. Espresso fires each action in sequence according to | |
| the given order, and executes them in the main thread. | |
| </p> | |
| <p> | |
| The | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html">{@code ViewActions}</a> | |
| class provides a list of helper methods for specifying common actions. | |
| You can use these methods as convenient shortcuts | |
| instead of creating and configuring individual | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> | |
| objects. You can specify such actions as: | |
| </p> | |
| <ul> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#click()">{@code ViewActions.click()}</a>: | |
| Clicks on the view. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#typeText(java.lang.String)">{@code ViewActions.typeText()}</a>: | |
| Clicks on a view and enters a specified string. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a>: | |
| Scrolls to the view. The | |
| target view must be subclassed from {@link android.widget.ScrollView} | |
| and the value of its | |
| <a href="http://developer.android.com/reference/android/view/View.html#attr_android:visibility">{@code android:visibility}</a> | |
| property must be {@link android.view.View#VISIBLE}. For views that extend | |
| {@link android.widget.AdapterView} (for example, | |
| {@link android.widget.ListView}), the | |
| <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> | |
| method takes care of scrolling for you. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#pressKey(int)">{@code ViewActions.pressKey()}</a>: | |
| Performs a key press using a specified keycode. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#clearText()">{@code ViewActions.clearText()}</a>: | |
| Clears the text in the target view. | |
| </li> | |
| </ul> | |
| <p> | |
| If the target view is inside a {@link android.widget.ScrollView}, | |
| perform the | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> | |
| action first to display the view in the screen before other proceeding | |
| with other actions. The | |
| <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> | |
| action will have no effect if the view is already displayed. | |
| </p> | |
| <!-- Section 2.4 --> | |
| <h3 id="intents"> | |
| Test your activities in isolation with Espresso Intents | |
| </h3> | |
| <p> | |
| <a href="https://google.github.io/android-testing-support-library/docs/espresso/intents/index.html" class="external-link">Espresso Intents</a> | |
| enables validation and stubbing of intents sent out by an app. | |
| With Espresso Intents, you can test an app, activity, or service in isolation | |
| by intercepting outgoing intents, stubbing the result, and sending it back to | |
| the component under test. | |
| </p> | |
| <p> | |
| To begin testing with Espresso Intents, you need | |
| to add the following line to your app's build.gradle file: | |
| </p> | |
| <pre> | |
| dependencies { | |
| // Other dependencies ... | |
| androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2' | |
| } | |
| </pre> | |
| <p> | |
| To test an intent, you need to create an instance of the | |
| <a href="{@docRoot}reference/android/support/test/espresso/intent/rule/IntentsTestRule.html">IntentsTestRule</a> | |
| class, which is very similar to the | |
| <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">ActivityTestRule</a> | |
| class. | |
| The | |
| <a href="{@docRoot}reference/android/support/test/espresso/intent/rule/IntentsTestRule.html">IntentsTestRule</a> | |
| class initializes Espresso Intents before each test, | |
| terminates the host activity, | |
| and releases Espresso Intents after each test. | |
| </p> | |
| <p> | |
| The test class shown in the following codes snippet provides a simple | |
| test for an explicit intent. It tests the activities and intents created in the | |
| <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a> | |
| tutorial. | |
| </p> | |
| <pre> | |
| @Large | |
| @RunWith(AndroidJUnit4.class) | |
| public class SimpleIntentTest { | |
| private static final String MESSAGE = "This is a test"; | |
| private static final String PACKAGE_NAME = "com.example.myfirstapp"; | |
| /* Instantiate an IntentsTestRule object. */ | |
| @Rule | |
| public IntentsTestRule≶MainActivity> mIntentsRule = | |
| new IntentsTestRule≶>(MainActivity.class); | |
| @Test | |
| public void verifyMessageSentToMessageActivity() { | |
| // Types a message into a EditText element. | |
| onView(withId(R.id.edit_message)) | |
| .perform(typeText(MESSAGE), closeSoftKeyboard()); | |
| // Clicks a button to send the message to another | |
| // activity through an explicit intent. | |
| onView(withId(R.id.send_message)).perform(click()); | |
| // Verifies that the DisplayMessageActivity received an intent | |
| // with the correct package name and message. | |
| intended(allOf( | |
| hasComponent(hasShortClassName(".DisplayMessageActivity")), | |
| toPackage(PACKAGE_NAME), | |
| hasExtra(MainActivity.EXTRA_MESSAGE, MESSAGE))); | |
| } | |
| } | |
| </pre> | |
| <p> | |
| For more information about Espresso Intents, see the | |
| <a href="https://google.github.io/android-testing-support-library/docs/espresso/intents/index.html" | |
| class="external-link">Espresso Intents | |
| documentation on the Android Testing Support Library site</a>. | |
| You can also download the | |
| <a href="https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IntentsBasicSample" | |
| class="external-link">IntentsBasicSample</a> and | |
| <a href="https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IntentsAdvancedSample" | |
| class="external-link">IntentsAdvancedSample</a> | |
| code samples. | |
| </p> | |
| <!-- Section 2.5 --> | |
| <h3 id="webviews"> | |
| Testing WebViews with Espresso Web | |
| </h3> | |
| <p> | |
| Espresso Web allows you to test {@link android.webkit.WebView} components | |
| contained within an activity. It uses the | |
| <a href="http://docs.seleniumhq.org/docs/03_webdriver.jsp" | |
| class="external-link">WebDriver API</a> to inspect and control the | |
| behavior of a {@link android.webkit.WebView}. | |
| </p> | |
| <p> | |
| To begin testing with Espresso Web, you need | |
| to add the following line to your app's build.gradle file: | |
| </p> | |
| <pre> | |
| dependencies { | |
| // Other dependencies ... | |
| androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2' | |
| } | |
| </pre> | |
| <p> | |
| When creating a test using Espresso Web, you need to enable | |
| JavaScript on the {@link android.webkit.WebView} when you instantiate the | |
| <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">ActivityTestRule</a> | |
| object to test the activity. In the tests, you can select | |
| HTML elements displayed in the | |
| {@link android.webkit.WebView} and simulate user interactions, like | |
| entering text into a text box and then clicking a button. After the actions | |
| are completed, you can then verify that the results on the | |
| Web page match the results that you expect. | |
| </p> | |
| <p> | |
| In the following code snippet, the class tests | |
| a {@link android.webkit.WebView} component with the id value 'webview' | |
| in the activity being tested. | |
| The <code>verifyValidInputYieldsSuccesfulSubmission()</code> test selects an | |
| <code><input></code> element on the | |
| Web page, enters some text, and checks text that appears in | |
| another element. | |
| </p> | |
| <pre> | |
| @LargeTest | |
| @RunWith(AndroidJUnit4.class) | |
| public class WebViewActivityTest { | |
| private static final String MACCHIATO = "Macchiato"; | |
| private static final String DOPPIO = "Doppio"; | |
| @Rule | |
| public ActivityTestRule<WebViewActivity> mActivityRule = | |
| new ActivityTestRule<WebViewActivity>(WebViewActivity.class, | |
| false /* Initial touch mode */, false /* launch activity */) { | |
| @Override | |
| protected void afterActivityLaunched() { | |
| // Enable JavaScript. | |
| onWebView().forceJavascriptEnabled(); | |
| } | |
| } | |
| @Test | |
| public void typeTextInInput_clickButton_SubmitsForm() { | |
| // Lazily launch the Activity with a custom start Intent per test | |
| mActivityRule.launchActivity(withWebFormIntent()); | |
| // Selects the WebView in your layout. | |
| // If you have multiple WebViews you can also use a | |
| // matcher to select a given WebView, onWebView(withId(R.id.web_view)). | |
| onWebView() | |
| // Find the input element by ID | |
| .withElement(findElement(Locator.ID, "text_input")) | |
| // Clear previous input | |
| .perform(clearElement()) | |
| // Enter text into the input element | |
| .perform(DriverAtoms.webKeys(MACCHIATO)) | |
| // Find the submit button | |
| .withElement(findElement(Locator.ID, "submitBtn")) | |
| // Simulate a click via JavaScript | |
| .perform(webClick()) | |
| // Find the response element by ID | |
| .withElement(findElement(Locator.ID, "response")) | |
| // Verify that the response page contains the entered text | |
| .check(webMatches(getText(), containsString(MACCHIATO))); | |
| } | |
| } | |
| </pre> | |
| <p> | |
| For more information about Espresso Web, see the | |
| <a href="https://google.github.io/android-testing-support-library/docs/espresso/web/index.html" | |
| class="external-link">Espresso | |
| Web documentation on the Android Testing Support Library site.</a>. | |
| You can also download this code snippet as part of the | |
| <a href="https://github.com/googlesamples/android-testing/tree/master/ui/espresso/WebBasicSample" | |
| class="external-link">Espresso Web code sample</a>. | |
| </p> | |
| <!-- Section 2.6 --> | |
| <h3 id="verify-results"> | |
| Verifying Results | |
| </h3> | |
| <p> | |
| Call the | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code ViewInteraction.check()}</a> | |
| or | |
| <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code DataInteraction.check()}</a> | |
| method to assert | |
| that the view in the UI matches some expected state. You must pass in a | |
| <a href="{@docRoot}reference/android/support/test/espresso/ViewAssertion.html">{@code ViewAssertion}</a> | |
| object as the argument. If the assertion fails, Espresso throws | |
| an {@link junit.framework.AssertionFailedError}. | |
| </p> | |
| <p> | |
| The | |
| <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> | |
| class provides a list of helper methods for specifying common | |
| assertions. The assertions you can use include: | |
| </p> | |
| <ul> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#doesNotExist()">{@code doesNotExist}</a>: | |
| Asserts that there is no view matching the specified | |
| criteria in the current view hierarchy. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#matches(org.hamcrest.Matcher<? super android.view.View>)">{@code matches}</a>: | |
| Asserts that the specified view exists in the current view hierarchy | |
| and its state matches some given Hamcrest matcher. | |
| </li> | |
| <li> | |
| <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#selectedDescendantsMatch(org.hamcrest.Matcher<android.view.View>, org.hamcrest.Matcher<android.view.View>)">{@code selectedDescendentsMatch}</a>: | |
| Asserts that the specified children views for a | |
| parent view exist, and their state matches some given Hamcrest matcher. | |
| </li> | |
| </ul> | |
| <p> | |
| The following code snippet shows how you might | |
| check that the text displayed in the UI has | |
| the same value as the text previously entered in the | |
| {@link android.widget.EditText} field. | |
| </p> | |
| <pre> | |
| public void testChangeText_sameActivity() { | |
| // Type text and then press the button. | |
| ... | |
| // Check that the text was changed. | |
| onView(withId(R.id.textToBeChanged)) | |
| .check(matches(withText(STRING_TO_BE_TYPED))); | |
| } | |
| </pre> | |
| <!-- Section 3 --> | |
| <h2 id="run"> | |
| Run Espresso Tests on a Device or Emulator | |
| </h2> | |
| <p> | |
| You can run Espresso tests from | |
| <a href="{@docRoot}studio/index.html">Android Studio</a> or | |
| from the command-line. Make sure to specify | |
| <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> | |
| as the default instrumentation runner in your project. | |
| </p> | |
| <p> | |
| To run your Espresso test, follow the steps for running instrumented tests | |
| described in | |
| <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests">Getting Started with Testing</a>. | |
| </p> |