(以下部分转载于科技向前冲,并加入了自己的总结与理解)
Appium定位控件的多种方法
需要用到Android sdk中的辅助工具 monitor(hierarchyviewer与uiautomatorviewer的整合)来获取控件的一些属性
1. findElementByName
1.1 示例
?
1 2 |
el = driver.findElementByName("Add note"); |
1.2 如何获得Name
调用driver.findElementByName("xxx");语句时Appium log如下,因此分析此方法中的Name其实包含三部分,为属性Name、Description、Text中任意一部分包含查询条件,均视为找到该element。因此,可以用view中的text属性值进行定位。
2.UIAutomator
el = driver.findElementByAndroidUIAutomator("new UiSelector().text(\"Add note\")");
2.1 如何获得UIAutomator参数
UIAutomator获取控件的方式多种多样,都是通过UiSelector对象来去查找,通过控件的text属性定位控件应该是最常用的一种方法了,毕竟移动应用的屏幕大小有限,存在text重复的可能性并不大,就算真的有重复,可以添加其他定位方法来缩写误差。
2.1.1 UISelector.text方法
该方法通过直接查找当前界面上所有的控件来比较每个控件的text属性是否如预期值来定位控件,挺好理解的,所以就没有必要细说了。
2.1.2. UISelector.textContains方法
3. findElementByClassName
3.1 示例
1 2 |
el = driver.findElementByClassName("android.widget.TextView"); assertThat(el.getText(),equalTo("Add note")); |
3.2 如何获得控件的ClassName
可以使用UIAutomatorViewer工具直接查看
3.3 建议
使用ClassName一般获得的view都不止一个,所以应该需要遍历一遍得到的views,然后缩写搜索条件来获得目标控件。示例中因为只有一个textview控件在窗口上面,所以不需要遍历。
4. findElementById
4.1 示例
1 2 |
el = driver.findElementById("android:id/title"); assertThat(el.getText(),equalTo("Add note")); |
4.2 如何获得Resource Id
可以通过UIAutomatorViewer获得
4.3 建议
如果目标设备的API Level低于18则UIAutomatorViewer不能获得对应的Resource ID,只有等于大于18的时候才能使用。
控件的所有属性都可以用作判断,比如它的text,index,resource-id是否clickable等,例如:
el = driver.findElementByXPath("//android.widget.TextView[contains(@text,'note2')]");
assertThat(el.getText(),equalTo("note2"));
如果我们像下面的方式使用index为0来查找控件note2,那么将会失败,因为该xpath只是说“我要查找页面上 android.widget.TextView类型的index为0的控件“,但如背景所说我们事实上有3个TextView控件,其中最上面的和中间 的控件他们的Index都是0.所以最终获得的控件其实是Appium第一个找到的最上面文本为”Notes“的TextView。
el = driver.findElementByXPath("//android.widget.TextView[contains(@index,0)]");
assertThat(el.getText(),equalTo("note2"));
那么我们就要想办法加多点路径,让xpath能分辨出需要的是下面的index为0的TextView,而不是上面的。观看上图的 UIAutomatorViewer控件的分层结构,发现这两个TextView是从LinearLayout开始分叉的,所以我们应该从该路径开始通过数组下标指定我们需要的是”在LinearLayout下面的第二个FrameLayout下面的ListView下面的Index为0的 TextView:
el = driver.findElementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[contains(@index,0)]");
assertThat(el.getText(),equalTo("note2"));