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 <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> 60 </ul> 61 </div> 62 </div> 63 64 <p> 65 Testing user interactions 66 within a single app helps to ensure that users do not 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 95<p>Before building your UI test with Espresso, make sure to configure your test source code 96location and project dependencies, as described in 97<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> 98Getting Started with Testing</a>.</p> 99 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> 102 103<pre> 104dependencies { 105 ... 106 androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' 107} 108</pre> 109 110<p>Turn off animations on your test device — leaving system animations turned on in the test 111device 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> 114 <ul> 115 <li> 116 <strong>Window animation scale</strong> 117 </li> 118 119 <li> 120 <strong>Transition animation scale</strong> 121 </li> 122 123 <li> 124 <strong>Animator duration scale</strong> 125 </li> 126 </ul> 127 </li> 128 </ul> 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> 133 134 <h2 id="build"> 135 Create an Espresso Test Class 136 </h2> 137 138 <p> 139 To create an Espresso test, create a Java class that follows this programming model: 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> 180onView(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> 184<h3 id="espresso-atr">Using Espresso with ActivityTestRule</h3> 185<p> 186The 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 191before 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 193and all methods annotated with {@code @After} are run.</p> 194 195<pre> 196package com.example.android.testing.espresso.BasicSample; 197 198import org.junit.Before; 199import org.junit.Rule; 200import org.junit.Test; 201import org.junit.runner.RunWith; 202 203import android.support.test.rule.ActivityTestRule; 204import android.support.test.runner.AndroidJUnit4; 205... 206 207@RunWith(AndroidJUnit4.class) 208@LargeTest 209public 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> 236 237 <h3 id="espresso-aitc2"> 238 Using Espresso with ActivityInstrumentationTestCase2 239 </h3> 240<p>The following section describes how to migrate to Espresso if you have existing test classes 241subclassed from {@link android.test.ActivityInstrumentationTestCase2} and you don't want to rewrite 242them to use JUnit4.</p> 243<p class="note"><strong>Note:</strong> For new UI tests, we strongly recommend that you write your 244test 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> 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> 267import android.support.test.InstrumentationRegistry; 268 269public 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} 290would inject the {@link android.app.Instrumentation} instance, but this test runner is being 291deprecated.</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> 336public 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> 361onView(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 367following example:</p> 368 369<pre> 370onView(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> 387onView(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 390shown in the following example:</p> 391<pre> 392onView(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 395learn 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> 452onData(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>: 551Asserts 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> 573public 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> 584<p> 585You can run Espresso tests from <a href="{@docRoot}studio/index.html">Android Studio</a> or 586from 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> 591To run your Espresso test, follow the steps for running instrumented tests 592described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> 593Getting Started with Testing</a>.</p> 594