In my previous article <<Appium based on Android's various findelement control positioning methods Practice and recommendations >> In the second chapter, Appium can use the Uiautomator method to locate the controls on the Android interface, just a few examples. As this article gives its own commitment, today special writing this article to describe uiautomator various control positioning methods, as the previous article of the sister article Exchange.
1. Background
In order to agree with the previous article, the practice object is also the use of the SDK comes with the Notepad application, also try to get in noteslist that activity in the menu options above the Add Note menu option. Here is a uiautomatorviewer to the interface.
One exception to this is the following section, " Locating controls by Pseudo-XPath methods ", using the menu options in the activity of Noteeditor. Because you need to demonstrate the ability to get a parent control through a child control and then get the sibling control, Uiautomatorviewer is as follows.
2. Positioning the control via text information through the control's Text property is one of the most common methods, after all, the mobile application screen size is limited, there is no possibility of text duplication is not big, even if there is a repetition, you can add other positioning methods to abbreviate the error. 2.1 Uiselector.text Method
Addnote = new UiObject (new Uiselector (). Text ("Add note"); Assertequals (Addnote.gettext (), "Add note");
This method is well understood by looking directly at all the controls on the current interface to compare whether the Text property of each control is positioning the control as expected, 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 method above, but does not require the input of all text information for the control.
2.3 Uiselector.textstartswith Method
Addnote = new UiObject (new Uiselector (). Textstartswith ("Add")); Assertequals (Addnote.gettext (), "Add note");
As the name implies, by judging whether the beginning of a control's text coincides with the expected string to obtain the control, in fact, personally feel that the need for this method is not strong, because its function can be completely replaced by the above method or the following regular expression method. And since you offer the Textstartswith method, why don't you offer a Textendwith method? 2.4 Uiselector.textmatches Method
Addnote = new UiObject (new Uiselector (). Textmatches ("^add.*")); Assertequals (Addnote.gettext (), "Add note");
The method is to use regular expressions to compare the text of the control to locate the control, it is interesting to note that the user's regular expression is limited, see the official description of the 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“。 The first sentence we do not care about it, the key is the second sentence, translation comes to be "The text of the target control must exactly match the regular expression we entered“。 What do you mean?It means that you can't get the control by comparing the parts of text with the regular expressions as usual.。 Take the following code as an example:
Addnote = new UiObject (new Uiselector (). Textmatches ("^add")); Assertequals (Addnote.gettext (), "Add note");
Normally this regular expression is not a problem, it means to "get the text with the start of the control, as for the Add Word serial interface is what value, there is no need to control it." But according to our official description, this is not possible, you have to complement the regular expression so that the positive and the expression and the text of the control completely match, as to what you use the wildcard character or string to exactly follow the syntax of regular expressions.Note that this restriction works well in uislector using all regular expression related methods. 3 positioning through the classname of controls
One problem with locating controls in this way is that they are prone to duplication, so it is common to use this method to narrow down the target control and then add other conditions such as text judgment to position the control.
3.1 Uiselector.classname method
Addnote = new UiObject (new Uiselector (). ClassName ("Android.widget.TextView"). Text ("Add note"); Assertequals (Addnote.gettext (), "Add note");
The instance first finds all the TextView controls through classname, and then finds the control in these TextView controls with the text "Add note". 3.2 Uiselector.classnamematches Method
Addnote = new UiObject (new Uiselector (). Classnamematches (". *textview$")); Assertequals (Addnote.gettext (), "Add note");
Judging whether the classname is consistent with the expected by regular expressions,note the limitations of regular expressions and the consistency described in section 2.4。 4. Locating the Uiselector class by pseudo-XPath method provides some methods for locating the control based on its hierarchical relationship in the XML layout of the interface. But Uiautomator doesn't really offer a findelementwithxpath-related approach like Appium, so here's what I call the Pseudo-XPath method. This chapter is not used to noteslist that activity in the menu options, but noteeditor the activity inside the menu options, there is more than one menu entry. 4.1 I think the most useful thing to do with the Uiselector.fromparent or Uiobject.getfromparent method is to test that the code is currently working on one of the controls in a group of controls at the same level and in turn needs to manipulate another control at the same level. The following example finds the sibling control delete at its same level through the Save control's parent control. Examples of uiobject.getfromparent methods and Uiselector.fromparent methods are listed here, and in fact they function 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");
The Uiselector.fromparent method (this example is a bit circuitous and clumsy, but for the sake of presentation):
Delete = new UiObject (new Uiselector (). Text ("Save"). Fromparent (New Uiselector (). Text ("Delete")); Assertequals (Delete.gettext (), "delete");
4.2 Through the Uiselector.childselector or Uiobject.getchild method, this method is how to quickly find the child controls 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. Locate the Android API Level18 and above by using the control ID to add an Android control's properties ResourceID,so be aware that before using this method, make sure that your target test device and your Uiautomoator library jar package are using the API level 18 version .。 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 the limitations of regular expressions and the consistency described in section 2.4
6. With contentdescription positioning in the Uiautomator framework and Appium using the Uiautomator framework, the property contentdescription of the control always emphasizes the need for developers to add, because
- Some controls use other methods that are difficult or impossible to locate
- The most important thing is to design a unique value for each control's contentdescription so that we can position the controls very quickly, so that we are agile enough!
The following example does not really run, because the Notepad application above the control is not contentdescription this property, but if we assume that the add note this control's contentdescription is " Addnotemenudesc "Words, the corresponding code should be 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. Other methods to locate in addition to the more commonly used methods, Uiautomator also support other methods, such as whether the control properties can be clicked to focus on the ability to narrow the scope of the control to be positioned, the use of methods not listed, you can view the following test validation 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 UiS Elector (). 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"), "note 1 ", 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"); } }
Uiautomator ways to locate Android controls practice and advice (Appium sister article)