目录
一、poco介绍
1、poco能做什么
2、三种定位方式
1)基本选择器
2)相对选择器
3)空间顺序选择器
4)正则表达式方式
3、poco支持平台
二、Airtest介绍
1、Airtest能做什么
2、Airtest不能做什么
3、Airtest的图像识别算法介绍
1)算法简介
2)修改Airtest使用的图像识别算法:
3)如何提高图像脚本的兼容性
一、poco介绍
1、poco能做什么
Poco可以获取控件的属性信息、操作控件、设置控件的text属性等等,但是连接设备、断言等操作,还需要依赖于Airtest的API,所以我们大多数情况下,都需要混合使用Airtest和Poco框架来编写我们的自动化脚本。
poco官方文档:https://poco.readthedocs.io/zh_CN/latest/source/README.html#
https://airtest.doc.io.netease.com/IDEdocs/poco_framework/1_poco_info/
Poco api :poco.pocofw module ‒ poco 1.0 文档
安装poco :
pip install pocoui
2、三种定位方式
Poco控件最基本的3种定位选择器分别是:
- 基本选择器
- 相对选择器
- 空间顺序选择器
1)基本选择器
用节点的属性和属性值去定位元素。
# 第一个参数是 name,可以省略对应的key
poco("star_single",type="Image")
2)相对选择器
通过元素之间的渲染层级关系进行选择,例如父子关系、兄弟关系、祖先后代关系等等。
poco("plays").child("playBasic").offspring("star_single")
- 子节点:
child
- 所有子节点:
children
- 子孙节点:
offspring
- 父节点:
parent
- 兄弟节点:
sibling
3)空间顺序选择器
利用索引顺序选中单个元素。
name0 = poco("Content").child(type="Text")[0].get_name()
name1 = poco("Content").child(type="Text")[1].get_name()
name2 = poco("Content").child(type="Text")[2].get_name()
4)正则表达式方式
上面是淘宝APP的icon控件,利用基本选择器,可以使用类似 poco(text="手机淘宝")
这样的方式来定位到这个淘宝的icon控件。
换成正则表达式来匹配这个控件的话,可以使用如下方式来进行匹配:
poco(textMatches="能匹配到手机淘宝的正则表达式")
例如 .*淘宝
,这个就是能匹配到“手机淘宝”的1个正则表达式,所以点击手机淘宝icon控件的语句可以写成如下的形式:
poco(textMatches=".*淘宝").click()
同理可以使用 nameMatches
来匹配控件的name属性:
利用基本选择器定位图中控件,定位脚本如下:
poco(name="com.netease.cloudmusic:id/portalTitle",text="每日推荐")
而换成正则表达式的匹配方式,则可以这么实现:
poco(nameMatches=".*portalTitle",textMatches=".*推荐")
PS:在编写层次特别深的一些定位脚本时,使用正则表达式来匹配,会非常简洁高效:
如果使用之前介绍的定位方式,脚本可能如下:
for i in poco("com.netease.cloudmusic:id/pagerListview").child("com.netease.cloudmusic:id/musicListItemContainer"):
info = i.child("com.netease.cloudmusic:id/songNameAndInfoArea").offspring("com.netease.cloudmusic:id/songInfo")
print(info.get_text())
利用基本选择器和相对选择器写出来的定位脚本,看起来非常繁琐,而且还需要非常 精确地了解其中的层级关系 ,否则定位脚本就很容易出错。
换成正则表达式的定位方式:仔细观察UI树发现,这些歌曲信息的控件名都是一样的,所以只要写1个正则表达式,匹配到这一批相同的控件名,就相当于定位到了当前页面所有的歌曲信息控件,接下来就可以利用poco遍历,逐一获取控件的text属性了:
for i in poco(nameMatches="com.*?songInfo"):
print(i.get_text())
不推荐的poco定位方式
通常不推荐使用相对选择器和控件顺序选择器进行定位,因为复杂的层级关系加上空间索引顺序,很容易出现运行效率差,或者因为索引值变化而导致出现找不到控件的问题。
除非是必要情况,一般不要选择这种定位方式。
推荐的poco定位方式
非常推荐多使用基本选择器和正则匹配表达式来定位控件
3、poco支持平台
Poco在大多数平台中,需要 事先接入Poco-SDK才可正常使用 ,在少数平台(如Android原生APP、iOS原生APP)可直接使用Poco,目前支持平台如下:
二、Airtest介绍
Airtest是一款跨平台的UI自动化测试框架,基于 图像识别原理 。本质上是Python的一个第三方库 。
官方文档:https://airtest.readthedocs.io/zh_CN/latest/
pip安装:
pip install airtest -i https://mirrors.aliyun.com/pypi/simple/
- Airtest支持的Python版本: 3.0≤Python≤3.9
1、Airtest能做什么
- 连接上待测设备
- 对待测设备实施模拟操作
点击、滑动、截图、输入文本、等待、断言。。。。
- 生成运行报告
Airtest支持生成HTML格式的测试报告,方便查看详细的步骤运行情况。
2、Airtest不能做什么
- Airtest能做接口测试吗?
不能,Airtest是一个UI测试框架,与接口测试框架不一样。
- Airtest能进行找色吗?
不能,Airtest基于各种图像识别原理,与找色工具有一定差别,目前Airtest不包含找色功能。
- Airtest能获取图片的文字吗?
不能,Airtest非OCR工具,不能识别出来图片里面是什么文字,它只能对比图片之前的匹配度。但我们可以通过Airtest截图,然后借助其它OCR接口来识别截图里面的文字。
- Airtest能拿到控件的图片吗?
不能,Airtest非侵入式框架,它不能直接拿到应用里面的控件图片,但是它能对整个画面进行截图或者进行局部截图。
3、Airtest的图像识别算法介绍
1)算法简介
在airtest框架中集成了不同种类的图像识别算法。其中包括模板匹配(也就是上文的TemplateMatching
)、以及基于特征点的图像识别方法(包含了上文的SURFMatching
和BRISKMatching
)。这两种识别方法的特点和区别如下:
模板匹配
无法跨分辨率识别
一定有相对最佳的匹配结果
方法名:"tpl"
特征点匹配
跨分辨率识别
不一定有匹配结果
方法名列表:["kaze", "brisk", "akaze", "orb", "sift", "surf", "brief"]
- 2篇推文:
https://mp.weixin.qq.com/s?__biz=MzUxMDc4NTkwMA==&mid=2247484068&idx=1&sn=8037c1ddec46ec26f2a8eff8b2252d2d&chksm=f97ce2a7ce0b6bb1512451367dceb85eca1073050fb9c3ce06503ebc9db8f10c2f8efc0d1506&token=1051694015&lang=zh_CN#rd
https://mp.weixin.qq.com/s?__biz=MzUxMDc4NTkwMA==&mid=2247486213&idx=1&sn=f0effedd8dcff9aa9e5950debcbceaf4&chksm=f97ceb06ce0b621082049db44ef0e3f4265ae7f7137c4d1a466313d9e3ff65d8e2b5f9a90dcd&token=1051694015&lang=zh_CN#rd
2)修改Airtest使用的图像识别算法:
from airtest.core.settings import Settings as ST
# 调整Airtest图像识别算法的使用顺序
ST.CVSTRATEGY = ["mstpl","tpl", "sift","brisk"]
# 指定仅使用mstpl算法
ST.CVSTRATEGY = ["mstpl"]
3)如何提高图像脚本的兼容性
- 截取图标时尽量不要截入过多的背景内容
如下图,选择第一种截图,而不是混入了过多背景的第二种截图:
- 尽量减少截取纯文字的图像
Airtest图像识别使用的算法 更适合用来识别按钮类(带边框)、图标类的图像 ,仅仅单独截取几个文字容易导致识别成功率较低,尽量调整图片截取内容来达到较好的识别效果,避免截取识别效果较差的内容。
- 合理调整阙值
举个例子,某个截图默认阙值为0.7,但是多次运行之后发现,有一定概率会识别到错误结果。这时候不妨将阙值调高一点试试,看看能不能提高正确识别的概率,如果可以,说明阙值调整是有效的。
修改Template的参数threshold:
touch(Template(r"tpl1598952570968.png", threshold=0.8, record_pos=(-0.021, 0.121), resolution=(900.0, 1600.0)))
设置全局的threshold(只适用于除断言语句之外的截图语句):
from airtest.core.setting import Settings as ST
ST.THRESHOLD = 0.7 # 其他语句的默认阈值
断言语句的阙值设置
from airtest.core.setting import Settings as ST
ST.THRESHOLD_STRICT = 0.7
在断言语句的截图中,双击进入图片编辑器,再修改里面的 threshold
,最终也是不会生效的,只能通过上述方式设置。
- 开启RGB彩色识别
在识别图像时,Airtest会先将图像转为灰度图再进行识别。因此假如有两个按钮,形状内容相同,只有颜色不同的情况下,Airtest将认为它们都是相同内容。如下图,如果仅截图第二个红色的【删除】按钮,Airtest会把另外俩个灰黑色的【删除】按钮认为是相同的。
通过勾选rgb选项(双击图片打开图片管理器勾选),或在代码中加入rgb=True,可以强制指定使用彩色图像进行识别。这样就能比较好地识别出那个红色的【删除】按钮了。
touch(Template(r"tpl1637052349130.png", rgb=True, record_pos=(-0.38, -0.11), resolution=(850, 909)))
- 巧用target_pos点击截图的不同位置
修改target_pos 参数:
touch(Template(r"tpl1598948415043.png", target_pos=6, record_pos=(-0.434, -0.773), resolution=(900, 1600)))
例如,我们的需求是点击中间那个按钮的,仅仅依靠截1个播放按钮来做识别,是很难保证具体识别到三个按钮中的具体哪个按钮的。
此时可以有2种截图方式来实现:
一种是在竖着的方向上,扩大截图范围,让中间那个按钮处于 target_pos=5
的位置上:
另一种是在横着的方向上,扩大截图范围把左侧的歌曲介绍也一起截图了,让中间那个按钮处于 target_pos=6
的位置上:
这2种方式都可以确保点到的是中间那个按钮(假设列表歌曲不变的情况下)。
所以,当精准截图(仅截取某个按钮/图标)不能满足唯一定位时,可以考虑加大截图范围,增加更多的特征点,确保截图定位的准确性。
- 切勿过度依赖录制功能
- 指定游戏的分辨率适配规则
- 自定义语句提高图像脚本兼容性
- 巧用坐标进行点击/滑动
- 巧用keyevent("BACK")替代返回的截图脚本
- 画面切换的时候,可以多使用wait或者sleep,再进行点击操作
- 打开应用尽量使用start_app而不是截图脚本
- 如果可以用poco框架,还可以用poco语句代替截图脚本