blob: 29e955fcb550c78063251a267fd14732f5396636 [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 {
Quddus Chong900831f2015-04-17 15:01:16 -0700123 androidTestCompile 'com.android.support.test:runner:0.2'
124 androidTestCompile 'com.android.support.test:rules:0.2'
125 androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
Quddus Chong7639e732015-03-05 13:16:24 -0800126}
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&lt;MyActivity&gt; {
231
232 private MyActivity mActivity;
233
234 public MyEspressoTest() {
235 super(MyActivity.class);
236 }
237
238 &#64;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&lt;? super android.view.View&gt;)">{@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&lt;android.view.View&gt;, org.hamcrest.Matcher&lt;android.view.View&gt;)">{@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>