| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 1 | page.title=Testing UI for a Single App |
| 2 | page.tags=testing,espresso |
| 3 | trainingnavtop=true |
| 4 | |
| 5 | @jd:body |
| 6 | |
| 7 | <!-- This is the training bar --> |
| 8 | <div id="tb-wrapper"> |
| 9 | <div id="tb"> |
| 10 | <h2>Dependencies and Prerequisites</h2> |
| 11 | |
| 12 | <ul> |
| 13 | <li>Android 2.2 (API level 8) or higher |
| 14 | </li> |
| 15 | |
| 16 | <li> |
| 17 | <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support |
| 18 | Library</a> |
| 19 | </li> |
| 20 | </ul> |
| 21 | |
| 22 | <h2> |
| 23 | This lesson teaches you to |
| 24 | </h2> |
| 25 | |
| 26 | <ol> |
| 27 | <li> |
| 28 | <a href="#setup">Set Up Espresso</a> |
| 29 | </li> |
| 30 | |
| 31 | <li> |
| 32 | <a href="#build">Create an Espresso Test Class</a> |
| 33 | </li> |
| 34 | |
| 35 | <li> |
| 36 | <a href="#run">Run Espresso Tests on a Device or Emulator</a> |
| 37 | </li> |
| 38 | </ol> |
| 39 | |
| 40 | <h2> |
| 41 | You should also read |
| 42 | </h2> |
| 43 | |
| 44 | <ul> |
| 45 | <li><a href="{@docRoot}reference/android/support/test/package-summary.html"> |
| 46 | Espresso API Reference</a></li> |
| 47 | </ul> |
| 48 | |
| 49 | <h2> |
| 50 | Try it out |
| 51 | </h2> |
| 52 | |
| 53 | <ul> |
| 54 | <li> |
| 55 | <a href="https://github.com/googlesamples/android-testing" |
| 56 | class="external-link">Espresso Code Samples</a> |
| 57 | </li> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 58 | <li><a href="https://www.code-labs.io/codelabs/android-testing/index.html?index=..%2F..%2Findex#0" |
| 59 | class="external-link">Android Testing Codelab</a></li> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 60 | </ul> |
| 61 | </div> |
| 62 | </div> |
| 63 | |
| 64 | <p> |
| Quddus Chong | 54dee34 | 2015-04-03 17:06:28 -0700 | [diff] [blame] | 65 | Testing user interactions |
| 66 | within a single app helps to ensure that users do not |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 67 | encounter unexpected results or have a poor experience when interacting with your app. |
| 68 | You should get into the habit of creating user interface (UI) tests if you need to verify |
| 69 | that the UI of your app is functioning correctly. |
| 70 | </p> |
| 71 | |
| 72 | <p> |
| 73 | The Espresso testing framework, provided by the |
| 74 | <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>, |
| 75 | provides APIs for writing UI tests to simulate user interactions within a |
| 76 | single target app. Espresso tests can run on devices running Android 2.2 (API level 8) and |
| 77 | higher. A key benefit of using Espresso is that it provides automatic synchronization of test |
| 78 | actions with the UI of the app you are testing. Espresso detects when the main thread is idle, |
| 79 | so it is able to run your test commands at the appropriate time, improving the reliability of |
| 80 | your tests. This capability also relieves you from having to adding any timing workarounds, |
| 81 | such as a sleep period, in your test code. |
| 82 | </p> |
| 83 | |
| 84 | <p> |
| 85 | The Espresso testing framework is an instrumentation-based API and works |
| 86 | with the |
| 87 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code |
| 88 | AndroidJUnitRunner}</a> test runner. |
| 89 | </p> |
| 90 | |
| 91 | <h2 id="setup"> |
| 92 | Set Up Espresso |
| 93 | </h2> |
| 94 | |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 95 | <p>Before building your UI test with Espresso, make sure to configure your test source code |
| 96 | location and project dependencies, as described in |
| 97 | <a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> |
| 98 | Getting Started with Testing</a>.</p> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 99 | |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 100 | <p>In the {@code build.gradle} file of your Android app module, you must set a dependency |
| 101 | reference to the Espresso library:</p> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 102 | |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 103 | <pre> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 104 | dependencies { |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 105 | ... |
| Stephan Linzner | 342c987 | 2015-09-21 14:21:13 -0700 | [diff] [blame] | 106 | androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 107 | } |
| 108 | </pre> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 109 | |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 110 | <p>Turn off animations on your test device — leaving system animations turned on in the test |
| 111 | device might cause unexpected results or may lead your test to fail. Turn off animations from |
| 112 | <em>Settings</em> by opening <em>Developing Options</em> and turning all the following options off: |
| 113 | </p> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 114 | <ul> |
| 115 | <li> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 116 | <strong>Window animation scale</strong> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 117 | </li> |
| 118 | |
| 119 | <li> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 120 | <strong>Transition animation scale</strong> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 121 | </li> |
| 122 | |
| 123 | <li> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 124 | <strong>Animator duration scale</strong> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 125 | </li> |
| 126 | </ul> |
| 127 | </li> |
| 128 | </ul> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 129 | <p>If you want to set up your project to use Espresso features other than what the core API |
| 130 | provides, see this |
| 131 | <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html" |
| 132 | class="external-link">resource</a>.</p> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 133 | |
| 134 | <h2 id="build"> |
| 135 | Create an Espresso Test Class |
| 136 | </h2> |
| 137 | |
| 138 | <p> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 139 | To create an Espresso test, create a Java class that follows this programming model: |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 140 | </p> |
| 141 | |
| 142 | <ol> |
| 143 | <li>Find the UI component you want to test in an {@link android.app.Activity} (for example, a |
| 144 | sign-in button in the app) by calling the |
| 145 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 146 | {@code onView()}</a> method, or the |
| 147 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)"> |
| 148 | {@code onData()}</a> method for {@link android.widget.AdapterView} controls. |
| 149 | </li> |
| 150 | |
| 151 | <li>Simulate a specific user interaction to perform on that UI component, by calling the |
| 152 | <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> |
| 153 | or |
| 154 | <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> |
| 155 | method and passing in the user action (for example, click on the sign-in button). To sequence |
| 156 | multiple actions on the same UI component, chain them using a comma-separated list in your |
| 157 | method argument. |
| 158 | </li> |
| 159 | |
| 160 | <li>Repeat the steps above as necessary, to simulate a user flow across multiple |
| 161 | activities in the target app. |
| 162 | </li> |
| 163 | |
| 164 | <li>Use the |
| 165 | <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> |
| 166 | methods to check that the UI reflects the expected |
| 167 | state or behavior, after these user interactions are performed. |
| 168 | </li> |
| 169 | </ol> |
| 170 | |
| 171 | <p> |
| 172 | These steps are covered in more detail in the sections below. |
| 173 | </p> |
| 174 | |
| 175 | <p> |
| 176 | The following code snippet shows how your test class might invoke this basic workflow: |
| 177 | </p> |
| 178 | |
| 179 | <pre> |
| 180 | onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher |
| 181 | .perform(click()) // click() is a ViewAction |
| 182 | .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion |
| 183 | </pre> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 184 | <h3 id="espresso-atr">Using Espresso with ActivityTestRule</h3> |
| 185 | <p> |
| 186 | The following section describes how to create a new Espresso test in the JUnit 4 style and use |
| 187 | <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> |
| 188 | {@code ActivityTestRule}</a> to reduce the amount of boilerplate code you need to write. By using |
| 189 | <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> |
| 190 | {@code ActivityTestRule}</a>, the testing framework launches the activity under test |
| 191 | before each test method annotated with {@code @Test} and before any method annotated with |
| 192 | {@code @Before}. The framework handles shutting down the activity after the test finishes |
| 193 | and all methods annotated with {@code @After} are run.</p> |
| 194 | |
| 195 | <pre> |
| 196 | package com.example.android.testing.espresso.BasicSample; |
| 197 | |
| 198 | import org.junit.Before; |
| 199 | import org.junit.Rule; |
| 200 | import org.junit.Test; |
| 201 | import org.junit.runner.RunWith; |
| 202 | |
| 203 | import android.support.test.rule.ActivityTestRule; |
| 204 | import android.support.test.runner.AndroidJUnit4; |
| 205 | ... |
| 206 | |
| 207 | @RunWith(AndroidJUnit4.class) |
| 208 | @LargeTest |
| 209 | public class ChangeTextBehaviorTest { |
| 210 | |
| 211 | private String mStringToBetyped; |
| 212 | |
| 213 | @Rule |
| 214 | public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>( |
| 215 | MainActivity.class); |
| 216 | |
| 217 | @Before |
| 218 | public void initValidString() { |
| 219 | // Specify a valid string. |
| 220 | mStringToBetyped = "Espresso"; |
| 221 | } |
| 222 | |
| 223 | @Test |
| 224 | public void changeText_sameActivity() { |
| 225 | // Type text and then press the button. |
| 226 | onView(withId(R.id.editTextUserInput)) |
| 227 | .perform(typeText(mStringToBetyped), closeSoftKeyboard()); |
| 228 | onView(withId(R.id.changeTextBt)).perform(click()); |
| 229 | |
| 230 | // Check that the text was changed. |
| 231 | onView(withId(R.id.textToBeChanged)) |
| 232 | .check(matches(withText(mStringToBetyped))); |
| 233 | } |
| 234 | } |
| 235 | </pre> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 236 | |
| 237 | <h3 id="espresso-aitc2"> |
| 238 | Using Espresso with ActivityInstrumentationTestCase2 |
| 239 | </h3> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 240 | <p>The following section describes how to migrate to Espresso if you have existing test classes |
| 241 | subclassed from {@link android.test.ActivityInstrumentationTestCase2} and you don't want to rewrite |
| 242 | them to use JUnit4.</p> |
| 243 | <p class="note"><strong>Note:</strong> For new UI tests, we strongly recommend that you write your |
| 244 | test in the JUnit 4 style and use the |
| 245 | <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> |
| 246 | {@code ActivityTestRule}</a> class, instead of |
| 247 | {@link android.test.ActivityInstrumentationTestCase2}.</p> |
| Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 248 | <p> |
| 249 | If you are subclassing {@link android.test.ActivityInstrumentationTestCase2} |
| 250 | to create your Espresso test class, you must inject an |
| 251 | {@link android.app.Instrumentation} instance into your test class. This step is required in |
| 252 | order for your Espresso test to run with the |
| 253 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> |
| 254 | test runner. |
| 255 | </p> |
| 256 | |
| 257 | <p> |
| 258 | To do this, call the |
| 259 | {@link android.test.InstrumentationTestCase#injectInstrumentation(android.app.Instrumentation) injectInstrumentation()} |
| 260 | method and pass in the result of |
| 261 | <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html#getInstrumentation()"> |
| 262 | {@code InstrumentationRegistry.getInstrumentation()}</a>, as shown in the following code |
| 263 | example: |
| 264 | </p> |
| 265 | |
| 266 | <pre> |
| 267 | import android.support.test.InstrumentationRegistry; |
| 268 | |
| 269 | public class MyEspressoTest |
| 270 | extends ActivityInstrumentationTestCase2<MyActivity> { |
| 271 | |
| 272 | private MyActivity mActivity; |
| 273 | |
| 274 | public MyEspressoTest() { |
| 275 | super(MyActivity.class); |
| 276 | } |
| 277 | |
| 278 | @Before |
| 279 | public void setUp() throws Exception { |
| 280 | super.setUp(); |
| 281 | injectInstrumentation(InstrumentationRegistry.getInstrumentation()); |
| 282 | mActivity = getActivity(); |
| 283 | } |
| 284 | |
| 285 | ... |
| 286 | } |
| 287 | </pre> |
| 288 | |
| 289 | <p class="note"><strong>Note:</strong> Previously, {@link android.test.InstrumentationTestRunner} |
| 290 | would inject the {@link android.app.Instrumentation} instance, but this test runner is being |
| 291 | deprecated.</p> |
| 292 | |
| 293 | <h3 id="accessing-ui-components"> |
| 294 | Accessing UI Components |
| 295 | </h3> |
| 296 | |
| 297 | <p> |
| 298 | Before Espresso can interact with the app under test, you must first specify the UI component |
| 299 | or <em>view</em>. Espresso supports the use of |
| 300 | <a href="http://hamcrest.org/" class="external-link">Hamcrest matchers</a> |
| 301 | for specifying views and adapters in your app. |
| 302 | </p> |
| 303 | |
| 304 | <p> |
| 305 | To find the view, call the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 306 | {@code onView()}</a> |
| 307 | method and pass in a view matcher that specifies the view that you are targeting. This is |
| 308 | described in more detail in <a href="#specifying-view-matcher">Specifying a View Matcher</a>. |
| 309 | The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 310 | {@code onView()}</a> method returns a |
| 311 | <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html"> |
| 312 | {@code ViewInteraction}</a> |
| 313 | object that allows your test to interact with the view. |
| 314 | However, calling the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 315 | {@code onView()}</a> method may not work if you want to locate a view in |
| 316 | an {@link android.widget.AdapterView} layout. In this case, follow the instructions in |
| 317 | <a href="#locating-adpeterview-view">Locating a view in an AdapterView</a> instead. |
| 318 | </p> |
| 319 | |
| 320 | <p class="note"> |
| 321 | <strong>Note</strong>: The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 322 | {@code onView()}</a> method does not check if the view you specified is |
| 323 | valid. Instead, Espresso searches only the current view hierarchy, using the matcher provided. |
| 324 | If no match is found, the method throws a |
| 325 | <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html"> |
| 326 | {@code NoMatchingViewException}</a>. |
| 327 | </p> |
| 328 | |
| 329 | <p> |
| 330 | The following code snippet shows how you might write a test that accesses an |
| 331 | {@link android.widget.EditText} field, enters a string of text, closes the virtual keyboard, |
| 332 | and then performs a button click. |
| 333 | </p> |
| 334 | |
| 335 | <pre> |
| 336 | public void testChangeText_sameActivity() { |
| 337 | // Type text and then press the button. |
| 338 | onView(withId(R.id.editTextUserInput)) |
| 339 | .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); |
| 340 | onView(withId(R.id.changeTextButton)).perform(click()); |
| 341 | |
| 342 | // Check that the text was changed. |
| 343 | ... |
| 344 | } |
| 345 | </pre> |
| 346 | |
| 347 | <h4 id="specifying-view-matcher"> |
| 348 | Specifying a View Matcher |
| 349 | </h4> |
| 350 | |
| 351 | <p> |
| 352 | You can specify a view matcher by using these approaches: |
| 353 | </p> |
| 354 | |
| 355 | <ul> |
| 356 | <li>Calling methods in the |
| 357 | <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html"> |
| 358 | {@code ViewMatchers}</a> class. For example, to find a view by looking for a text string it |
| 359 | displays, you can call a method like this: |
| 360 | <pre> |
| 361 | onView(withText("Sign-in")); |
| 362 | </pre> |
| 363 | |
| 364 | <p>Similarly you can call |
| 365 | <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html#withId(int)"> |
| 366 | {@code withId()}</a> and providing the resource ID ({@code R.id}) of the view, as shown in the |
| 367 | following example:</p> |
| 368 | |
| 369 | <pre> |
| 370 | onView(withId(R.id.button_signin)); |
| 371 | </pre> |
| 372 | |
| 373 | <p> |
| 374 | Android resource IDs are not guaranteed to be unique. If your test attempts to match to a |
| 375 | resource ID used by more than one view, Espresso throws an |
| 376 | <a href="{@docRoot}reference/android/support/test/espresso/AmbiguousViewMatcherException.html"> |
| 377 | {@code AmbiguousViewMatcherException}</a>. |
| 378 | </p> |
| 379 | </li> |
| 380 | <li>Using the Hamcrest |
| 381 | <a href="http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html" |
| 382 | class="external-link">{@code Matchers}</a> class. You can use the |
| 383 | {@code allOf()} methods to combine multiple matchers, such as |
| 384 | {@code containsString()} and {@code instanceOf()}. This approach allows you to |
| 385 | filter the match results more narrowly, as shown in the following example: |
| 386 | <pre> |
| 387 | onView(allOf(withId(R.id.button_signin), withText("Sign-in"))); |
| 388 | </pre> |
| 389 | <p>You can use the {@code not} keyword to filter for views that don't correspond to the matcher, as |
| 390 | shown in the following example:</p> |
| 391 | <pre> |
| 392 | onView(allOf(withId(R.id.button_signin), not(withText("Sign-out")))); |
| 393 | </pre> |
| 394 | <p>To use these methods in your test, import the {@code org.hamcrest.Matchers} package. To |
| 395 | learn more about Hamcrest matching, see the |
| 396 | <a href="http://hamcrest.org/" class="external-link">Hamcrest site</a>. |
| 397 | </p> |
| 398 | </li> |
| 399 | </ul> |
| 400 | |
| 401 | <p> |
| 402 | To improve the performance of your Espresso tests, specify the minimum matching information |
| 403 | needed to find your target view. For example, if a view is uniquely identifiable by its |
| 404 | descriptive text, you do not need to specify that it is also assignable from the |
| 405 | {@link android.widget.TextView} instance. |
| 406 | </p> |
| 407 | |
| 408 | <h4 id="#locating-adpeterview-view"> |
| 409 | Locating a view in an AdapterView |
| 410 | </h4> |
| 411 | |
| 412 | <p> |
| 413 | In an {@link android.widget.AdapterView} widget, the view is dynamically populated with child |
| 414 | views at runtime. If the target view you want to test is inside an |
| 415 | {@link android.widget.AdapterView} |
| 416 | (such as a {@link android.widget.ListView}, {@link android.widget.GridView}, or |
| 417 | {@link android.widget.Spinner}), the |
| 418 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> |
| 419 | {@code onView()}</a> method might not work because only a |
| 420 | subset of the views may be loaded in the current view hierarchy. |
| 421 | </p> |
| 422 | |
| 423 | <p> |
| 424 | Instead, call the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> |
| 425 | method to obtain a |
| 426 | <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html"> |
| 427 | {@code DataInteraction}</a> |
| 428 | object to access the target view element. Espresso handles loading the target view element |
| 429 | into the current view hierarchy. Espresso also takes care of scrolling to the target element, |
| 430 | and putting the element into focus. |
| 431 | </p> |
| 432 | |
| 433 | <p class="note"> |
| 434 | <strong>Note</strong>: The |
| 435 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> |
| 436 | method does not check if if the item you specified corresponds with a view. Espresso searches |
| 437 | only the current view hierarchy. If no match is found, the method throws a |
| 438 | <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html"> |
| 439 | {@code NoMatchingViewException}</a>. |
| 440 | </p> |
| 441 | |
| 442 | <p> |
| 443 | The following code snippet shows how you can use the |
| 444 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> |
| 445 | method together |
| 446 | with Hamcrest matching to search for a specific row in a list that contains a given string. |
| 447 | In this example, the {@code LongListActivity} class contains a list of strings exposed |
| 448 | through a {@link android.widget.SimpleAdapter}. |
| 449 | </p> |
| 450 | |
| 451 | <pre> |
| 452 | onData(allOf(is(instanceOf(Map.class)), |
| 453 | hasEntry(equalTo(LongListActivity.ROW_TEXT), is(str)))); |
| 454 | </pre> |
| 455 | |
| 456 | <h3 id="perform-actions"> |
| 457 | Performing Actions |
| 458 | </h3> |
| 459 | |
| 460 | <p> |
| 461 | Call the <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> |
| 462 | or |
| 463 | <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> |
| 464 | methods to |
| 465 | simulate user interactions on the UI component. You must pass in one or more |
| 466 | <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> |
| 467 | objects as arguments. Espresso fires each action in sequence according to |
| 468 | the given order, and executes them in the main thread. |
| 469 | </p> |
| 470 | |
| 471 | <p> |
| 472 | The |
| 473 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html">{@code ViewActions}</a> |
| 474 | class provides a list of helper methods for specifying common actions. |
| 475 | You can use these methods as convenient shortcuts instead of creating and configuring |
| 476 | individual <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> |
| 477 | objects. You can specify such actions as: |
| 478 | </p> |
| 479 | |
| 480 | <ul> |
| 481 | <li> |
| 482 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#click()">{@code ViewActions.click()}</a>: |
| 483 | Clicks on the view. |
| 484 | </li> |
| 485 | |
| 486 | <li> |
| 487 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#typeText(java.lang.String)">{@code ViewActions.typeText()}</a>: |
| 488 | Clicks on a view and enters a specified string. |
| 489 | </li> |
| 490 | |
| 491 | <li> |
| 492 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a>: |
| 493 | Scrolls to the view. The |
| 494 | target view must be subclassed from {@link android.widget.ScrollView} |
| 495 | and the value of its |
| 496 | <a href="http://developer.android.com/reference/android/view/View.html#attr_android:visibility">{@code android:visibility}</a> |
| 497 | property must be {@link android.view.View#VISIBLE}. For views that extend |
| 498 | {@link android.widget.AdapterView} (for example, |
| 499 | {@link android.widget.ListView}), |
| 500 | the |
| 501 | <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> |
| 502 | method takes care of scrolling for you. |
| 503 | </li> |
| 504 | |
| 505 | <li> |
| 506 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#pressKey(int)">{@code ViewActions.pressKey()}</a>: |
| 507 | Performs a key press using a specified keycode. |
| 508 | </li> |
| 509 | |
| 510 | <li> |
| 511 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#clearText()">{@code ViewActions.clearText()}</a>: |
| 512 | Clears the text in the target view. |
| 513 | </li> |
| 514 | </ul> |
| 515 | |
| 516 | <p> |
| 517 | If the target view is inside a {@link android.widget.ScrollView}, perform the |
| 518 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> |
| 519 | action first to display the view in the screen before other proceeding |
| 520 | with other actions. The |
| 521 | <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> |
| 522 | action will have no effect if the view is already displayed. |
| 523 | </p> |
| 524 | |
| 525 | <h3 id="verify-results"> |
| 526 | Verifying Results |
| 527 | </h3> |
| 528 | |
| 529 | <p> |
| 530 | Call the |
| 531 | <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code ViewInteraction.check()}</a> |
| 532 | or |
| 533 | <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code DataInteraction.check()}</a> |
| 534 | method to assert |
| 535 | that the view in the UI matches some expected state. You must pass in a |
| 536 | <a href="{@docRoot}reference/android/support/test/espresso/ViewAssertion.html"> |
| 537 | {@code ViewAssertion}</a> object as the argument. If the assertion fails, Espresso throws |
| 538 | an {@link junit.framework.AssertionFailedError}. |
| 539 | </p> |
| 540 | |
| 541 | <p> |
| 542 | The |
| 543 | <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> |
| 544 | class provides a list of helper methods for specifying common |
| 545 | assertions. The assertions you can use include: |
| 546 | </p> |
| 547 | |
| 548 | <ul> |
| 549 | <li> |
| 550 | <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#doesNotExist()">{@code doesNotExist}</a>: |
| 551 | Asserts that there is no view matching the specified criteria in the current view hierarchy. |
| 552 | </li> |
| 553 | |
| 554 | <li> |
| 555 | <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#matches(org.hamcrest.Matcher<? super android.view.View>)">{@code matches}</a>: |
| 556 | Asserts that the specified view exists in the current view hierarchy |
| 557 | and its state matches some given Hamcrest matcher. |
| 558 | </li> |
| 559 | |
| 560 | <li> |
| 561 | <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> |
| 562 | : Asserts that the specified children views for a |
| 563 | parent view exist, and their state matches some given Hamcrest matcher. |
| 564 | </li> |
| 565 | </ul> |
| 566 | |
| 567 | <p> |
| 568 | The following code snippet shows how you might check that the text displayed in the UI has |
| 569 | the same value as the text previously entered in the |
| 570 | {@link android.widget.EditText} field. |
| 571 | </p> |
| 572 | <pre> |
| 573 | public void testChangeText_sameActivity() { |
| 574 | // Type text and then press the button. |
| 575 | ... |
| 576 | |
| 577 | // Check that the text was changed. |
| 578 | onView(withId(R.id.textToBeChanged)) |
| 579 | .check(matches(withText(STRING_TO_BE_TYPED))); |
| 580 | } |
| 581 | </pre> |
| 582 | |
| 583 | <h2 id="run">Run Espresso Tests on a Device or Emulator</h2> |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 584 | <p> |
| smain@google.com | 89d1170 | 2016-05-14 19:20:00 -0700 | [diff] [blame] | 585 | You can run Espresso tests from <a href="{@docRoot}studio/index.html">Android Studio</a> or |
| Quddus Chong | e3f6c81 | 2015-08-26 14:16:05 -0700 | [diff] [blame] | 586 | from the command-line. Make sure to specify |
| 587 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> |
| 588 | {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project. |
| 589 | </p> |
| 590 | <p> |
| 591 | To run your Espresso test, follow the steps for running instrumented tests |
| 592 | described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> |
| 593 | Getting Started with Testing</a>.</p> |