diff options
author | Quddus Chong <quddusc@google.com> | 2015-04-03 21:49:43 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-03 21:49:43 +0000 |
commit | cef55cde1cf1b9b15583d6b4c439dfea7bac7c26 (patch) | |
tree | ae2eda7368dee1539b62ef5ba289250b85a0ce1a | |
parent | 7c167023ed4a9363bfae0ae64c23dde10d5e1d7c (diff) | |
parent | b3c310b60dfab11b9b8d41b00ae06a82090f3d14 (diff) | |
download | frameworks_base-cef55cde1cf1b9b15583d6b4c439dfea7bac7c26.zip frameworks_base-cef55cde1cf1b9b15583d6b4c439dfea7bac7c26.tar.gz frameworks_base-cef55cde1cf1b9b15583d6b4c439dfea7bac7c26.tar.bz2 |
am b3c310b6: am ba386b55: am f2c2be78: am d9e2c05d: am 0c3b894c: am 91070dc4: Merge "docs: Added training docs for UI testing frameworks (Espresso, UI Automator)." into lmp-docs
* commit 'b3c310b60dfab11b9b8d41b00ae06a82090f3d14':
docs: Added training docs for UI testing frameworks (Espresso, UI Automator).
-rw-r--r-- | docs/html/tools/testing-support-library/index.jd | 8 | ||||
-rw-r--r-- | docs/html/training/testing/ui-testing/espresso-testing.jd | 579 | ||||
-rw-r--r-- | docs/html/training/testing/ui-testing/index.jd | 76 | ||||
-rw-r--r-- | docs/html/training/testing/ui-testing/uiautomator-testing.jd | 520 | ||||
-rw-r--r-- | docs/html/training/training_toc.cs | 18 |
5 files changed, 1199 insertions, 2 deletions
diff --git a/docs/html/tools/testing-support-library/index.jd b/docs/html/tools/testing-support-library/index.jd index aeace8e..c8c9ef5 100644 --- a/docs/html/tools/testing-support-library/index.jd +++ b/docs/html/tools/testing-support-library/index.jd @@ -391,7 +391,9 @@ onView(withId(R.id.changeTextBt)).perform(click());</pre> <p> To learn more about using Espresso, see the - <a href="{@docRoot}reference/android/support/test/package-summary.html">API reference</a>. + <a href="{@docRoot}reference/android/support/test/package-summary.html">API reference</a> and + <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html"> + Testing UI for a Single App</a> training. </p> <h3 id="UIAutomator"> @@ -531,7 +533,9 @@ allAppsButton.clickAndWaitForNewWindow();</pre> <p> To learn more about using UI Automator, see the - <a href="{@docRoot}reference/android/support/test/package-summary.html">API reference</a>. + <a href="{@docRoot}reference/android/support/test/package-summary.html">API reference</a> and + <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html"> + Testing UI for Multiple Apps</a> training. </p> <h2 id="setup"> diff --git a/docs/html/training/testing/ui-testing/espresso-testing.jd b/docs/html/training/testing/ui-testing/espresso-testing.jd new file mode 100644 index 0000000..e5e37f7 --- /dev/null +++ b/docs/html/training/testing/ui-testing/espresso-testing.jd @@ -0,0 +1,579 @@ +page.title=Testing UI for a Single App +page.tags=testing,espresso +trainingnavtop=true + +@jd:body + +<!-- This is the training bar --> +<div id="tb-wrapper"> +<div id="tb"> + <h2>Dependencies and Prerequisites</h2> + + <ul> + <li>Android 2.2 (API level 8) or higher + </li> + + <li> + <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support + Library</a> + </li> + </ul> + + <h2> + This lesson teaches you to + </h2> + + <ol> + <li> + <a href="#setup">Set Up Espresso</a> + </li> + + <li> + <a href="#build">Create an Espresso Test Class</a> + </li> + + <li> + <a href="#run">Run Espresso Tests on a Device or Emulator</a> + </li> + </ol> + + <h2> + You should also read + </h2> + + <ul> + <li><a href="{@docRoot}reference/android/support/test/package-summary.html"> + Espresso API Reference</a></li> + </ul> + + <h2> + Try it out + </h2> + + <ul> + <li> + <a href="https://github.com/googlesamples/android-testing" + class="external-link">Espresso Code Samples</a> + </li> + </ul> + </div> + </div> + + <p> + UI tests that involve user interactions + within a single app help to ensure that users do not + encounter unexpected results or have a poor experience when interacting with your app. + You should get into the habit of creating user interface (UI) tests if you need to verify + that the UI of your app is functioning correctly. + </p> + + <p> + The Espresso testing framework, provided by the + <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>, + provides APIs for writing UI tests to simulate user interactions within a + single target app. Espresso tests can run on devices running Android 2.2 (API level 8) and + higher. A key benefit of using Espresso is that it provides automatic synchronization of test + actions with the UI of the app you are testing. Espresso detects when the main thread is idle, + so it is able to run your test commands at the appropriate time, improving the reliability of + your tests. This capability also relieves you from having to adding any timing workarounds, + such as a sleep period, in your test code. + </p> + + <p> + The Espresso testing framework is an instrumentation-based API and works + with the + <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code + AndroidJUnitRunner}</a> test runner. + </p> + + <h2 id="setup"> + Set Up Espresso + </h2> + + <p> + Before you begin using Espresso, you must: + </p> + + <ul> + <li> + <strong>Install the Android Testing Support Library</strong>. The Espresso API is + located under the {@code com.android.support.test.espresso} package. These classes allow + you to create tests that use the Espresso testing framework. To learn how to install the + library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> + Testing Support Library Setup</a>. + </li> + + <li> + <strong>Set up your project structure.</strong> In your Gradle project, the source code for + the target app that you want to test is typically placed under the {@code app/src/main} + folder. The source code for instrumentation tests, including + your Espresso tests, must be placed under the <code>app/src/androidTest</code> folder. To + learn more about setting up your project directory, see + <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. + </li> + + <li> + <strong>Specify your Android testing dependencies</strong>. In order for the + <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to + correctly build and run your Espresso tests, you must specify the following libraries in + the {@code build.gradle} file of your Android app module: + + <pre> +dependencies { + androidTestCompile 'com.android.support.test:testing-support-lib:0.1' + androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0' +} +</pre> + </li> + + <li> + <strong>Turn off animations on your test device.</strong> Leaving system animations turned + on in the test device might cause unexpected results or may lead your test to fail. Turn + off animations from <em>Settings</em> by opening <em>Developing Options</em> and + turning all the following options off: + <ul> + <li> + <em>Window animation scale</em> + </li> + + <li> + <em>Transition animation scale</em> + </li> + + <li> + <em>Animator duration scale</em> + </li> + </ul> + </li> + </ul> + + <h2 id="build"> + Create an Espresso Test Class + </h2> + + <p> + To create an Espresso test, create a Java class or an + {@link android.test.ActivityInstrumentationTestCase2} + subclass that follows this programming model: + </p> + + <ol> + <li>Find the UI component you want to test in an {@link android.app.Activity} (for example, a + sign-in button in the app) by calling the + <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> method, or the + <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)"> + {@code onData()}</a> method for {@link android.widget.AdapterView} controls. + </li> + + <li>Simulate a specific user interaction to perform on that UI component, by calling the + <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> + or + <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> + method and passing in the user action (for example, click on the sign-in button). To sequence + multiple actions on the same UI component, chain them using a comma-separated list in your + method argument. + </li> + + <li>Repeat the steps above as necessary, to simulate a user flow across multiple + activities in the target app. + </li> + + <li>Use the + <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> + methods to check that the UI reflects the expected + state or behavior, after these user interactions are performed. + </li> + </ol> + + <p> + These steps are covered in more detail in the sections below. + </p> + + <p> + The following code snippet shows how your test class might invoke this basic workflow: + </p> + +<pre> +onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher + .perform(click()) // click() is a ViewAction + .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion +</pre> + + <h3 id="espresso-aitc2"> + Using Espresso with ActivityInstrumentationTestCase2 + </h3> + + <p> + If you are subclassing {@link android.test.ActivityInstrumentationTestCase2} + to create your Espresso test class, you must inject an + {@link android.app.Instrumentation} instance into your test class. This step is required in + order for your Espresso test to run with the + <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> + test runner. + </p> + + <p> + To do this, call the + {@link android.test.InstrumentationTestCase#injectInstrumentation(android.app.Instrumentation) injectInstrumentation()} + method and pass in the result of + <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html#getInstrumentation()"> + {@code InstrumentationRegistry.getInstrumentation()}</a>, as shown in the following code + example: + </p> + +<pre> +import android.support.test.InstrumentationRegistry; + +public class MyEspressoTest + extends ActivityInstrumentationTestCase2<MyActivity> { + + private MyActivity mActivity; + + public MyEspressoTest() { + super(MyActivity.class); + } + + @Before + public void setUp() throws Exception { + super.setUp(); + injectInstrumentation(InstrumentationRegistry.getInstrumentation()); + mActivity = getActivity(); + } + + ... +} +</pre> + +<p class="note"><strong>Note:</strong> Previously, {@link android.test.InstrumentationTestRunner} +would inject the {@link android.app.Instrumentation} instance, but this test runner is being +deprecated.</p> + + <h3 id="accessing-ui-components"> + Accessing UI Components + </h3> + + <p> + Before Espresso can interact with the app under test, you must first specify the UI component + or <em>view</em>. Espresso supports the use of +<a href="http://hamcrest.org/" class="external-link">Hamcrest matchers</a> + for specifying views and adapters in your app. + </p> + + <p> + To find the view, call the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> + method and pass in a view matcher that specifies the view that you are targeting. This is + described in more detail in <a href="#specifying-view-matcher">Specifying a View Matcher</a>. + The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> method returns a + <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html"> + {@code ViewInteraction}</a> + object that allows your test to interact with the view. + However, calling the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> method may not work if you want to locate a view in + an {@link android.widget.AdapterView} layout. In this case, follow the instructions in + <a href="#locating-adpeterview-view">Locating a view in an AdapterView</a> instead. + </p> + + <p class="note"> + <strong>Note</strong>: The <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> method does not check if the view you specified is + valid. Instead, Espresso searches only the current view hierarchy, using the matcher provided. + If no match is found, the method throws a + <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html"> + {@code NoMatchingViewException}</a>. + </p> + + <p> + The following code snippet shows how you might write a test that accesses an + {@link android.widget.EditText} field, enters a string of text, closes the virtual keyboard, + and then performs a button click. + </p> + +<pre> +public void testChangeText_sameActivity() { + // Type text and then press the button. + onView(withId(R.id.editTextUserInput)) + .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); + onView(withId(R.id.changeTextButton)).perform(click()); + + // Check that the text was changed. + ... +} +</pre> + + <h4 id="specifying-view-matcher"> + Specifying a View Matcher + </h4> + + <p> + You can specify a view matcher by using these approaches: + </p> + + <ul> + <li>Calling methods in the + <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html"> + {@code ViewMatchers}</a> class. For example, to find a view by looking for a text string it + displays, you can call a method like this: + <pre> +onView(withText("Sign-in")); +</pre> + +<p>Similarly you can call +<a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html#withId(int)"> +{@code withId()}</a> and providing the resource ID ({@code R.id}) of the view, as shown in the +following example:</p> + +<pre> +onView(withId(R.id.button_signin)); +</pre> + + <p> + Android resource IDs are not guaranteed to be unique. If your test attempts to match to a + resource ID used by more than one view, Espresso throws an +<a href="{@docRoot}reference/android/support/test/espresso/AmbiguousViewMatcherException.html"> + {@code AmbiguousViewMatcherException}</a>. + </p> + </li> + <li>Using the Hamcrest + <a href="http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html" + class="external-link">{@code Matchers}</a> class. You can use the + {@code allOf()} methods to combine multiple matchers, such as + {@code containsString()} and {@code instanceOf()}. This approach allows you to + filter the match results more narrowly, as shown in the following example: +<pre> +onView(allOf(withId(R.id.button_signin), withText("Sign-in"))); +</pre> +<p>You can use the {@code not} keyword to filter for views that don't correspond to the matcher, as +shown in the following example:</p> +<pre> +onView(allOf(withId(R.id.button_signin), not(withText("Sign-out")))); +</pre> +<p>To use these methods in your test, import the {@code org.hamcrest.Matchers} package. To +learn more about Hamcrest matching, see the +<a href="http://hamcrest.org/" class="external-link">Hamcrest site</a>. +</p> + </li> + </ul> + + <p> + To improve the performance of your Espresso tests, specify the minimum matching information + needed to find your target view. For example, if a view is uniquely identifiable by its + descriptive text, you do not need to specify that it is also assignable from the + {@link android.widget.TextView} instance. + </p> + + <h4 id="#locating-adpeterview-view"> + Locating a view in an AdapterView + </h4> + + <p> + In an {@link android.widget.AdapterView} widget, the view is dynamically populated with child + views at runtime. If the target view you want to test is inside an + {@link android.widget.AdapterView} + (such as a {@link android.widget.ListView}, {@link android.widget.GridView}, or + {@link android.widget.Spinner}), the +<a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onView(org.hamcrest.Matcher<android.view.View>)"> + {@code onView()}</a> method might not work because only a + subset of the views may be loaded in the current view hierarchy. + </p> + + <p> + Instead, call the <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> + method to obtain a + <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html"> + {@code DataInteraction}</a> + object to access the target view element. Espresso handles loading the target view element + into the current view hierarchy. Espresso also takes care of scrolling to the target element, + and putting the element into focus. + </p> + + <p class="note"> + <strong>Note</strong>: The + <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> + method does not check if if the item you specified corresponds with a view. Espresso searches + only the current view hierarchy. If no match is found, the method throws a + <a href="{@docRoot}reference/android/support/test/espresso/NoMatchingViewException.html"> + {@code NoMatchingViewException}</a>. + </p> + + <p> + The following code snippet shows how you can use the + <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> + method together + with Hamcrest matching to search for a specific row in a list that contains a given string. + In this example, the {@code LongListActivity} class contains a list of strings exposed + through a {@link android.widget.SimpleAdapter}. + </p> + +<pre> +onData(allOf(is(instanceOf(Map.class)), + hasEntry(equalTo(LongListActivity.ROW_TEXT), is(str)))); +</pre> + + <h3 id="perform-actions"> + Performing Actions + </h3> + + <p> + Call the <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code ViewInteraction.perform()}</a> + or + <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#perform(android.support.test.espresso.ViewAction...)">{@code DataInteraction.perform()}</a> + methods to + simulate user interactions on the UI component. You must pass in one or more + <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> + objects as arguments. Espresso fires each action in sequence according to + the given order, and executes them in the main thread. + </p> + + <p> + The + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html">{@code ViewActions}</a> + class provides a list of helper methods for specifying common actions. + You can use these methods as convenient shortcuts instead of creating and configuring + individual <a href="{@docRoot}reference/android/support/test/espresso/ViewAction.html">{@code ViewAction}</a> + objects. You can specify such actions as: + </p> + + <ul> + <li> + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#click()">{@code ViewActions.click()}</a>: + Clicks on the view. + </li> + + <li> + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#typeText(java.lang.String)">{@code ViewActions.typeText()}</a>: + Clicks on a view and enters a specified string. + </li> + + <li> + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a>: + Scrolls to the view. The + target view must be subclassed from {@link android.widget.ScrollView} + and the value of its + <a href="http://developer.android.com/reference/android/view/View.html#attr_android:visibility">{@code android:visibility}</a> + property must be {@link android.view.View#VISIBLE}. For views that extend + {@link android.widget.AdapterView} (for example, + {@link android.widget.ListView}), + the + <a href="{@docRoot}reference/android/support/test/espresso/Espresso.html#onData(org.hamcrest.Matcher<java.lang.Object>)">{@code onData()}</a> + method takes care of scrolling for you. + </li> + + <li> + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#pressKey(int)">{@code ViewActions.pressKey()}</a>: + Performs a key press using a specified keycode. + </li> + + <li> + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#clearText()">{@code ViewActions.clearText()}</a>: + Clears the text in the target view. + </li> + </ul> + + <p> + If the target view is inside a {@link android.widget.ScrollView}, perform the + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> + action first to display the view in the screen before other proceeding + with other actions. The + <a href="{@docRoot}reference/android/support/test/espresso/action/ViewActions.html#scrollTo()">{@code ViewActions.scrollTo()}</a> + action will have no effect if the view is already displayed. + </p> + + <h3 id="verify-results"> + Verifying Results + </h3> + + <p> + Call the + <a href="{@docRoot}reference/android/support/test/espresso/ViewInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code ViewInteraction.check()}</a> + or + <a href="{@docRoot}reference/android/support/test/espresso/DataInteraction.html#check(android.support.test.espresso.ViewAssertion)">{@code DataInteraction.check()}</a> + method to assert + that the view in the UI matches some expected state. You must pass in a + <a href="{@docRoot}reference/android/support/test/espresso/ViewAssertion.html"> + {@code ViewAssertion}</a> object as the argument. If the assertion fails, Espresso throws + an {@link junit.framework.AssertionFailedError}. + </p> + + <p> + The + <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html">{@code ViewAssertions}</a> + class provides a list of helper methods for specifying common + assertions. The assertions you can use include: + </p> + + <ul> + <li> + <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#doesNotExist()">{@code doesNotExist}</a>: +Asserts that there is no view matching the specified criteria in the current view hierarchy. + </li> + + <li> + <a href="{@docRoot}reference/android/support/test/espresso/assertion/ViewAssertions.html#matches(org.hamcrest.Matcher<? super android.view.View>)">{@code matches}</a>: + Asserts that the specified view exists in the current view hierarchy + and its state matches some given Hamcrest matcher. + </li> + + <li> + <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> + : Asserts that the specified children views for a + parent view exist, and their state matches some given Hamcrest matcher. + </li> + </ul> + + <p> + The following code snippet shows how you might check that the text displayed in the UI has + the same value as the text previously entered in the + {@link android.widget.EditText} field. + </p> +<pre> +public void testChangeText_sameActivity() { + // Type text and then press the button. + ... + + // Check that the text was changed. + onView(withId(R.id.textToBeChanged)) + .check(matches(withText(STRING_TO_BE_TYPED))); +} +</pre> + +<h2 id="run">Run Espresso Tests on a Device or Emulator</h2> + + <p> + To run Espresso tests, you must use the + <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> + class provided in the + <a href="{@docRoot}tools/testing-support-library/index.html"> + Android Testing Support Library</a> as your default test runner. The + <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for + Gradle</a> provides a default directory ({@code src/androidTest/java}) for you to store the + instrumented test classes and test suites that you want to run on a device. The + plug-in compiles the test code in that directory and then executes the test app using + the configured test runner class. + </p> + + <p> + To run Espresso tests in your Gradle project: + </p> + + <ol> + <li>Specify + <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> + as the default test instrumentation runner in + your {@code build.gradle} file: + + <pre> +android { + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } +}</pre> + </li> + <li>Run your tests from the command-line by calling the the {@code connectedCheck} + (or {@code cC}) task: + <pre> +./gradlew cC</pre> + </li> + </ol>
\ No newline at end of file diff --git a/docs/html/training/testing/ui-testing/index.jd b/docs/html/training/testing/ui-testing/index.jd new file mode 100644 index 0000000..605de22 --- /dev/null +++ b/docs/html/training/testing/ui-testing/index.jd @@ -0,0 +1,76 @@ +page.title=Automating User Interface Tests +page.tags=testing + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2> + You should also read + </h2> + + <ul> + <li> + <a href="{@docRoot}/tools/testing-support-library/index.html">Testing Support Library</a> + </li> + </ul> +</div> +</div> + +<p>User interface (UI) testing lets you ensure that your app meets its functional requirements +and achieves a high standard of quality such that it is more likely to be successfully adopted by +users.</p> + +<p>One approach to UI testing is to simply have a human tester perform a set of user operations on +the target app and verify that it is behaving correctly. However, this manual approach can be +time-consuming, tedious, and error-prone. A more efficient approach is to write your UI +tests such that user actions are performed in an automated way. The automated approach allows +you to run your tests quickly and reliably in a repeatable manner.</p> + +<p class="note"><strong>Note: </strong>It is strongly encouraged that you use +<a href="{@docRoot}sdk/installing/studio.html">Android Studio</a> for +building your test apps, because it provides project setup, library inclusion, and packaging +conveniences. This class assumes you are using Android Studio.</p> + +<p>To automate UI tests with Android Studio, you implement your test code in a separate +Android test folder ({@code src/androidTest/java}). The +<a href="{@docRoot}tools/building/plugin-for-gradle.html">Android +Plug-in for Gradle</a> builds a test app based on your test code, then loads the test app on the +same device as the target app. In your test code, you can use UI testing frameworks to +simulate user interactions on the target app, in order to perform testing tasks that cover specific +usage scenarios.</p> + +<p>For testing Android apps, you typically create these types of automated UI tests:</p> + +<ul> +<li><em>UI tests that span a single app:</em> This type of test verifies that the target app behaves +as expected when a user performs a specific action or enters a specific input in its activities. +It allows you to check that the target app returns the correct UI output in response +to user interactions in the app’s activities. UI testing frameworks like Espresso allow you to +programmatically simulate user actions and test complex intra-app user interactions.</li> +<li><em>UI tests that span multiple apps:</em> This type of test verifies the correct behavior of +interactions between different user apps or between user apps and system apps. For example, you +might want to test that your camera app shares images correctly with a 3rd-party social media app, +or with the default Android Photos app. UI testing frameworks that support cross-app interactions, +such as UI Automator, allow you to create tests for such scenarios.</li> +</ul> + +<p>The lessons in this class teach you how to use the tools and APIs in the +<a href="{@docRoot}/tools/testing-support-library/index.html">Android Testing Support Library</a> +to build these types of automated tests. Before you begin building tests using these +APIs, you must install the Android Testing Support Library, as described in +<a href="{@docRoot}/tools/testing-support-library/index.html#setup">Downloading the Android +Testing Support Library</a>.</p> + +<h2>Lessons</h2> +<dl> + <dt><strong><a href="espresso-testing.html"> +Testing UI for a Single App</a></strong></dt> + <dd>Learn how to test UI in a single app by using the Espresso testing framework.</dd> + <dt><strong><a href="uiautomator-testing.html"> +Testing UI for Multiple Apps</a></strong></dt> + <dd>Learn how to test UI in multiple apps by using the UI Automator testing framework</dd> +</dl>
\ No newline at end of file diff --git a/docs/html/training/testing/ui-testing/uiautomator-testing.jd b/docs/html/training/testing/ui-testing/uiautomator-testing.jd new file mode 100644 index 0000000..e314b70 --- /dev/null +++ b/docs/html/training/testing/ui-testing/uiautomator-testing.jd @@ -0,0 +1,520 @@ +page.title=Testing UI for Multiple Apps +page.tags=testing,ui automator +trainingnavtop=true + +@jd:body + +<!-- This is the training bar --> +<div id="tb-wrapper"> +<div id="tb"> + <h2>Dependencies and Prerequisites</h2> + + <ul> + <li>Android 4.3 (API level 18) or higher</li> + <li><a href="{@docRoot}tools/testing-support-library/index.html"> + Android Testing Support Library</a></li> + </ul> + + <h2>This lesson teaches you to</h2> + + <ol> + <li><a href="#setup">Set Up UI Automator</a></li> + <li><a href="#build">Create a UI Automator Test Class</a></li> + <li><a href="#run">Run UI Automator Tests on a Device or Emulator</a></li> + </ol> + + <h2>You should also read</h2> + + <ul> + <li><a href="{@docRoot}reference/android/support/test/package-summary.html"> +UI Automator API Reference</a></li> + </ul> + + <h2>Try it out</h2> + + <ul> + <li><a href="https://github.com/googlesamples/android-testing" +class="external-link">UI Automator Code Samples</a></li> + </ul> +</div> +</div> + +<p>A user interface (UI) test that involves user interactions across multiple apps lets you +verify that your app behaves correctly when the user flow crosses into other apps or into the +system UI. An example of such a user flow is a messaging app that lets the user enter a text +message, launches the Android contact picker so that the users can select recipients to send the +message to, and then returns control to the original app for the user to submit the message.</p> + +<p>This lesson covers how to write such UI tests using the +UI Automator testing framework provided by the +<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. +The UI Automator APIs let you interact with visible elements on a device, regardless of +which {@link android.app.Activity} is in focus. Your test can look up a UI component by using +convenient descriptors such as the text displayed in that component or its content description. UI +Automator tests can run on devices running Android 4.3 (API level 18) or higher.</p> + +<p>The UI Automator testing framework is an instrumentation-based API and works +with the +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> + {@code AndroidJUnitRunner}</a> +test runner. +</p> + +<h2 id="setup">Set Up UI Automator</h2> +<p>Before you begin using UI Automator, you must:</p> + + <ul> + <li> + <strong>Install the Android Testing Support Library</strong>. The UI Automator API is + located under the {@code com.android.support.test.uiautomator} package. These classes allow + you to create tests that use the Espresso testing framework. To learn how to install the + library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> + Testing Support Library Setup</a>. + </li> + + <li> + <strong>Set up your project structure.</strong> In your Gradle project, the source code for + the target app that you want to test is typically placed under the {@code app/src/main} + folder. The source code for instrumentation tests, including + your UI Automator tests, must be placed under the <code>app/src/androidTest</code> folder. + To learn more about setting up your project directory, see + <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. + </li> + + <li> + <strong>Specify your Android testing dependencies</strong>. In order for the + <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to + correctly build and run your UI Automator tests, you must specify the following libraries in + the {@code build.gradle} file of your Android app module: + + <pre> +dependencies { + androidTestCompile 'com.android.support.test:testing-support-lib:0.1' + androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.0.0' +} +</pre> + </li> + </ul> + +<p>To optimize your UI Automator testing, you should first inspect the target app’s UI components +and ensure that they are accessible. These optimization tips are described in the next two +sections.</p> + +<h3 id="inspecting-ui">Inspecting the UI on a device</h3> +<p>Before designing your test, inspect the UI components that are visible on the device. To +ensure that your UI Automator tests can access these components, check that these components +have visible text labels, +<a href="http://developer.android.com/reference/android/view/View.html#attr_android:contentDescription"> +{@code android:contentDescription}</a> +values, or both.</p> + +<p>The {@code uiautomatorviewer} tool provides a convenient visual interface to inspect the layout +hierarchy and view the properties of UI components that are visible on the foreground of the device. +This information lets you create more fine-grained tests using UI Automator. For example, you can +create a UI selector that matches a specific visible property. </p> + +<p>To launch the {@code uiautomatorviewer} tool:</p> + +<ol> + <li>Launch the target app on a physical device.</li> + <li>Connect the device to your development machine.</li> + <li>Open a terminal window and navigate to the {@code <android-sdk>/tools/} directory.</li> + <li>Run the tool with this command: +<pre>$ uiautomatorviewer</pre> + </li> +</ol> + +<p>To view the UI properties for your application:</p> + +<ol> + <li>In the {@code uiautomatorviewer} interface, click the <strong>Device Screenshot</strong> +button.</li> + <li>Hover over the snapshot in the left-hand panel to see the UI components identified by the +{@code uiautomatorviewertool}. The properties are listed in the lower right-hand panel and the +layout hierarchy in the upper right-hand panel.</li> + <li>Optionally, click on the <strong>Toggle NAF Nodes</strong> button to see UI components that +are non-accessible to UI Automator. Only limited information may be available for these +components.</li> +</ol> + +<p>To learn about the common types of UI components provided by Android, see +<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>.</p> + +<h3>Ensuring your Activity is accessible</h3> +<p>The UI Automator test framework depends on the accessibility features of the Android framework +to look up individual UI elements. As a developer, you should implement these minimum +optimizations in your {@link android.app.Activity} to support UI Automator:</p> + +<ul> +<li>Use the +<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"> + {@code android:contentDescription}</a> +attribute to label the {@link android.widget.ImageButton}, {@link android.widget.ImageView}, +{@link android.widget.CheckBox} and other user interface controls.</li> +<li>Provide an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> +attribute instead of a content description for {@link android.widget.EditText} fields.</li> +<li>Associate an <a href="http://developer.android.com/reference/android/widget/TextView.html#attr_android:hint"> + {@code android:hint}</a> +attribute with any graphical icons used by controls that provide feedback to the user +(for example, status or state information).</li> +<li>Use the {@code uiautomatorviewer} tool to ensure that the UI component is accessible to the +testing framework. You can also test the application by turning on accessibility services like +TalkBack and Explore by Touch, and try using your application using only directional controls.</li> +</ul> + +<p>Generally, app developers get accessibility support for free, courtesy of +the {@link android.view.View} and {@link android.view.ViewGroup} +classes. However, some apps use custom view elements to provide a richer user experience. Such +custom elements won't get the accessibility support that is provided by the standard Android UI +elements. If this applies to your app, make sure that it exposes the custom-drawn UI element to +Android accessibility services by implementing the +{@link android.view.accessibility.AccessibilityNodeProvider} class.</p> + +<p>If the custom view element contains a single element, make it accessible by +<a href="{@docRoot}guide/topics/ui/accessibility/apps.html#accessibility-methods">implementing +accessibility API methods</a>. +If the custom view contains elements that are not views themselves (for example, a +{@link android.webkit.WebView}, make sure it implements the +{@link android.view.accessibility.AccessibilityNodeProvider} class. For container views that +extend an existing container implementation +(for example, a {@link android.widget.ListView}), implementing +{@link android.view.accessibility.AccessibilityNodeProvider} is not necessary.</p> + +<p>For more information about implementing and testing accessibility, see +<a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>.</p> + +<h2 id="build">Create a UI Automator Test Class</h2> + +<p>To build a UI Automator test, create a class that extends +{@link android.test.InstrumentationTestCase}. Implement the following programming model in your +UI Automator test class:</p> + +<ol> +<li>Get a + <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> + object to access the device you want to test, by calling the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#getInstance(android.app.Instrumentation)"> +{@code getInstance()}</a> +method and passing it an {@link android.app.Instrumentation} object as the argument.</li> +<li>Get a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +object to access a UI component that is displayed on the device + (for example, the current view in the foreground), by calling the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)"> + {@code findObject()}</a> +method. +</li> +<li>Simulate a specific user interaction to perform on that UI component, by calling a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +method; for example, call +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#performMultiPointerGesture(android.view.MotionEvent.PointerCoords[]...)"> + {@code performMultiPointerGesture()}</a> +to simulate a multi-touch gesture, and +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)">{@code setText()}</a> +to edit a text field. You can call on the APIs in steps 2 and 3 repeatedly as necessary to test +more complex user interactions that involve multiple UI components or sequences of user actions.</li> +<li>Check that the UI reflects the expected state or behavior, after these user interactions are + performed. </li> +</ol> + +<p>These steps are covered in more detail in the sections below.</p> + +<h3 id="accessing-ui-components">Accessing UI Components</h3> +<p>The +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> + object is the primary way you access and manipulate the state of the +device. In your tests, you can call +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> +methods to check for the state of various properties, such as current orientation or display size. +Your test can use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> +object to perform device-level actions, such as forcing the device into a specific rotation, +pressing D-pad hardware buttons, and pressing the Home and Menu buttons.</p> + +<p>It’s good practice to start your test from the Home screen of the device. From the Home screen +(or some other starting location you’ve chosen in the device), you can call the methods provided by +the UI Automator API to select and interact with specific UI elements. </p> + +<p>The following code snippet shows how your test might get an instance of +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> +and simulate a Home button press:</p> + +<pre> +import android.test.InstrumentationTestCase; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.By; + +public class CalculatorUiTest extends InstrumentationTestCase { + + private UiDevice mDevice; + + public void setUp() { + // Initialize UiDevice instance + mDevice = UiDevice.getInstance(getInstrumentation()); + + // Start from the home screen + mDevice.pressHome(); + mDevice.wait(Until.hasObject(By.pkg(getHomeScreenPackage()).depth(0)), + } +} +</pre> + +<p>Use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">{@code findObject()}</a> +method to retrieve a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +which represents a view that matches a given selector criteria. You can reuse the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +instances that you have created in other parts of your app testing, as needed. Note that the +UI Automator test framework searches the current display for a match every time your test uses a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +instance to click on a UI element or query a property.</p> + +<p>The following snippet shows how your test might construct +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +instances that represent a Cancel button and a OK button in an app.</p> + +<pre> +UiObject cancelButton = mDevice.findObject(new UiSelector() + .text("Cancel")) + .className("android.widget.Button")); +UiObject okButton = mDevice.findObject(new UiSelector() + .text("OK")) + .className("android.widget.Button")); + +// Simulate a user-click on the OK button, if found. +if(okButton.exists() && okButton.isEnabled()) { + okButton.click(); +} +</pre> + +<h4 id="specifying-selector">Specifying a selector</h4> +<p>If you want to access a specific UI component in an app, use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> +class. This class represents a query for specific elements in the +currently displayed UI. </p> + +<p>If more than one matching element is found, the first matching element in the layout hierarchy +is returned as the target +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>. +When constructing a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>, +you can chain together multiple properties to refine your search. If no matching UI element is +found, a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObjectNotFoundException.html"> +{@code UiAutomatorObjectNotFoundException}</a> is thrown. </p> + +<p>You can use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html#childSelector(android.support.test.uiautomator.UiSelector)">{@code childSelector()}</a> +method to nest multiple +<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> +instances. For example, the following code example shows how your test might specify a search to +find the first {@link android.widget.ListView} in the currently displayed UI, then search within that +{@link android.widget.ListView} to find a UI element with the text property Apps.</p> + +<pre> +UiObject appItem = new UiObject(new UiSelector() + .className("android.widget.ListView") + .instance(1) + .childSelector(new UiSelector() + .text("Apps"))); +</pre> + +<p>As a best practice, when specifying a selector, you should use a Resource ID (if one is assigned +to a UI element) instead of a text element or content-descriptor. Not all elements have a text +element (for example, icons in a toolbar). Text selectors are brittle and can lead to test failures +if there are minor changes to the UI. They may also not scale across different languages; your text +selectors may not match translated strings.</p> + +<p>It can be useful to specify the object state in your selector criteria. For example, if you want +to select a list of all checked elements so that you can uncheck them, call the +<a href="{@docRoot}reference/android/support/test/uiautomator/By.html#checked(boolean)"> +{@code checked()}</a> +method with the argument set to {@code true}.</p> + +<h3 id="performing-actions">Performing Actions</h3> + +<p>Once your test has obtained a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +object, you can call the methods in the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> +class to perform user interactions on the UI component represented by that +object. You can specify such actions as:</p> + +<ul> +<li> +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#click()"> + {@code click()}</a> +: Clicks the center of the visible bounds of the UI element.</li> +<li> +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#dragTo(int, int, int)"> + {@code dragTo()}</a> +: Drags this object to arbitrary coordinates.</li> +<li> +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)"> + {@code setText()}</a> +: Sets the text in an editable field, after clearing the field's content. +Conversely, the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#clearTextField()"> + {@code clearTextField()}</a> +method clears the existing text in an editable field.</li> +<li> +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeUp(int)"> + {@code swipeUp()}</a> +: Performs the swipe up action on the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>. +Similarly, the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeDown(int)"> + {@code swipeDown()}</a>, +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeLeft(int)"> + {@code swipeLeft()}</a>, and +<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeRight(int)"> + {@code swipeRight()}</a> +methods perform corresponding actions.</li> +</ul> + +<p>The UI Automator testing framework allows you to send an +{@link android.content.Intent} +or launch an {@link android.app.Activity} +without using shell commands, by getting a +{@link android.content.Context} +object through +{@link android.app.Instrumentation#getContext() getContext()}.</p> + +<p>The following snippet shows how your test can use an +{@link android.content.Intent} to launch the app under test. This approach is useful when you are +only interested in testing the calculator app, and don't care about the launcher.</p> + +<pre> +public void setUp() { + ... + + // Launch a simple calculator app + Context context = getInstrumentation().getContext(); + Intent intent = context.getPackageManager() + .getLaunchIntentForPackage(CALC_PACKAGE); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + // Clear out any previous instances + context.startActivity(intent); + mDevice.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT); +} +</pre> + +<h4 id="actions-on-collections">Performing actions on collections</h4> + +<p>Use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> + {@code UiCollection}</a> +class if you want to simulate user interactions on a +collection of items (for example, songs in a music album or a list of emails in an Inbox). To +create a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> + {@code UiCollection}</a> +object, specify a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> +that searches for a +UI container or a wrapper of other child UI elements, such as a layout view that contains child UI +elements.</p> + +<p>The following code snippet shows how your test might construct a +<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> + {@code UiCollection}</a> +to represent a video album that is displayed within a {@link android.widget.FrameLayout}:</p> + +<pre> +UiCollection videos = new UiCollection(new UiSelector() + .className("android.widget.FrameLayout")); + +// Retrieve the number of videos in this collection: +int count = videos.getChildCount(new UiSelector() + .className("android.widget.LinearLayout")); + +// Find a specific video and simulate a user-click on it +UiObject video = videos.getChildByText(new UiSelector() + .className("android.widget.LinearLayout"), "Cute Baby Laughing"); +video.click(); + +// Simulate selecting a checkbox that is associated with the video +UiObject checkBox = video.getChild(new UiSelector() + .className("android.widget.Checkbox")); +if(!checkBox.isSelected()) checkbox.click(); +</pre> + +<h4 id="actions-on-scrollable-views">Performing actions on scrollable views</h4> +<p>Use the +<a href="{@docRoot}reference/android/support/test/uiautomator/UiScrollable.html"> + {@code UiScrollable}</a> +class to simulate vertical or horizontal scrolling across a display. This technique is helpful when +a UI element is positioned off-screen and you need to scroll to bring it into view.</p> + +<p>The following code snippet shows how to simulate scrolling down the Settings menu and clicking +on an About tablet option:</p> + +<pre> +UiScrollable settingsItem = new UiScrollable(new UiSelector() + .className("android.widget.ListView")); +UiObject about = settingsItem.getChildByText(new UiSelector() + .className("android.widget.LinearLayout"), "About tablet"); +about.click(); +</pre> + +<h3 id="verifying-results">Verifying Results</h3> +<p>The {@link android.test.InstrumentationTestCase} extends {@link junit.framework.TestCase}, so +you can use standard JUnit <a href="http://junit.org/javadoc/latest/org/junit/Assert.html" +class="external-link">{@code Assert}</a> methods to test +that UI components in the app return the expected results. </p> + +<p>The following snippet shows how your test can locate several buttons in a calculator app, click +on them in order, then verify that the correct result is displayed.</p> + +<pre> +private static final String CALC_PACKAGE = "com.myexample.calc"; + +public void testTwoPlusThreeEqualsFive() { + // Enter an equation: 2 + 3 = ? + mDevice.findObject(new UiSelector() + .packageName(CALC_PACKAGE).resourceId("two")).click(); + mDevice.findObject(new UiSelector() + .packageName(CALC_PACKAGE).resourceId("plus")).click(); + mDevice.findObject(new UiSelector() + .packageName(CALC_PACKAGE).resourceId("three")).click(); + mDevice.findObject(new UiSelector() + .packageName(CALC_PACKAGE).resourceId("equals")).click(); + + // Verify the result = 5 + UiObject result = mDevice.findObject(By.res(CALC_PACKAGE, "result")); + assertEquals("5", result.getText()); +} +</pre> + +<h2 id="run">Run UI Automator Tests on a Device or Emulator</h2> +<p>UI Automator tests are based on the {@link android.app.Instrumentation} class. The +<a href="https://developer.android.com/tools/building/plugin-for-gradle.html"> + Android Plug-in for Gradle</a> +provides a default directory ({@code src/androidTest/java}) for you to store the instrumented test +classes and test suites that you want to run on a device. The plug-in compiles the test +code in that directory and then executes the test app using a test runner class. You are +strongly encouraged to use the +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> +class provided in the +<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> +as your default test runner. </p> + +<p>To run UI Automator tests in your Gradle project:</p> + +<ol> +<li>Specify +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> +as the default test instrumentation runner in your {@code build.gradle} file: +<pre> +android { + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } +}</pre> +</li> +<li>Run your tests from the command-line by calling the {@code connectedCheck} + (or {@code cC}) task: +<pre>./gradlew cC</pre> +</li> +</ol>
\ No newline at end of file diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 2873b5b..3ee7ab7 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1840,6 +1840,24 @@ results." </ul> </li> </ul> + <ul> + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/ui-testing/index.html" + description="How to automate your user interface tests for Android apps."> + Automating UI Tests + </a></div> + <ul> + <li><a href="<?cs var:toroot ?>training/testing/ui-testing/espresso-testing.html"> + <span class="en">Testing UI for a Single App</span> + </a> + </li> + <li><a href="<?cs var:toroot ?>training/testing/ui-testing/uiautomator-testing.html"> + <span class="en">Testing UI for Multiple Apps</span> + </a> + </li> + </ul> + </li> + </ul> </li> <!-- End best Testing --> |