Quddus Chong | 7639e73 | 2015-03-05 13:16:24 -0800 | [diff] [blame] | 1 | page.title=Testing UI for Multiple Apps |
| 2 | page.tags=testing,ui automator |
| 3 | trainingnavtop=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 4.3 (API level 18) or higher</li> |
| 14 | <li><a href="{@docRoot}tools/testing-support-library/index.html"> |
| 15 | Android Testing Support Library</a></li> |
| 16 | </ul> |
| 17 | |
| 18 | <h2>This lesson teaches you to</h2> |
| 19 | |
| 20 | <ol> |
| 21 | <li><a href="#setup">Set Up UI Automator</a></li> |
| 22 | <li><a href="#build">Create a UI Automator Test Class</a></li> |
| 23 | <li><a href="#run">Run UI Automator Tests on a Device or Emulator</a></li> |
| 24 | </ol> |
| 25 | |
| 26 | <h2>You should also read</h2> |
| 27 | |
| 28 | <ul> |
| 29 | <li><a href="{@docRoot}reference/android/support/test/package-summary.html"> |
| 30 | UI Automator API Reference</a></li> |
| 31 | </ul> |
| 32 | |
| 33 | <h2>Try it out</h2> |
| 34 | |
| 35 | <ul> |
| 36 | <li><a href="https://github.com/googlesamples/android-testing" |
| 37 | class="external-link">UI Automator Code Samples</a></li> |
| 38 | </ul> |
| 39 | </div> |
| 40 | </div> |
| 41 | |
| 42 | <p>A user interface (UI) test that involves user interactions across multiple apps lets you |
| 43 | verify that your app behaves correctly when the user flow crosses into other apps or into the |
| 44 | system UI. An example of such a user flow is a messaging app that lets the user enter a text |
| 45 | message, launches the Android contact picker so that the users can select recipients to send the |
| 46 | message to, and then returns control to the original app for the user to submit the message.</p> |
| 47 | |
| 48 | <p>This lesson covers how to write such UI tests using the |
| 49 | UI Automator testing framework provided by the |
| 50 | <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. |
| 51 | The UI Automator APIs let you interact with visible elements on a device, regardless of |
| 52 | which {@link android.app.Activity} is in focus. Your test can look up a UI component by using |
| 53 | convenient descriptors such as the text displayed in that component or its content description. UI |
| 54 | Automator tests can run on devices running Android 4.3 (API level 18) or higher.</p> |
| 55 | |
| 56 | <p>The UI Automator testing framework is an instrumentation-based API and works |
| 57 | with the |
| 58 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> |
| 59 | {@code AndroidJUnitRunner}</a> |
| 60 | test runner. |
| 61 | </p> |
| 62 | |
| 63 | <h2 id="setup">Set Up UI Automator</h2> |
| 64 | <p>Before you begin using UI Automator, you must:</p> |
| 65 | |
| 66 | <ul> |
| 67 | <li> |
| 68 | <strong>Install the Android Testing Support Library</strong>. The UI Automator API is |
| 69 | located under the {@code com.android.support.test.uiautomator} package. These classes allow |
| 70 | you to create tests that use the Espresso testing framework. To learn how to install the |
| 71 | library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> |
| 72 | Testing Support Library Setup</a>. |
| 73 | </li> |
| 74 | |
| 75 | <li> |
| 76 | <strong>Set up your project structure.</strong> In your Gradle project, the source code for |
| 77 | the target app that you want to test is typically placed under the {@code app/src/main} |
| 78 | folder. The source code for instrumentation tests, including |
| 79 | your UI Automator tests, must be placed under the <code>app/src/androidTest</code> folder. |
| 80 | To learn more about setting up your project directory, see |
| 81 | <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. |
| 82 | </li> |
| 83 | |
| 84 | <li> |
| 85 | <strong>Specify your Android testing dependencies</strong>. In order for the |
| 86 | <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to |
| 87 | correctly build and run your UI Automator tests, you must specify the following libraries in |
| 88 | the {@code build.gradle} file of your Android app module: |
| 89 | |
| 90 | <pre> |
| 91 | dependencies { |
| 92 | androidTestCompile 'com.android.support.test:testing-support-lib:0.1' |
| 93 | androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.0.0' |
| 94 | } |
| 95 | </pre> |
| 96 | </li> |
| 97 | </ul> |
| 98 | |
| 99 | <p>To optimize your UI Automator testing, you should first inspect the target app’s UI components |
| 100 | and ensure that they are accessible. These optimization tips are described in the next two |
| 101 | sections.</p> |
| 102 | |
| 103 | <h3 id="inspecting-ui">Inspecting the UI on a device</h3> |
| 104 | <p>Before designing your test, inspect the UI components that are visible on the device. To |
| 105 | ensure that your UI Automator tests can access these components, check that these components |
| 106 | have visible text labels, |
| 107 | <a href="http://developer.android.com/reference/android/view/View.html#attr_android:contentDescription"> |
| 108 | {@code android:contentDescription}</a> |
| 109 | values, or both.</p> |
| 110 | |
| 111 | <p>The {@code uiautomatorviewer} tool provides a convenient visual interface to inspect the layout |
| 112 | hierarchy and view the properties of UI components that are visible on the foreground of the device. |
| 113 | This information lets you create more fine-grained tests using UI Automator. For example, you can |
| 114 | create a UI selector that matches a specific visible property. </p> |
| 115 | |
| 116 | <p>To launch the {@code uiautomatorviewer} tool:</p> |
| 117 | |
| 118 | <ol> |
| 119 | <li>Launch the target app on a physical device.</li> |
| 120 | <li>Connect the device to your development machine.</li> |
| 121 | <li>Open a terminal window and navigate to the {@code <android-sdk>/tools/} directory.</li> |
| 122 | <li>Run the tool with this command: |
| 123 | <pre>$ uiautomatorviewer</pre> |
| 124 | </li> |
| 125 | </ol> |
| 126 | |
| 127 | <p>To view the UI properties for your application:</p> |
| 128 | |
| 129 | <ol> |
| 130 | <li>In the {@code uiautomatorviewer} interface, click the <strong>Device Screenshot</strong> |
| 131 | button.</li> |
| 132 | <li>Hover over the snapshot in the left-hand panel to see the UI components identified by the |
| 133 | {@code uiautomatorviewertool}. The properties are listed in the lower right-hand panel and the |
| 134 | layout hierarchy in the upper right-hand panel.</li> |
| 135 | <li>Optionally, click on the <strong>Toggle NAF Nodes</strong> button to see UI components that |
| 136 | are non-accessible to UI Automator. Only limited information may be available for these |
| 137 | components.</li> |
| 138 | </ol> |
| 139 | |
| 140 | <p>To learn about the common types of UI components provided by Android, see |
| 141 | <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>.</p> |
| 142 | |
| 143 | <h3>Ensuring your Activity is accessible</h3> |
| 144 | <p>The UI Automator test framework depends on the accessibility features of the Android framework |
| 145 | to look up individual UI elements. As a developer, you should implement these minimum |
| 146 | optimizations in your {@link android.app.Activity} to support UI Automator:</p> |
| 147 | |
| 148 | <ul> |
| 149 | <li>Use the |
| 150 | <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"> |
| 151 | {@code android:contentDescription}</a> |
| 152 | attribute to label the {@link android.widget.ImageButton}, {@link android.widget.ImageView}, |
| 153 | {@link android.widget.CheckBox} and other user interface controls.</li> |
| 154 | <li>Provide an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> |
| 155 | attribute instead of a content description for {@link android.widget.EditText} fields.</li> |
| 156 | <li>Associate an <a href="http://developer.android.com/reference/android/widget/TextView.html#attr_android:hint"> |
| 157 | {@code android:hint}</a> |
| 158 | attribute with any graphical icons used by controls that provide feedback to the user |
| 159 | (for example, status or state information).</li> |
| 160 | <li>Use the {@code uiautomatorviewer} tool to ensure that the UI component is accessible to the |
| 161 | testing framework. You can also test the application by turning on accessibility services like |
| 162 | TalkBack and Explore by Touch, and try using your application using only directional controls.</li> |
| 163 | </ul> |
| 164 | |
| 165 | <p>Generally, app developers get accessibility support for free, courtesy of |
| 166 | the {@link android.view.View} and {@link android.view.ViewGroup} |
| 167 | classes. However, some apps use custom view elements to provide a richer user experience. Such |
| 168 | custom elements won't get the accessibility support that is provided by the standard Android UI |
| 169 | elements. If this applies to your app, make sure that it exposes the custom-drawn UI element to |
| 170 | Android accessibility services by implementing the |
| 171 | {@link android.view.accessibility.AccessibilityNodeProvider} class.</p> |
| 172 | |
| 173 | <p>If the custom view element contains a single element, make it accessible by |
| 174 | <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#accessibility-methods">implementing |
| 175 | accessibility API methods</a>. |
| 176 | If the custom view contains elements that are not views themselves (for example, a |
| 177 | {@link android.webkit.WebView}, make sure it implements the |
| 178 | {@link android.view.accessibility.AccessibilityNodeProvider} class. For container views that |
| 179 | extend an existing container implementation |
| 180 | (for example, a {@link android.widget.ListView}), implementing |
| 181 | {@link android.view.accessibility.AccessibilityNodeProvider} is not necessary.</p> |
| 182 | |
| 183 | <p>For more information about implementing and testing accessibility, see |
| 184 | <a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>.</p> |
| 185 | |
| 186 | <h2 id="build">Create a UI Automator Test Class</h2> |
| 187 | |
| 188 | <p>To build a UI Automator test, create a class that extends |
| 189 | {@link android.test.InstrumentationTestCase}. Implement the following programming model in your |
| 190 | UI Automator test class:</p> |
| 191 | |
| 192 | <ol> |
| 193 | <li>Get a |
| 194 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> |
| 195 | object to access the device you want to test, by calling the |
| 196 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#getInstance(android.app.Instrumentation)"> |
| 197 | {@code getInstance()}</a> |
| 198 | method and passing it an {@link android.app.Instrumentation} object as the argument.</li> |
| 199 | <li>Get a |
| 200 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 201 | object to access a UI component that is displayed on the device |
| 202 | (for example, the current view in the foreground), by calling the |
| 203 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)"> |
| 204 | {@code findObject()}</a> |
| 205 | method. |
| 206 | </li> |
| 207 | <li>Simulate a specific user interaction to perform on that UI component, by calling a |
| 208 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 209 | method; for example, call |
| 210 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#performMultiPointerGesture(android.view.MotionEvent.PointerCoords[]...)"> |
| 211 | {@code performMultiPointerGesture()}</a> |
| 212 | to simulate a multi-touch gesture, and |
| 213 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)">{@code setText()}</a> |
| 214 | to edit a text field. You can call on the APIs in steps 2 and 3 repeatedly as necessary to test |
| 215 | more complex user interactions that involve multiple UI components or sequences of user actions.</li> |
| 216 | <li>Check that the UI reflects the expected state or behavior, after these user interactions are |
| 217 | performed. </li> |
| 218 | </ol> |
| 219 | |
| 220 | <p>These steps are covered in more detail in the sections below.</p> |
| 221 | |
| 222 | <h3 id="accessing-ui-components">Accessing UI Components</h3> |
| 223 | <p>The |
| 224 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> |
| 225 | object is the primary way you access and manipulate the state of the |
| 226 | device. In your tests, you can call |
| 227 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> |
| 228 | methods to check for the state of various properties, such as current orientation or display size. |
| 229 | Your test can use the |
| 230 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> |
| 231 | object to perform device-level actions, such as forcing the device into a specific rotation, |
| 232 | pressing D-pad hardware buttons, and pressing the Home and Menu buttons.</p> |
| 233 | |
| 234 | <p>It’s good practice to start your test from the Home screen of the device. From the Home screen |
| 235 | (or some other starting location you’ve chosen in the device), you can call the methods provided by |
| 236 | the UI Automator API to select and interact with specific UI elements. </p> |
| 237 | |
| 238 | <p>The following code snippet shows how your test might get an instance of |
| 239 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a> |
| 240 | and simulate a Home button press:</p> |
| 241 | |
| 242 | <pre> |
| 243 | import android.test.InstrumentationTestCase; |
| 244 | import android.support.test.uiautomator.UiDevice; |
| 245 | import android.support.test.uiautomator.By; |
| 246 | |
| 247 | public class CalculatorUiTest extends InstrumentationTestCase { |
| 248 | |
| 249 | private UiDevice mDevice; |
| 250 | |
| 251 | public void setUp() { |
| 252 | // Initialize UiDevice instance |
| 253 | mDevice = UiDevice.getInstance(getInstrumentation()); |
| 254 | |
| 255 | // Start from the home screen |
| 256 | mDevice.pressHome(); |
| 257 | mDevice.wait(Until.hasObject(By.pkg(getHomeScreenPackage()).depth(0)), |
| 258 | } |
| 259 | } |
| 260 | </pre> |
| 261 | |
| 262 | <p>Use the |
| 263 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">{@code findObject()}</a> |
| 264 | method to retrieve a |
| 265 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 266 | which represents a view that matches a given selector criteria. You can reuse the |
| 267 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 268 | instances that you have created in other parts of your app testing, as needed. Note that the |
| 269 | UI Automator test framework searches the current display for a match every time your test uses a |
| 270 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 271 | instance to click on a UI element or query a property.</p> |
| 272 | |
| 273 | <p>The following snippet shows how your test might construct |
| 274 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 275 | instances that represent a Cancel button and a OK button in an app.</p> |
| 276 | |
| 277 | <pre> |
| 278 | UiObject cancelButton = mDevice.findObject(new UiSelector() |
| 279 | .text("Cancel")) |
| 280 | .className("android.widget.Button")); |
| 281 | UiObject okButton = mDevice.findObject(new UiSelector() |
| 282 | .text("OK")) |
| 283 | .className("android.widget.Button")); |
| 284 | |
| 285 | // Simulate a user-click on the OK button, if found. |
| 286 | if(okButton.exists() && okButton.isEnabled()) { |
| 287 | okButton.click(); |
| 288 | } |
| 289 | </pre> |
| 290 | |
| 291 | <h4 id="specifying-selector">Specifying a selector</h4> |
| 292 | <p>If you want to access a specific UI component in an app, use the |
| 293 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> |
| 294 | class. This class represents a query for specific elements in the |
| 295 | currently displayed UI. </p> |
| 296 | |
| 297 | <p>If more than one matching element is found, the first matching element in the layout hierarchy |
| 298 | is returned as the target |
| 299 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>. |
| 300 | When constructing a |
| 301 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>, |
| 302 | you can chain together multiple properties to refine your search. If no matching UI element is |
| 303 | found, a |
| 304 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObjectNotFoundException.html"> |
| 305 | {@code UiAutomatorObjectNotFoundException}</a> is thrown. </p> |
| 306 | |
| 307 | <p>You can use the |
| 308 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html#childSelector(android.support.test.uiautomator.UiSelector)">{@code childSelector()}</a> |
| 309 | method to nest multiple |
| 310 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> |
| 311 | instances. For example, the following code example shows how your test might specify a search to |
| 312 | find the first {@link android.widget.ListView} in the currently displayed UI, then search within that |
| 313 | {@link android.widget.ListView} to find a UI element with the text property Apps.</p> |
| 314 | |
| 315 | <pre> |
| 316 | UiObject appItem = new UiObject(new UiSelector() |
| 317 | .className("android.widget.ListView") |
| 318 | .instance(1) |
| 319 | .childSelector(new UiSelector() |
| 320 | .text("Apps"))); |
| 321 | </pre> |
| 322 | |
| 323 | <p>As a best practice, when specifying a selector, you should use a Resource ID (if one is assigned |
| 324 | to a UI element) instead of a text element or content-descriptor. Not all elements have a text |
| 325 | element (for example, icons in a toolbar). Text selectors are brittle and can lead to test failures |
| 326 | if there are minor changes to the UI. They may also not scale across different languages; your text |
| 327 | selectors may not match translated strings.</p> |
| 328 | |
| 329 | <p>It can be useful to specify the object state in your selector criteria. For example, if you want |
| 330 | to select a list of all checked elements so that you can uncheck them, call the |
| 331 | <a href="{@docRoot}reference/android/support/test/uiautomator/By.html#checked(boolean)"> |
| 332 | {@code checked()}</a> |
| 333 | method with the argument set to {@code true}.</p> |
| 334 | |
| 335 | <h3 id="performing-actions">Performing Actions</h3> |
| 336 | |
| 337 | <p>Once your test has obtained a |
| 338 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 339 | object, you can call the methods in the |
| 340 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a> |
| 341 | class to perform user interactions on the UI component represented by that |
| 342 | object. You can specify such actions as:</p> |
| 343 | |
| 344 | <ul> |
| 345 | <li> |
| 346 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#click()"> |
| 347 | {@code click()}</a> |
| 348 | : Clicks the center of the visible bounds of the UI element.</li> |
| 349 | <li> |
| 350 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#dragTo(int, int, int)"> |
| 351 | {@code dragTo()}</a> |
| 352 | : Drags this object to arbitrary coordinates.</li> |
| 353 | <li> |
| 354 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)"> |
| 355 | {@code setText()}</a> |
| 356 | : Sets the text in an editable field, after clearing the field's content. |
| 357 | Conversely, the |
| 358 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#clearTextField()"> |
| 359 | {@code clearTextField()}</a> |
| 360 | method clears the existing text in an editable field.</li> |
| 361 | <li> |
| 362 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeUp(int)"> |
| 363 | {@code swipeUp()}</a> |
| 364 | : Performs the swipe up action on the |
| 365 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>. |
| 366 | Similarly, the |
| 367 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeDown(int)"> |
| 368 | {@code swipeDown()}</a>, |
| 369 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeLeft(int)"> |
| 370 | {@code swipeLeft()}</a>, and |
| 371 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeRight(int)"> |
| 372 | {@code swipeRight()}</a> |
| 373 | methods perform corresponding actions.</li> |
| 374 | </ul> |
| 375 | |
| 376 | <p>The UI Automator testing framework allows you to send an |
| 377 | {@link android.content.Intent} |
| 378 | or launch an {@link android.app.Activity} |
| 379 | without using shell commands, by getting a |
| 380 | {@link android.content.Context} |
| 381 | object through |
| 382 | {@link android.app.Instrumentation#getContext() getContext()}.</p> |
| 383 | |
| 384 | <p>The following snippet shows how your test can use an |
| 385 | {@link android.content.Intent} to launch the app under test. This approach is useful when you are |
| 386 | only interested in testing the calculator app, and don't care about the launcher.</p> |
| 387 | |
| 388 | <pre> |
| 389 | public void setUp() { |
| 390 | ... |
| 391 | |
| 392 | // Launch a simple calculator app |
| 393 | Context context = getInstrumentation().getContext(); |
| 394 | Intent intent = context.getPackageManager() |
| 395 | .getLaunchIntentForPackage(CALC_PACKAGE); |
| 396 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| 397 | // Clear out any previous instances |
| 398 | context.startActivity(intent); |
| 399 | mDevice.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT); |
| 400 | } |
| 401 | </pre> |
| 402 | |
| 403 | <h4 id="actions-on-collections">Performing actions on collections</h4> |
| 404 | |
| 405 | <p>Use the |
| 406 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> |
| 407 | {@code UiCollection}</a> |
| 408 | class if you want to simulate user interactions on a |
| 409 | collection of items (for example, songs in a music album or a list of emails in an Inbox). To |
| 410 | create a |
| 411 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> |
| 412 | {@code UiCollection}</a> |
| 413 | object, specify a |
| 414 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a> |
| 415 | that searches for a |
| 416 | UI container or a wrapper of other child UI elements, such as a layout view that contains child UI |
| 417 | elements.</p> |
| 418 | |
| 419 | <p>The following code snippet shows how your test might construct a |
| 420 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html"> |
| 421 | {@code UiCollection}</a> |
| 422 | to represent a video album that is displayed within a {@link android.widget.FrameLayout}:</p> |
| 423 | |
| 424 | <pre> |
| 425 | UiCollection videos = new UiCollection(new UiSelector() |
| 426 | .className("android.widget.FrameLayout")); |
| 427 | |
| 428 | // Retrieve the number of videos in this collection: |
| 429 | int count = videos.getChildCount(new UiSelector() |
| 430 | .className("android.widget.LinearLayout")); |
| 431 | |
| 432 | // Find a specific video and simulate a user-click on it |
| 433 | UiObject video = videos.getChildByText(new UiSelector() |
| 434 | .className("android.widget.LinearLayout"), "Cute Baby Laughing"); |
| 435 | video.click(); |
| 436 | |
| 437 | // Simulate selecting a checkbox that is associated with the video |
| 438 | UiObject checkBox = video.getChild(new UiSelector() |
| 439 | .className("android.widget.Checkbox")); |
| 440 | if(!checkBox.isSelected()) checkbox.click(); |
| 441 | </pre> |
| 442 | |
| 443 | <h4 id="actions-on-scrollable-views">Performing actions on scrollable views</h4> |
| 444 | <p>Use the |
| 445 | <a href="{@docRoot}reference/android/support/test/uiautomator/UiScrollable.html"> |
| 446 | {@code UiScrollable}</a> |
| 447 | class to simulate vertical or horizontal scrolling across a display. This technique is helpful when |
| 448 | a UI element is positioned off-screen and you need to scroll to bring it into view.</p> |
| 449 | |
| 450 | <p>The following code snippet shows how to simulate scrolling down the Settings menu and clicking |
| 451 | on an About tablet option:</p> |
| 452 | |
| 453 | <pre> |
| 454 | UiScrollable settingsItem = new UiScrollable(new UiSelector() |
| 455 | .className("android.widget.ListView")); |
| 456 | UiObject about = settingsItem.getChildByText(new UiSelector() |
| 457 | .className("android.widget.LinearLayout"), "About tablet"); |
| 458 | about.click(); |
| 459 | </pre> |
| 460 | |
| 461 | <h3 id="verifying-results">Verifying Results</h3> |
| 462 | <p>The {@link android.test.InstrumentationTestCase} extends {@link junit.framework.TestCase}, so |
| 463 | you can use standard JUnit <a href="http://junit.org/javadoc/latest/org/junit/Assert.html" |
| 464 | class="external-link">{@code Assert}</a> methods to test |
| 465 | that UI components in the app return the expected results. </p> |
| 466 | |
| 467 | <p>The following snippet shows how your test can locate several buttons in a calculator app, click |
| 468 | on them in order, then verify that the correct result is displayed.</p> |
| 469 | |
| 470 | <pre> |
| 471 | private static final String CALC_PACKAGE = "com.myexample.calc"; |
| 472 | |
| 473 | public void testTwoPlusThreeEqualsFive() { |
| 474 | // Enter an equation: 2 + 3 = ? |
| 475 | mDevice.findObject(new UiSelector() |
| 476 | .packageName(CALC_PACKAGE).resourceId("two")).click(); |
| 477 | mDevice.findObject(new UiSelector() |
| 478 | .packageName(CALC_PACKAGE).resourceId("plus")).click(); |
| 479 | mDevice.findObject(new UiSelector() |
| 480 | .packageName(CALC_PACKAGE).resourceId("three")).click(); |
| 481 | mDevice.findObject(new UiSelector() |
| 482 | .packageName(CALC_PACKAGE).resourceId("equals")).click(); |
| 483 | |
| 484 | // Verify the result = 5 |
| 485 | UiObject result = mDevice.findObject(By.res(CALC_PACKAGE, "result")); |
| 486 | assertEquals("5", result.getText()); |
| 487 | } |
| 488 | </pre> |
| 489 | |
| 490 | <h2 id="run">Run UI Automator Tests on a Device or Emulator</h2> |
| 491 | <p>UI Automator tests are based on the {@link android.app.Instrumentation} class. The |
| 492 | <a href="https://developer.android.com/tools/building/plugin-for-gradle.html"> |
| 493 | Android Plug-in for Gradle</a> |
| 494 | provides a default directory ({@code src/androidTest/java}) for you to store the instrumented test |
| 495 | classes and test suites that you want to run on a device. The plug-in compiles the test |
| 496 | code in that directory and then executes the test app using a test runner class. You are |
| 497 | strongly encouraged to use the |
| 498 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> |
| 499 | class provided in the |
| 500 | <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> |
| 501 | as your default test runner. </p> |
| 502 | |
| 503 | <p>To run UI Automator tests in your Gradle project:</p> |
| 504 | |
| 505 | <ol> |
| 506 | <li>Specify |
| 507 | <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> |
| 508 | as the default test instrumentation runner in your {@code build.gradle} file: |
| 509 | <pre> |
| 510 | android { |
| 511 | defaultConfig { |
| 512 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" |
| 513 | } |
| 514 | }</pre> |
| 515 | </li> |
| 516 | <li>Run your tests from the command-line by calling the {@code connectedCheck} |
| 517 | (or {@code cC}) task: |
| 518 | <pre>./gradlew cC</pre> |
| 519 | </li> |
| 520 | </ol> |