转载:https://airtest.doc.io.netease.com/tutorial/0_automated_testing/
9 | 如何生产兼容性强的自动化测试脚本
在阅读本教程前,请确保先阅读我们的5分钟上手教程。
9.1 提纲
通过阅读本小节教程,你将了解以下内容:
- 如何选择Airtest/Poco
- 提高截图脚本的兼容性
- 提升脚本运行速度
- 如何快速验证脚本兼容性
9.2 如何选择Airtest/Poco
在测试脚本中,我们可以同时使用图像脚本(Airtest)和UI脚本(Poco)。相比于图像脚本,UI脚本更加精确、运行速度更快。我们在撰写脚本时,应该如何使用这两种类型的脚本呢?
这与待测应用的类型有关:
1、原生APP:
建议直接使用Poco的UI脚本,在必要的界面判断时用图像脚本。
2、游戏:
已集成Poco-SDK,使用Poco的UI脚本,必要界面使用图像脚本。
暂时无法集成SDK,使用图像脚本。
9.3 如何提升截图脚本兼容性
在测试脚本撰写中,很多同学会发现图像脚本的兼容性很难保证。这里分享一些常用的技巧:
9.3.1 合理调整阈值
在每行图像识别脚本运行的时候,包含三个步骤:① 图像识别的初步识别结果;② 计算结果可信度;③ 通过脚本中的阈值筛选结果。
脚本中的阈值在这里起到结果筛选的作用,阈值的高低将直接影响到返回的识别结果:
阈值过高:可能导致把低可信度的初始结果全部过滤掉,最终没有有效的图像识别结果。
阈值过低:可能导致返回的是错误结果(没有正确识别结果的情况,因为阈值过低使得错误结果得以通过筛选)。我们在提升图像脚本兼容性的时候,最重要的一个部分就是设置合理的阈值。Airtest框架中的默认识别阈值为0.7,我们可以进行适当调整。
(1)调整阈值:使用“图像编辑器”调整单行脚本阈值
我们一般使用“图片编辑器”修改阈值。在脚本框中双击图片打开“图片编辑器”,我们可以实时调节右侧的threshold阈值数值,并点击Snapshot + Recognition按钮来实时验证识别结果。识别结果的可信度会直接呈现在下方状态栏上,可信度大于阈值时才会返回识别结果:
注意: 建议阈值设定在[0.6, 0.9]之间,避免阈值过低混入错误结果、或者阈值过高导致经常找不到结果。
(2)调整阈值:设置脚本的全局阈值
如果我们想直接为整个测试脚本的图像脚本设置阈值,则可以在脚本开头时进行全局阈值的设置:
# 全局阈值的范围为[0, 1]
from airtest.core.setting import Settings as ST
ST.THRESHOLD_STRICT = 0.7 # assert_exists语句的默认阈值,一般比THRESHOLD更高一些
ST.THRESHOLD = 0.7 # 其它语句的默认阈值
9.3.2 截图技巧
(1)特征点要多!
例如对于这样子的界面:
我需要点击中间第二个【安装】按钮。如果直接截图“安装”可能根本点击不到,或者点击到错误的按钮。
截取拥有更多特征的图片,返回的结果则会是正确的,如下图所示。
(2)设置点击位置traget_pos
这里设置点击位置,其实依然是为了在截取特征点多的时候能够点击到正确位置。比如对于类似于弹窗型的截图,需要点击关闭按钮:
如果仅仅截图下图中的关闭图标,图像识别的成功率是不高的。
但是我们截图整个窗口,并且双击图片设置traget_pos=2,如此识别成功率相对高很多。截图如下:
具体target_pos设置可以参考我们的文档:图像点击位置target_pos(整型)
9.3.3 自定义语句提高图像脚本兼容性
对于设备长宽比不同、设备分辨率不同、多种字体的情况,我们可以通过语法来提高兼容性。这种方式需要连接上脚本兼容性有问题的设备,把对应截图纳入搜索列表。代码脚本如下:
picList = [pic1,pic2,pic3] # 截图的图片对象列表
for pic in picList:
pos = exists(pic)
if pos:
touch(pos)
break # 只要找到图片列表中的任何一张图片,就执行touch
注意:如果for循环中没有break语句,会导致次逻辑运行时将所有的图片都找一遍(找到后执行touch),而非找到合适结果立即返回。
9.4 部分场景下的便捷操作
在部分场景下,通过一些替代性操作(比如直接操作坐标、使用按钮指令、记忆元素位置等),可以省去对图像识别的兼容性调试,甚至可以加快脚本执行速度。
9.4.1 操作坐标
(1)操作坐标案例一:过场动画
比如过场动画会很慢,我们可以选择跳过,这时就可以使用坐标进行设备操作。如下图的游戏过场动画:
# perform a simple click
touch([10, 10])
(2)操作坐标案例二:App介绍页
在考拉APP打开后,有4个介绍页滑动后才能进去。如果通过Airtest/Poco的UI测试语句,需要运行半天。而通过直接使用固定坐标位置滑动,执行四下即可。要注意的是,这里坐标脚本的连续运行操作得太快,设备甚至有可能会反应不过来,一般每行语句后面需要加一下sleep(1.0),等待一下设备响应。
如果这种情形非常多,可以封装成通用的函数,用到的时候调用一下即可。 省代码+快速~
# get the device width & height
width, height = device().get_current_resolution()
# cal swipe (start/end) point coordinate
start_pt = (width * 0.9, height / 2)
end_pt = (width * 0.1, height / 2)
# swipe for 5 times:
for i in range(5):
swipe(start_pt, end_pt)
sleep(1) # wait for the device's response
9.4.2 使用手机按键指令
很多情况下,BACK按钮可以进行灵活使用。经常在点开一个页面,想返回上一个页面时,可以选择按UI按钮,但是一般KeyEvent(“BACK”)也可以达到目的,简单直接-兼容性又好。
9.4.3 位置记忆
还有一些特殊的情形,比如炉石中,敌我双方的英雄位置是固定的,每次攻击敌方英雄的时候都需要用到这个位置。 可以考虑全局保存位置,之后需要使用的时候直接调用对应位置就行了。
上图中需要注意的是,需要使用wait语句来等待获取到英雄位置,而不是exists。因为这里一定是需要拿到对应英雄的位置,需要等待其出现(不出现直接触发报错),而exists语句如果没有英雄出现不会报错。
上图中,需要随时使用随从攻击对方英雄时,直接将随从图片swipe至地方英雄的位置就可以了。
9.5 借助多设备运行功能验证脚本的兼容性
通过我们的新功能——多脚本多设备插件,来验证脚本的兼容性。通过同一个测试脚本同时在多台不同分辨率的设备上实际运行,以确保脚本的兼容性。