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