1.简介
uiautomator2是一个自动化测试开源工具,仅支持android平台的自动化测试,其封装了谷歌自带的uiautomator2测试框架,可以运行在支持Python的任一系统上,目前版本为2.10.2
开源库地址:
https://github.com/openatx/uiautomator2
2.工作原理
引用自https://testerhome.com/topics/11357
如图所示,python-uiautomator2主要分为两个部分,python客户端,移动设备
- python端: 运行脚本,并向移动设备发送HTTP请求
- 移动设备:移动设备上运行了封装了uiautomator2的HTTP服务,解析收到的请求,并转化成uiautomator2的代码。
整个过程
- 在移动设备上安装
atx-agent
(守护进程), 随后atx-agent
启动uiautomator2服务(默认7912端口)进行监听 - 在PC上编写测试脚本并执行(相当于发送HTTP请求到移动设备的server端)
- 移动设备通过WIFI或USB接收到PC上发来的HTTP请求,执行制定的操作
3.安装与启动
3.1 安装uiautomator2
使用pip安装
pip install -U uiautomator2
安装完成后,使用如下python代码查看环境是事配置成功
说明:后文中所有代码都需要导入uiautomator2库,为了简化我使用u2代替,d代表driver
import uiautomator2 as u2
# 连接并启动
d = u2.connect()
print(d.info)
能正确打印出设备的信息则表示安装成功
注意:需要安装 adb 工具,并配置到系统环境变量,才能操作手机
安装有问题可以到https://github.com/openatx/uiautomator2/wiki/Common-issues这里查看一下有没有相同的问题
3.2 安装weditor
weditor是一款基于浏览器的UI查看器,用来帮助我们查看UI元素定位。
因为uiautomator是独占资源,所以当atx运行的时候uiautomatorviewer是不能用的,为了减少atx频繁的启停,就需要用到此工具
使用pip安装
pip install -U weditor
查看安装是否成功
weditor --help
出现如下信息表示安装成功
运行weditor
python -m weditor
#或者直接在命令行运行
weditor
4. 元素定位
4.1 使用方法
d(定位方式=定位值)
#例:
element = d(text='Phone')
#这里返回的是一个列表,当没找到元素时,不会报错,只会返回一个长度为0的列表
#当找到多个元素时,会返回多个元素的列表,需要加下标再定位
element[0].click()
#获取元素个数
print(element.count)
4.2 支持的定位方式
ui2支持 android 中 UiSelector 类中的所有定位方式,详细可以在这个网址查看https://developer.android.com/reference/android/support/test/uiautomator/UiSelector
整体内容如下,所有的属性可以通过weditor查看到
名称 | 描述 |
---|---|
text | text是指定文本的元素 |
textContains | text中包含有指定文本的元素 |
textMatches | text符合指定正则的元素 |
textStartsWith | text以指定文本开头的元素 |
className | className是指定类名的元素 |
classNameMatches | className类名符合指定正则的元素 |
description | description是指定文本的元素 |
descriptionContains | description中包含有指定文本的元素 |
descriptionMatches | description符合指定正则的元素 |
descriptionStartsWith | description以指定文本开头的元素 |
checkable | 可检查的元素,参数为True,False |
checked | 已选中的元素,通常用于复选框,参数为True,False |
clickable | 可点击的元素,参数为True,False |
longClickable | 可长按的元素,参数为True,False |
scrollable | 可滚动的元素,参数为True,False |
enabled | 已激活的元素,参数为True,False |
focusable | 可聚焦的元素,参数为True,False |
focused | 获得了焦点的元素,参数为True,False |
selected | 当前选中的元素,参数为True,False |
packageName | packageName为指定包名的元素 |
packageNameMatches | packageName为符合正则的元素 |
resourceId | resourceId为指定内容的元素 |
resourceIdMatches | resourceId为符合指定正则的元素 |
4.3 子元素和兄弟定位
子元素定位
child()
#查找类名为android.widget.ListView下的Bluetooth元素
d(className="android.widget.ListView").child(text="Bluetooth")
# 下面这两种方式定位有点不准确,不建议使用
d(className="android.widget.ListView")\
.child_by_text("Bluetooth",allow_scroll_search=True)
d(className="android.widget.ListView").child_by_description("Bluetooth")
兄弟元素定位
sibling()
#查找与google同一级别,类名为android.widget.ImageView的元素
d(text="Google").sibling(className="android.widget.ImageView")
链式调用
d(className="android.widget.ListView", resourceId="android:id/list") \
.child_by_text("Wi‑Fi", className="android.widget.LinearLayout") \
.child(className="android.widget.Switch") \
.click()
4.4 相对定位
相对定位支持在left
, right
, top
, bottom
,即在某个元素的前后左右
d(A).left(B),# 选择A左边的B
d(A).right(B),# 选择A右边的B
d(A).up(B), #选择A上边的B
d(A).down(B),# 选择A下边的B
#选择 WIFI 右边的开关按钮
d(text='Wi‑Fi').right(resourceId='android:id/widget_frame')
4.5 元素常用API
表格标注有@property装饰的类属性方法,均为下方示例方式
d(test="Settings").exists
方法 | 描述 | 返回值 | 备注 |
---|---|---|---|
exists() | 判断元素是否存在 | True,Flase | @property |
info() | 返回元素的所有信息 | 字典 | @property |
get_text() | 返回元素文本 | 字符串 | |
set_text(text) | 设置元素文本 | None | |
clear_text() | 清空元素文本 | None | |
center() | 返回元素的中心点位置 | (x,y) | 基于整个屏幕的点 |
exists其它使用方法:
d.exists(text='Wi‑Fi',timeout=5)
info()输出信息:
{
"bounds": {
"bottom": 407,
"left": 216,
"right": 323,
"top": 342
},
"childCount": 0,
"className": "android.widget.TextView",
"contentDescription": null,
"packageName": "com.android.settings",
"resourceName": "android:id/title",
"text": "Wi‑Fi",
"visibleBounds": {
"bottom": 407,
"left": 216,
"right": 323,
"top": 342
},
"checkable": false,
"checked": false,
"clickable": false,
"enabled": true,
"focusable": false,
"focused": false,
"longClickable": false,
"scrollable": false,
"selected": false
}
可以通过上方信息分别获取元素的所有属性
4.6 XPATH定位
因为Java uiautoamtor中默认是不支持xpath,这是属于ui2的扩展功能,速度会相比其它定位方式慢一些
在xpath定位中,ui2中的description 定位需要替换为content-desc,resourceId 需要替换为resource-id
使用方法
# 只会返回一个元素,如果找不到元素,则会报XPathElementNotFoundError错误
# 如果找到多个元素,默认会返回第0个
d.xpath('//*[@resource-id="com.android.launcher3:id/icon"]')
# 如果返回的元素有多个,需要使用all()方法返回列表
# 使用all方法,当未找到元素时,不会报错,会返回一个空列表
d.xpath(