UIAutomator practices and suggestions for locating Android controls (Appium companion), uiautomatorappium

Source: Internet
Author: User
Tags appium

UIAutomator practices and suggestions for locating Android controls (Appium companion), uiautomatorappium

In my previous article, <Appium's various Android-based FindElement control locating methods practices and suggestions> Chapter 2 describes how Appium can be used to locate the Android interface using the UIAutomator method. control, at that time, I just gave an example. As promised by this article, I wrote this article today to describe the methods for positioning various controls of UIAutomator, as a companion article in the previous article, to see each other.

1. Background

In order to reach an agreement with the previous article, this practical object is also the NotePad application that comes with the SDK. It is also an attempt to obtain the Add note Menu option on the Menu Options in the NotesList Activity. The following is an interface for UIAutomatorViewer.


However, the following is an exception"Use the pseudo xpath method to locate the control"The Menu options in the activity NoteEditor must be used for Chapter instances, because you need to demonstrate how to obtain the parent control through the Child control and then obtain the functions of the sibling control. The UIAutomatorViewer is as follows.


2. using text information to locate a widget using the text attribute should be the most common method. After all, the screen size of a mobile app is limited and there is no possibility of text duplication, even if there are duplicates, you can add other positioning methods to abbreviated errors. 2.1 UISelector. text Method
        addNote = new UiObject(new UiSelector().text("Add note"));        assertEquals(addNote.getText(),"Add note");
This method is easy to understand by directly searching all controls on the current interface to compare whether the text attribute of each control is as expected to locate the control, so there is no need to elaborate. 2.2. UISelector. textContains Method
        addNote = new UiObject(new UiSelector().textContains("Add"));        assertEquals(addNote.getText(),"Add note");
This method is similar to the preceding method, but you do not need to enter all text information of the control.
2.3 UISelector. textStartsWith Method
        addNote = new UiObject(new UiSelector().textStartsWith("Add"));        assertEquals(addNote.getText(),"Add note");
As the name suggests, you can determine whether the text of a control matches the expected string to obtain the control. In fact, I personally think this method is not necessary, because its function can be completely replaced by the above method or the following regular expression method. Besides, since you have provided the textStartsWith method, why don't you provide a textEndWith method! 2.4 UISelector. textMatches Method
        addNote = new UiObject(new UiSelector().textMatches("^Add.*"));        assertEquals(addNote.getText(),"Add note");
This method uses regular expressions to compare the text of the control to locate the control. What is interesting here is that the regular expressions used by users are limited. Please refer to the official description of this method :" Set the search criteria to match the visible text displayed for a widget (for example, the text label to launch an app ). the text for the widget must match exactly with the string in your input argument". In the first sentence, we don't need to worry about it. The key is the second sentence. The translation means that "the text of the target control (all content) must exactly match the regular expression we entered". What does it mean? This means that you cannot obtain the control by comparing the part of text as the regular expression. The following code is used as an example:
        addNote = new UiObject(new UiSelector().textMatches("^Add"));        assertEquals(addNote.getText(),"Add note");
Normally, this regular expression is correct. It means that you want to "obtain the text control starting with" Add ". What is the value of the" Add "serial port, there is no need to manage it ". However, according to the official description above, this is not acceptable. You must complete the regular expression to make the positive expression completely match the control text, as for what wildcard characters or strings you use, you can use the regular expression syntax. Note that this restriction is valid in UISlector's methods related to all regular expressions. 3. Locate through the ClassName of the control

This method is used to locate the control. A problem occurs easily when the control is repeated. Therefore, this method is generally used to narrow down the target control, and then add other conditions such as text judgment to locate the control.

3.1 UISelector. className Method
        addNote = new UiObject(new UiSelector().className("android.widget.TextView").text("Add note"));        assertEquals(addNote.getText(),"Add note");
In the instance, first find all TextView controls through ClassName, and then find the controls whose text is "Add note" in these TextView controls. 3.2 UISelector. classNameMatches Method
        addNote = new UiObject(new UiSelector().classNameMatches(".*TextView$"));        assertEquals(addNote.getText(),"Add note");
