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