This article translated from: testing UI for multiple Apps
Level limited oneself feel many places express not in place, but can't find the better expression way, if you think have better expression way, help me to improve!
UI testing across multiple apps
Test your appui by interacting across multiple apps to make sure your app is performing correctly, such as when a user switches between your app and other apps or into the system UI. An example is a user switching to the SMS app which allows the user to enter a text message, then switch to the Android address Book to select the target to send, and then return to the SMS app to send the SMS.
This lesson includes how to write these UI tests using the UI Automation test framework provided by the Android testing support library. The UI Automation API allows you to interact with elements that are visible on your device, ignoring which activity is interacting with it. Your test can refer to a UI component, such as the text of a component presentation or its content description, through a handy description of the usage. UI Automation tests can be run on Android 4.3 (API level 18) or higher levels of the API.
The UI Automation test framework is based on the instrumentation API and works with the Androidjunitrunner test Runner.
Set UI Automator
Before you start using UI Automator for UI testing, make sure your project configures your test code catalog and engineering dependencies as described in starting your test.
In your Android APP module's Build.gradle file, you must set the UI Automator Library's dependencies:
dependencies { ... ‘com.android.support.test.uiautomator:uiautomator-v18:2.1.1‘}
To optimize your UI Automator testing, you must first check the UI components of the target app to make sure they are available. These optimization recommendations will be described in the following two sections.
Check the UI on the device
Before you design your tests, you should check that the UI components are visible on the device. To ensure that your UI Automator tests can get these components, check that they have visible text tags, are configured with Android:contentdescription, or have two of them.
The Uiautomatorviewer tool provides a convenient visual interface to check the layout hierarchy and view the properties of the UI components, which are visible in the foreground of the device. With this information you can use the UI Automator to create more delicate tests. For example, you can create a UI seletor that can match a particular visual property.
Load a uiautomatorviewer tool:
- Load a target app onto the physical device.
- Connect the device to your development machine
- Open a terminal and navigate to the
<android-sdk>/tools/
directory.
- Run the tool with a command
$ uiautomatorviewer
View the features of your app's UI
- On the Uiautomatorviewer screen, click the Device screenshot button.
- You can overview the UI component definition by Uiautomatorviewrtool hovering the snapshot in the left panel. The features of this component are listed below the right panel, and the layout level is above the left.
- Selectively click the Toggle NAF node button to view UI components that are not captured by the UI Automator, but can only get limited information about those components.
Learn about the universal UI components provided by Android and view the user Interface.
Make sure your activity is available.
The UI Automator test framework relies on the features available from the Android framework to view standalone UI elements. As a developer, you should implement these most basic optimizations in your activity to support UI Automator:
- Use the Android:contentdescription property to give ImageButton, ImageView, checkbox tagging, and other user interface control components.
- Provide EditText with a android:hint attribute to replace the content description.
- Combine the Android:hint attribute with any graphical icon to provide feedback to the user (for example, status information).
- Use the Uiautomatorviewer tool class to ensure that the UI component can be obtained by the test framework. You can also test the application by opening the Get service like talkback and then browsing by touch, then try to use your app only in one direction.
Often, app developers have easy access to view and ViewGroup support, however, some apps use custom view to give users a richer user experience. These custom elements will not get the support provided by standard UI elements. If your app uses a custom view, make sure that the custom drawing UI element is exposed by implementing the Accessibilitynodeprovider class for Android get service.
If the custom view element contains a single element, let him make it available by implementing the API method. If the custom view contains elements, they are not view own (for example, a wevview, make sure it implements the Accessibilitynodeprovider class. For the Package Class View it inherits a container implementation of the existing package (for example, a ListView), implementing Accessibilitynodeprovider is not required.
For more information on implementations and the availability of tests, see Making applications Accessible.
Create a UI Automator test class
Your UI Automator test class should be written in the style of the JUnit 4 test class. To learn more about creating JUnit 4 test classes and using JUnit 4 for assertions, annotations, see Building instrumented unit tests.
Add @runwith (androidjunit4.class) annotations where you begin defining the test class. You should also declare the Androidjunitrunner as your default test runner provided in the Android testing support Library.
For a more detailed description of this step, see: Run UI Automator Tests on a Device or Emulator.
Write your UI Automator test class according to the following programming rules:
- Get the Uidevice object to access the device you want to test by calling the GetInstance () method and passing a instrumentation object parameter into
- By calling the Findobject () method, get a UIObject object to access the UI component that is displayed on the device (for example, the current view in the foreground).
- The interaction between a specific and UI component is simulated by invoking the UIObject method. For example, call Performmultipointergesture () to simulate a complex touch gesture, and SetText () to edit a text field. You can repeat the 2nd and 3rd steps of the API as needed to test more complex user interactions It allows more UI components to participate in or a series of user actions.
- Check the UI reflects the expected state or behavior, after these user interactions is performed. Checks if the UI follows the user interaction The desired state or performance gives feedback.
These steps are used extensively in the following sections.
Accessing the UI Component
Uidevice is the most basic way to access and manipulate the state of your device. In your test, you can call the Uidevice method to check for different features, such as the current direction or the size of the display. Your test can use the Uidevice object to perform device-level actions, such as rotating the device, pressing the D-PAD hardware button, and pressing the Home and Menu buttons.
The best thing to do is to start testing from the home screen of the device, and at home screens (or other starting positions you choose on the device), you can call the UI Automator Api to provide a way to select and interact with specific UI elements.
The following code snippet shows you how to get an instance of Uidevice and simulate pressing the home key:
ImportOrg.junit.Before;ImportANDROID.SUPPORT.TEST.RUNNER.ANDROIDJUNIT4;ImportAndroid.support.test.uiautomator.UiDevice;ImportAndroid.support.test.uiautomator.By;ImportAndroid.support.test.uiautomator.Until, .....@RunWith(Androidjunit4.class)@SdkSuppress(Minsdkversion = -) Public class changetextbehaviortest { Private Static FinalString Basic_sample_package ="Com.example.android.testing.uiautomator.BasicSample";Private Static Final intLaunch_timeout = the;Private Static FinalString string_to_be_typed ="Uiautomator";PrivateUidevice Mdevice;@Before Public void Startmainactivityfromhomescreen() {//Initialize Uidevice instanceMdevice = Uidevice.getinstance (Instrumentationregistry.getinstrumentation ());//Start from the home screenMdevice.presshome ();//Wait for launcher FinalString launcherpackage = Mdevice.getlauncherpackagename (); Assertthat (Launcherpackage, Notnullvalue ()); Mdevice.wait (Until.hasobject (by.pkg (launcherpackage) Depth (0)), launch_timeout);//Launch the appContext context = Instrumentationregistry.getcontext ();FinalIntent Intent = Context.getpackagemanager (). Getlaunchintentforpackage (Basic_sample_package);//Clear out any previous instancesIntent.addflags (Intent.flag_activity_clear_task); Context.startactivity (Intent);//Wait for the app to appearMdevice.wait (Until.hasobject (by.pkg (basic_sample_package) Depth (0)), launch_timeout); }}
In this example, @SdkSuppress (minsdkversion = 18) statement to ensure that the test will only run on Android 4.3 (API level 18) or later, because the UI Automator framework requires Android The SDK version must not be less than 18.
Use the Findobject () method to get a uiobject that represents a view that matches the given selection criteria. You can reuse UIObject instances created in other parts of your app test. It is important to note that the UI Automator test framework looks for a matching display each time you use a UIObject instance to click on a UI element or query for a property.
The following snippet shows how your test might construct UiObject instances that represent a Cancel button and a OK Butto N in an app. The following code snippet shows you how your test creates a UIObject instance that represents a Cancle button and an OK button in the app.
uiobject CancelButton = Mdevice.findObject (new Uiselector () .text ( "Cancel" )) .classname ( "Android.widget.Button" )) UiObject OKButton = Mdevice.findobject (New Uiselector () .text ()) .classname ( "Android.widget.Button" )) Simulate a user-click on the OK button, if Found.if (Okbutton.exists () && Amp Okbutton.isenabled ()) {Okbutton.click () ; }
Specifically declare a selector
If you want to access a specific UI component in the app, you can use the Uiselector class. This class represents a query for a specific element of the currently displayed UI.
If more than one matching element is found, the first matching element in the layout hierarchy will be returned as a UIObject object. When building a uiselector, you can concatenate multiple properties together to reorganize a query. If a matching UI element is not found, a uiautomatorobjectnotfoundexception will be thrown
You can use the Childselector () method and the Uiselector instance to nest each other. For example, the following code example shows you how to specifically declare a query in your test to find the first ListView in the currently displayed UI, and then look for the UI element with the Text property in the ListView.
new UiObject(new UiSelector() .className("android.widget.ListView") .instance(1) .childSelector(new UiSelector() .text("Apps")));
Best way, when specifically declaring a selector, you should use a resource ID (if you have already declared a UI element) in place of a text element or Content-descriptor. Not all elements have text elements (for example, icons in toolbar). The Text selectors is very fragile, and if you modify the UI it can easily lead to a test failure. They may also not cross the language, your text selectors may not match the translated strings.
Specifying the state of an object is very useful in your selector standard. For example, if you want to select a range of selected elements, you can uncheck them, call the checked () method, and pass true as their argument.
Perform actions
Once your test has obtained a UIObject object, you can invoke the method in the UIObject class to perform the user interaction that the object represents for the UI component. You can specifically declare these actions as:
- Click (): Tap the center of the visual area of the UI element
- Dragto (): Drag this object to the specified coordinates
- SetText (): Sets the content for this field after clearing the contents of the field. Instead, the Cleartextfield () method clears the content that exists in an editable field.
- Swipeup (): Performs a matching action on the UIObject object, swipe up action, similar, Swipedown (), Swipeleft (), and Swiperight () methods.
The UI Automation test framework allows you to send a intent or load an activity to get a context object using the GetContext () method without using the shell command.
The following code snippet shows you how to use intent to load an app for testing. This approach is very useful when you are only interested in the test Calculator app and don't worry about launcher
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 outAny previous instances context. StartActivity(Intent);Mdevice. Wait(Until. Hasobject(By. Pkg(Calc_package). Depth(0)), TIMEOUT);}
To perform an action on a collection
If you want to simulate interacting with an item in a collection (for example, a song in a music album or a mailing list in your Inbox), you can use the Uicollection class. In order to create a Uicollection object, specifically declare a uiselector it looks for a UI container or a wrapper for a different child UI element, such as a layout view that contains child UI elements.
The following code snippet shows you how to build a uicollection in your test to represent a video album it is displayed in a framelayout:
Uicollection videos =NewUicollection (NewUiselector (). ClassName ("Android.widget.FrameLayout"));//Retrieve the number ofVideosinch This Collection: int count = Videos.getchildcount (NewUiselector (). ClassName ("Android.widget.LinearLayout"));//Find a specific video andSimulate a User-click onItuiobject video = Videos.getchildbytext (NewUiselector (). ClassName ("Android.widget.LinearLayout"),"Cute Baby Laughing"); Video.click ();//Simulate selecting a checkbox that isAssociated withThe Videouiobject CheckBox = Video.getchild (NewUiselector (). ClassName ("Android.widget.Checkbox"));if(!checkbox.isselected ()) Checkbox.click ();
Perform an action in a scrollable view
Use the Uiscrollable class to simulate vertical or horizontal scrolling across a display. This technique was helpful when a UI element was positioned off-screen and you need to scroll to bring it into view. Using Uiscro The Llable class to simulate scrolling in horizontal or vertical directions. This technique is very useful, and when a UI element has scrolled out of the screen, you need to scroll to get it into view.
The following code snippet shows how to simulate scrolling down the Settings menu and then clicking on the About option:
UiScrollable settingsItem = new UiScrollable(new UiSelector() .className("android.widget.ListView"));UiObject about = settingsItem.getChildByText(new UiSelector() .className("android.widget.LinearLayout""About tablet");about.click();
Validation results
Instrumentationtestcase inherits from TestCase, so you can use the standard JUnit assertion method to test whether the UI elements in your app return the expected results.
The following code snippet shows how your test finds a button for a calculator app, clicks them in order, and then verifies that the results are correct.
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("both")). 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 =5UiObject result = Mdevice. Findobject(By. Res(Calc_package,"Result"));Assertequals ("5", result. GetText());}
Run UI Automation tests on a specific device or simulator
You can run UI Automation tests from Android Studio or from the command line. Make sure that Androidjunitrunner is declared as the default instrumentation runner in your project.
Follow the steps described in starting your test to run your UI automator test.
UI testing across multiple apps