Use a regular expression to determine whether the className is as expected. Note that the limit of the regular expression is consistent with that described in section 2.4. 4. using the pseudo xpath method to locate the UISelector class provides some methods to locate the control based on the hierarchical relationship of the control in the XML layout of the interface. However, uiautomation does not actually provide methods related to findElementWithXpath similar to Appium, so here I call it the pseudo xpath method. This chapter no longer uses menu options in the activity NotesList, but Menu options in the activity NoteEditor, which contains more than one Menu entry. 4.1 Use UiSelector. fromParent or UiObject. the getFromParent method is one of the most useful cases for me to test the code. Currently, the code is operating on a group of controls at the same level, in turn, you need to operate another control at the same level. The following example shows how to use the parent control of the save control to find the delete sibling control at the same level. Here we list the instances through the UiObject. getFromParent method and the UiSelector. fromParent method. In fact, their functions are the same. UiObject. getFromPatrent method:
        save =  new UiObject(new UiSelector().text("Save"));        assertEquals(save.getText(),"Save");        delete = save.getFromParent(new UiSelector().text("Delete"));        assertEquals(delete.getText(),"Delete");
UiSelector. fromParent method (this example is a bit clumsy, but we will look at it for demonstration ):
        delete = new UiObject(new UiSelector().text("Save").fromParent(new UiSelector().text("Delete")));        assertEquals(delete.getText(),"Delete");
4.2 The UiSelector. childSelector or UiObject. getChild method is used to quickly find the child control under the parent control when the parent control is known. UiObject. getChild method:
        UiObject parentView = new UiObject(new UiSelector().className("android.view.View"));        save = parentView.getChild(new UiSelector().text("Save"));        assertEquals(save.getText(),"Save");
UiSelector. childSelector method:
        save = new UiObject(new UiSelector().className("android.view.View").childSelector(new UiSelector().text("Save")));        assertEquals(save.getText(),"Save");
5. added the ResourceId attribute of the Android control in the Android API Level18 and later versions by using the control ID, therefore, before using this method, make sure that your target Testing Device and your UIAutomoator library jar package use a version above API Level 18. For example, I am using a library of version 19 in the local sdk: D: \ Develops \ AndroidSDK \ platforms \ android-19 \ uiautomator. jar5.1 UiSelector. resourceId Method
        addNote = new UiObject(new UiSelector().resourceId("android:id/title"));        assertEquals(addNote.getText(),"Add note");
5.2 UiSelector. resourceIdMatches Method
        addNote = new UiObject(new UiSelector().resourceIdMatches(".+id/title"));        assertEquals(addNote.getText(),"Add note");
Note that the limitations of regular expressions are consistent with those described in section 2.4.
6. Use contentDescription to locate in the UiAutomator framework and the Appium using the Uiautomator framework. The contentDescription attribute of the Control always emphasizes that developers need to add it because
  • Some controls are difficult to use or cannot be located at all.
  • The most important thing is to design a unique value for the contentDescription of each control so that we can quickly locate the control and make it agile enough!
