1. 定位工具
前言,在环境搭建已经安装anroid-sdk,里面就自带有元素定位的工具。找到uiautomatorviewer.bat文件,位置在D:\android-sdk-windows\tools里。可以选择快捷发送到桌面,这样就方便随时使用了。
连接上手机,打开uiautomatorviewer.bat文件,出现这2个按钮:
第一个图标是获取设备截屏,可以获取元素完整的层级关系,所以我们一般使用这个。
第二个图标是获取压缩后的设备截屏,包含各个元素的属性,无法获得完整的层级路径。
ps:工具只能获取手机当前的界面截图,而不是实时同步的显示手机界面
2. 定位方法
- 通过ID进行定位
driver.findElementsById("cn.etouch.ecalendar:id/img_edit")
需要注意的是取值一定要唯一,如果不是唯一,可以选择resource-id、name、text、accessibility id其他方法进行定位
- 通过class定位
driver.findElementsByClassName("android.widget.ImageButton")
class是一个类属性,一般重复性会很高,所以很少直接使用,这里讲class属性是由于在xpath中会频繁用到class属性
- 通过xpath进行定位
xpath是一种特殊的定位方法,理论上xpath可以定位到所有元素
xpath有2种写法,一种绝对路径,一种相对路径。
绝对路径:
元素的全路径,包含了全部节点。这种方法首先一看就觉得太长写起来好累,如果层级再多那写起来简直无休无止了;另一方面由于涉及到太多层,一旦中间任何一层有变动,那元素就定位不到了,例如:
/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.view.ViewGroup/android.widget.ImageButton
相对路径:
1.如果当前class内存在唯一text可以定位元素,直接用当前class+text,例如:
//android.widget.TextView[@text='123']
2.如果当前class内存在唯一content-desc可以定位元素,直接用当前class+content-desc,例如:
//android.widget.TextView[@content-desc='123']
3.如果当前class内,resource-id、text、content-desc三者取其二或者取其三能唯一定位元素,直接用当前class+两者/三者并列,例如:
//android.widget.TextView[@resource-id='com.space.grid.debug:id/text' and @text='123']
4.如果当前class内,text、content-desc中的文本内容不是完全符合,但能匹配部分内容,可用当前class+模糊定位contains,例如:
//android.widget.TextView[contains(@text,'123')]
5.如果在当前class内无法通过以上4种办法定位元素,则向上寻找元素的父节点或者祖父节点通过以上4种办法定位,总之是找到能唯一定位且离元素最近的一个上层节点,例如:
//android.widget.RelativeLayout[@resource-id='com.space.grid.debug:id/address']/android.widget.ImageView[2]
ps:xpath的下标是从1开始的,不是0
- 坐标定位
如果在uiautomatorviewer.bat工具里找不到元素,就只能使用坐标进行定位了。但是有很大的问题,每个手机的分辨率是不一致的,坐标可能只当前手机可用,如果需要这种操作,还要加上手机识别判断。