通过 uiautomatorviewer.bat工具可以查看控件的属性,该工具位于\android-sdk\tools目录下。需要注意的是,你的手机设备或模拟器的API要在16以上,也就是Android版本得是4.2以上,因为这个工具是Google在4.2以后推出来的,只适用于4.2以后的版本。
*执行原理: uiautomatorviewer是发送dump命令,让存放在手机设备中/system/bin/uiautomator下的脚本执行,获得一个uidump.xml的文件,然后将这个xml文件抓到本地,本地读取xml文件就可以了。文件可以看到node节点的信息:包括package和resource_id等等。
PS:Appium桌面版本也提供定位工具——inspector[放大镜的图标]。
首先启动模拟器(adb devices查看设备是否连接),打开uiautomatorviewer.bat工具(功能有:打开已保存的截图;连接设备桌面;保存当前屏幕截图):
PS:保存截图后有两个文件,一个是屏幕截图一个是xml格式的屏幕层级关系(uix文件),直接打开已保存的截图,就不用每次都连接设备打开应用了。
#id定位:通过uiautomatorviewer.bat工具可以查看对象的id属性——resource-id。
用法:driver.find_element_by_id("com.android.calculator2:id/digit_1")
注意,如果driver.find_element_by_id("com.android.calculator2:id/digit_1")找不到元素时,方法会抛出异常,而driver.find_elements_by_id("com.android.calculator2:id/digit_1")则不会报错,其他driver.find_elements_by_XX方法也是这样。
#name定位:通过uiautomatorviewer.bat工具可以查看对象的name属性——text(Appium1.5以前的,1.8以后取消了)。
用法:driver.find_element_by_name("1")
#appium_desktop不支持driver.find_element_by_name
#class name定位:通过uiautomatorviewer.bat工具可以查看对象的class name属性——class。
用法:driver.find_element_by_class_name("android.widget.Button")
使用 class name定位一般获得的view都不止一个,所以需要遍历一遍得到的 views,然后缩小搜索条件来获得目标控件。
比如,先定位一组控件
list = driver.find_elements_by_class_name("android.widget.Button")
# 循环遍历所有控件
for i in list:
print(i)
# 操作某一个控件
list[0].click()
# 点击第一个控件
list[-1].click() # 点击最后一个控件
#accessibility id定位:通过uiautomatorviewer.bat工具可以查看对象的accessibility id属性——content-desc。如果这个属性不为空则推荐使用。[iOS中指的是name属性]
#xpath定位,xpath是xml path的简称,是功能强大的一种定位方式:通常使用xpath相对路径和属性定位。
说明:绝对路径以"/"号表示,相对路径则以"//"表示。当xpath的路径以"/"开头时,表示让xpath解析引擎从文档的根节点开始解析;当xpath路径以"//"开头时,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。而当"/"出现在xpath路径中时,则表示寻找父节点的直接子节点;当"//"出现在xpath路径中时,则表示寻找父节点下任意符合条件的子节点,不管嵌套了多少层级,所以其实xpath的路径可以绝对路径和相对路径混合在一起来进行表示,强大吧!!!
常用用法:
driver.find_element_by_xpath("//android.view.ViewGroup/android.widget.Button[7]")
#查找页面上第一个android.view.ViewGroup元素内的第7个android.widget.Button子元素,即1
driver.find_element_by_xpath("//android.view.ViewGroup/android.widget.Button[@text='1']")
#查找页面上第一个android.view.ViewGroup元素内的text属性为1的android.widget.Button子元素,即1
driver.find_element_by_xpath("//android.view.ViewGroup/android.widget.Button[@class='android.widget.Button'][@index='6']")
#查找页面上第一个android.view.ViewGroup元素内的class属性为android.widget.Button并且index属性为6的android.widget.Button子元素,即1
以上用法是xpath中基于准确元素属性的定位,其实xpath作为定位神器也可以用于模糊匹配:
*contains定位:
driver.find_element_by_xpath("//android.widget.Button[contains(@resource-id,'1')]")
#查找页面上resource-id属性包含1的android.widget.Button元素
备注:关于xpath这种定位方式,webdriver会将整个页面的所有元素进行扫描以定位我们所需要的元素,所以这是一个非常费时的操作,如果你的脚本中大量使用xpath做元素定位的话,会导致你的脚本执行速度降低,所以我们还是慎用的!
#Android uiautomator 定位:通过android 自带的android uiautomator的类库去查找元素。 Appium元素定位方法其实也是基于Uiautomator来进行封装的。
# id 定位driver.find_element_by_android_uiautomator('newUiSelector().resourceId("com.tal.kaoyan:id/login_email_edittext")')
# text定位
driver.find_element_by_android_uiautomator('newUiSelector().text("请输入用户名")')
# class name定位driver.find_element_by_android_uiautomator('newUiSelector().className("android.widget.EditText")')
#组合定位
id+textid_text='newUiSelector().resourceId("com.baidu.yuedu:id/webbooktitle").text("小说")'driver.find_element_by_android_uiautomator(id_text).click()
# 滚动到指定位置self.driver.find_element_by_android_uiautomator('newUiScrollable(''newUiSelector().scrollable(true).instance(0))''.scrollIntoView(''newUiSelector().text("Views").instance(0));').click()