The following examples have not really run, because the control on the Notepad application does not have the contentDescription attribute, but if we assume that the contentDescription of the Add note control is "AddNoteMenuDesc, the Code should be written as follows. 6.1 UiSelector. description Method
        addNote = new UiObject(new UiSelector().description("AddNoteMenuDesc));        assertEquals(addNote.getText(),"Add note");
</Pre> 6.3 UiSelector. descriptionStartWith Method
        addNote = new UiObject(new UiSelector().descriptionStartsWith("AddNote"));        assertEquals(addNote.getText(),"Add note");
6.4 UiSelector. descriptionMatches Method
        //addNote = new UiObject(new UiSelector().descriptionMatches("^AddNote.*$"));        //assertEquals(addNote.getText(),"Add note");
7. in addition to the commonly used methods, UIAutomator also supports other methods. For example, you can narrow down the scope of the control to be located based on whether the control attribute can be clicked and can be focused or pressed, for more information, see the following test code.
package majcit.com.UIAutomatorDemo;import com.android.uiautomator.core.UiDevice;import com.android.uiautomator.core.UiObject;import com.android.uiautomator.core.UiObjectNotFoundException;import com.android.uiautomator.core.UiScrollable;import com.android.uiautomator.core.UiSelector;import com.android.uiautomator.testrunner.UiAutomatorTestCase;import static org.hamcrest.Matchers.*;import static org.hamcrest.MatcherAssert.assertThat;public class UISelectorFindElementTest extends UiAutomatorTestCase { public void testDemo() throws UiObjectNotFoundException {          UiDevice device = getUiDevice();        device.pressHome();          // Start Notepad        UiObject appNotes = new UiObject(new UiSelector().text("Notes"));         appNotes.click();          //Sleep 3 seconds till the app get ready        try {              Thread.sleep(3000);          } catch (InterruptedException e1) {              // TODO Auto-generated catch block              e1.printStackTrace();          }                  //Evoke the system menu option        device.pressMenu();        UiObject addNote = new UiObject(new UiSelector().text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject (new UiSelector().checked(false).clickable(true));        assertEquals(addNote.getText(),"Add note");                        addNote = new UiObject(new UiSelector().className("android.widget.TextView").text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().classNameMatches(".*TextView$"));        assertEquals(addNote.getText(),"Add note");                //addNote = new UiObject(new UiSelector().description("AddNoteMenuDesc));        //assertEquals(addNote.getText(),"Add note");                //addNote = new UiObject(new UiSelector().descriptionContains("AddNote"));        //assertEquals(addNote.getText(),"Add note");                //addNote = new UiObject(new UiSelector().descriptionStartsWith("AddNote"));        //assertEquals(addNote.getText(),"Add note");                //addNote = new UiObject(new UiSelector().descriptionMatches("^AddNote.*$"));        //assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().focusable(true).text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().focused(false).text("Add note"));        assertEquals(addNote.getText(),"Add note");                        //TBD        //addNote = new UiObject(new UiSelector().fromParent(selector))                addNote = new UiObject(new UiSelector().index(0).text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().className("android.widget.TextView").enabled(true).instance(0));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().longClickable(false).text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().text("Add note"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().textContains("Add"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().textStartsWith("Add"));        assertEquals(addNote.getText(),"Add note");                        addNote = new UiObject(new UiSelector().textMatches("Add.*"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().resourceId("android:id/title"));        assertEquals(addNote.getText(),"Add note");                addNote = new UiObject(new UiSelector().resourceIdMatches(".+id/title"));        assertEquals(addNote.getText(),"Add note");                //Go to the editor activity, need to cancel menu options first        device.pressMenu();        //Find out the new added note entry        UiScrollable noteList = new UiScrollable( new UiSelector().className("android.widget.ListView"));          //UiScrollable noteList = new UiScrollable( new UiSelector().scrollable(true));         UiObject note = null;        if(noteList.exists()) {        note = noteList.getChildByText(new UiSelector().className("android.widget.TextView"), "Note1", true);          //note = noteList.getChildByText(new UiSelector().text("Note1"), "Note1", true);         }        else {        note = new UiObject(new UiSelector().text("Note1"));        }        assertNotNull(note);                //Go to the NoteEditor activity        note.click();        device.pressMenu();                UiObject save = null;        UiObject delete = null;                save =  new UiObject(new UiSelector().text("Save"));        assertEquals(save.getText(),"Save");        delete = save.getFromParent(new UiSelector().text("Delete"));        assertEquals(delete.getText(),"Delete");                delete = new UiObject(new UiSelector().text("Save").fromParent(new UiSelector().text("Delete")));        assertEquals(delete.getText(),"Delete");                save = new UiObject(new UiSelector().className("android.view.View").childSelector(new UiSelector().text("Save")));        assertEquals(save.getText(),"Save");                UiObject parentView = new UiObject(new UiSelector().className("android.view.View"));        save = parentView.getChild(new UiSelector().text("Save"));        assertEquals(save.getText(),"Save");                              }  }





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.