推荐一款超好用的UI自动化工具: UiAutomator2!
以下文章来源于测试开发技术 ,作者狂师
1、 导读
做过Android自动化测试的同学想必都知道,最开始用的UiAutomator是Google提供的⽤来做安卓⾃动化测试的⼀个Java库,基于Accessibility服务,功能强⼤,但仅⽀持Java语⾔,并原生框架一开始并不⽀持Python。
后面一些Python技术爱好者,实在看不过去了,撸起袖子开发了一款UiAutomator Python版本,项目地址:
https://github.com/xiaocong/uiautomator
安装及基本使用:
$ pip install uiautomator
from uiautomator import device as d
d.screen.on()
d(text="Clock").click()
2、UiAutomator2
当然,今天介绍的主角是另外一框架框:UiAutomator2, 有人说UiAutomator2是不是UiAutomator的升级版本,功能确实是升级,但两个框架其实并没有任何直接关系,甚至根本不是一波人开发的。
UiAutomator2框架是阿里的一位大神杰作。
简单介绍一下:
UiAutomator2是⼀个开源的⾃动化测试⼯具,提供了⼀系列的Python API,⽅便测试⼈员⽤Python编写⾃动化测试脚本。
框架原理图:
项目地址:
https://github.com/openatx/uiautomator2
随着近几年UiAutomator2框架的不断迭代,功能也越发强大了,更多详细功能和介绍建议读者去项目官方地址查阅。
快速开始:
先准备一台开启了开发者选项的安卓手机,连接上电脑,确保执行adb devices可以看到连接上的设备。
安装uiautomator2
pip3 install -U uiautomator2
运行python3 -m uiautomator2 init安装包含httprpc服务的apk到手机.
命令行运行python打开python交互窗口。然后将下面的命令输入到窗口中。
import uiautomator2 as u2
d = u2.connect() # connect to device
print(d.info)
3、UiAutomator2 特色功能
在Android自动化测试过程中,经常会遇到一些非期望需要操作的弹框,一旦出现这些非预期弹框,势必对自动化执行稳定带来影响,今天要重点介绍的就是UIAutomator2中watcher(观察者)的功能,或者称之为监听者模式。
本质上watcher的设计思路主要是为了解决一些弹窗或者 确认框诸如此类问题。
具体watcher又该怎么用?
1、官方示例:
# 常用写法,注册匿名监控
d.watcher.when("安装").click()
# 注册名为ANR的监控,当出现ANR和Force Close时,点击Force Close
d.watcher("ANR").when(xpath="ANR").when("Force Close").click()
2、用法说明:
d.watcher("WATCHER_NAME").when(text="确认").click(text="确认")
d.watcher("WATCHER_NAME2").when(text="OK").when(text="Wait").press("back", "home")
解释:
第一句表示:注册一个名字为“WATCHER_NAME”的watcher,当存在UiSelector满足“text='确认'”的时候,执行点击操作
第二句表示:注册一个名字为“WATCHER_NAME2”的watcher,当满足两个条件时,依次按back与home键。
3、回调示例
d.watcher.when("抢红包").press("back")
d.watcher.when("//*[@text = 'Out of memory']").call(lambda d: d.shell('am force-stop com.im.qq'))
# 回调说明
def click_callback(d: u2.Device):
d.xpath("确定").click() # 在回调中调用不会再次触发watcher
d.xpath("继续").click() # 使用d.xpath检查元素的时候,会触发watcher(目前最多触发5次)
需要注意的是,即便完成watcher注册了,并不代表已经生效,需要手动开启它,有两种方法:
# 方式一:启动所有的观察者,并一直运行在手机后台
d.watchers.watched = True
# 方式二:强制运行所有监控
d.watchers.run()
其他常用Watcher监控命令:
# 移除ANR的监控
d.watcher.remove("ANR")
# 移除所有的监控
d.watcher.remove()
# 开始后台监控
d.watcher.start()
d.watcher.start(2.0) # 默认监控间隔2.0s
# 强制运行所有监控
d.watcher.run()
# 停止监控
d.watcher.stop()
# 停止并移除所有的监控,常用于初始化
d.watcher.reset()
# 查看当前所有watcher
d.watchers
# 判断 某个/所有观察者中的某个 是否已经被触发过
d.watcher("watcher_name").triggered
d.watchers.triggered
当你使用方式一时,在你不想使用它的时候,需要使用d.watchers.watched = False手动关闭;当然,你也可以使用下方的remove方法移除某个watcher,如此它便不会再生效,使用d.watchers.run(),则与方法一不同,它是在这条命令执行的瞬时启动一次,结束后便不会再触发。
4、案例模拟
本案例,假设自动模拟打电话、挂电话操作,如果是使用d.watchers.watched = True,可以先执行脚本,再进行呼叫。
import uiautomator2 as u2
# 连接被叫设备
d = u2.connect('192.168.1.105:62001')
# 注册一个名字为"Phone"的watcher,当存在UiSelector的description="拒绝"时,点击
d.watcher("Phone").when(description="拒绝").click()
# 启动前,查看Phone是否已经注册且触发过
print("Triggered Before:", d.watcher("Phone").triggered)
# 后台启动,持续监控
d.watchers.watched = True
# 查看当前已经注册的watchers
print("Watchers:", d.watchers)
# 启动后,查看Phone是否已经注册且触发过
print("Triggered After:", d.watcher("Phone").triggered)
# 重置watchers的triggered状态
d.watchers.reset()
# 移除Phone这个watcher
d.watcher("Phone").remove()
# 移除后,查看当前已经注册的watchers
print("Watchers:", d.watchers)
也可以将启动方式改成d.watchers.run()如果是使用d.watchers.run(),则需要在电话已经处于呼叫的过程中,触发脚本,具体效果,可自行运行尝试。
好了,时间关系,今天就先分享到这,其他更多优秀功能,读者可自行研究。
作者:狂师
欢迎关注微信公众号 :Python测试社区