会员登录|免费注册|忘记密码|管理入口 返回主站||保存桌面
AirTest 基本使用及框架浅剖析——五分钟上手制作游戏辅助手机h游戏「AirTest 基本使用及框架浅剖析——五分钟上手制作游戏辅助」
2025-02-20IP属地 湖北3

Airtest Project 是为编写自动化脚本,达到提升测试效率的一整套解决方案。它可以轻松的扩展到多平台、多引擎上;如基础的 Android和IOS手机应用、App;Windows上的应用等。

学习使用 Airtest Project 很容易,由于 Airtest Project 是基于Python的,只需要会一点基础的 Python 基础知识即可。Airtest Project 需要一个开发环境,推荐使用配套的 AirtestIDE;AirtestIDE针对于 Airtest Project 有一些特殊的功能,使用别的环境可能会让你开发时工作繁琐,效率降低等。

Airtest Project 包含了两个框架,一个是 Airtest 一个是 Poco,这两个框架都是Python 的第三方库。在开发过程中,可以在开发时引入其它库加强你的脚本。

Airtest
是一个跨平台的、基于图像识别的UI自动化测试框架,适用于游戏和App,支持平台有Windows、Android和iOS——引于官方文档

Airtest 可实现“即看见可操作”,但是对文本内容的获取缺无能为力;这一点在官方文档中也有说明。这一点缺点也有解决办法:可通过引入文字识别库进行补缺,如:pytesseract。

使用 Airtest 进行自动化测试时,操作流程一般为:图片截取 → 图片对比 → 相似度与设定值对比 → 找出坐标位置 → 点击。默认情况下 Airtest 对于不同颜色的对比并不敏感,需要开启颜色对比。

在测试对象非原生App或无法取得项目源码时使用 Airtest 进行测试是个很好的选择。

Poco
是一款基于UI控件识别的自动化测试框架,目前支持Unity3D/cocos2dx-*/Android原生app/iOS原生app/微信小程序,也可以在其他引擎中自行接入poco-sdk来使用——引于官方文档

在已有项目源码或测试对象为原生App时使用Poco进行自动化测试,不仅满足可对文本的获取,而且相比 Airtest 更为简洁!本篇只讲解 Airtest 的操作。

AirtestIDE
是一个我们配套推出的跨平台的UI自动化测试编辑器,内置了Airtest和Poco的相关插件功能,能够使用它快速简单地编写脚本——引于官方文档

使用 AirtestIDE 将极大的简便我们的开发过程,对开发者非常友好。提供了截图及截图预览、可连接设备自动读取、高亮的编辑界面、脚本录制、支持设备远程连接并且在嵌入设备对象窗口实时刷新。

安装 AirtestIDE 后,打开 AirtestIDE ,打开模拟器中需要测试的App。
AirtestIDE 的设备窗口默认在可是界面的最右边。
在这里插入图片描述
在 AirtestIDE 中,界面元素可以拖拽,布置成你所喜爱的界面风格。假设一些窗口无意中关闭,可在窗口下拉选项中打开窗口。
在这里插入图片描述

连接设备只需要在移动设备的窗口下列表点击出现的设备信息中的connect,即可连接。
在这里插入图片描述
假设设备列表并未出现设备,点击刷新
在这里插入图片描述
如果是使用真机设备请使用USB线连接手机,并且允许USB调试,之后刷新ADB。
远程连接需要只是IP及端口号,填入字段点击连接即可。
更多链接本文不再赘述。可查看官方文档

我当前使用的设备为模拟器设备,模拟器连接过程直接在出现的设备列中点击connect即可
在这里插入图片描述

在 Airtest 开发中是以“.air”作为文件后缀。
连接设备后,查看代码

 

其中 将Airtest的基本API引入,为之后编写做好准备。
查看可视窗口最左侧,有Airtest辅助窗与Poco辅助窗,本篇主要讲解Airtest。
在这里插入图片描述
首先尝试第一个操作touch,touch中文译为“触摸”,从命名上得知,这是个可实现“触碰”功能的操作。首先鼠标悬浮在 touch 选项处
在这里插入图片描述
将会提示 touch 功能的相关信息,现在简单的尝试一下 touch 功能。
点击 touch ,把鼠标移动到设备窗,找到你想要实现点击的按钮,点下左键不放,进行拖拽选中,随后放手。
在这里插入图片描述
这时,代码编辑区将会出现 ,点击运行脚本,尝试使用
在这里插入图片描述
运行效果如下
在这里插入图片描述
从效果中可以看到 touch 将会找到与我们所选中的图形相似的图案,进行计算匹配,达到匹配的要求后,进行点击操作。

现在查看一下 touch 函数的实现,从中得到更多的信息,帮助我们进行脚本的开发;点击文件名,然后选择“打开当前文件项目目录”
在这里插入图片描述
找到当前文件目录后,找到与文件名相同的 .air 文件,使用编辑器进行打开。
以下为编辑器打开该该文件后的代码

 

在不经过 AirtestIDE 处理的代码中,图片的表现形式为路径,以及使用了 Template 作为处理,此处,Template 函数接收3个函数,分别为:图片路径 ecord_pos以及resolution。

在 Airtest api 文档中查询 Template 方法。

在这里插入图片描述
查看文档的值,刚刚使用的Template将会直接使用参数初始化一个类。

其中参数查看文档得知

  • filename:文件路径
  • threshold:图像识别阈值,是用来判定一张图片识别是否成功的阈值,例如一张图片识别到的匹配度是0.65,而我们设置的threshold为0.7的话,Airtest会认为匹配失败,从而进行下一次匹配。
  • target_pos:图像点击位置,当识别出一张图像后,Airtest将会默认去点击图像的正中心位置,有时我们希望它识别出图片后点击其他位置,可以通过修改target_pos属性来实现。
  • rgb:切换彩色与灰度识别,在识别图像时,Airtest会先将图像转为灰度图再进行识别。因此假如有两个按钮,形状内容相同,只有颜色不同的情况下,Airtest将认为它们都是相同内容。
    通过勾选rgb选项,或在代码中加入rgb=True,可以强制指定使用彩色图像进行识别。
    其中参数,还差 record_pos 与 resolution;以下为Template类,查看文档得知
  • resolution:录制时的屏幕分辨率
  • record_pos:录制时屏幕上的坐标
 

通过以上分析的值,在代码

 

其中 resolution 为当前设备的分辨率为:540, 960;可是这和我设置的分辨率不一样,查看文档得知“在使用不同分辨率的设备进行图像识别时,可能会导致识别成功率不佳,因此Airtest提供了默认的分辨率适配规则”。从中也得到了些许信息,如“使用缩放后是否不精确?”,当然,文档也给出了解决方案:“想要提高2d游戏的识别精度,最好的办法就是明确指定你的游戏的分辨率适配规则;下面的代码指定了一个自定义的缩放规则:直接return原来的值,不管屏幕分辨率,所有UI都不进行缩放。
代码如下

 

这里的RESIZE_METHOD,即我们定义的custom_resize_method使用的输入参数为

  • w, h # 录制下来的UI图片的宽高
  • sch_resolution # 录制时的屏幕分辨率
  • src_resolution # 回放时的屏幕分辨率

以上分析得知,通过Template示例后一个对象,作为参数传给touch方法,那么touch方法应该进行剩下的图片查找及触摸操作;继续分析touch方法。

以下在文档中找到touch方法
在这里插入图片描述
文档中说明,touch方法为在设备屏幕上执行触摸操作。参数有

  • 一个目标,这个目标可以是 Template 的实例或者是一个坐标
  • 执行多少次点击
  • 按照平台的不同所需的不同参数
  • 最终返回位点击的坐标
  • 适用平台为 Android, 、Windows 、iOS

点击源代码查看实现

 

经过之前的分析,得知 touch 将会执行查找图片和点击的操作;从实现中得知
传入参数后,首先判断传入的对象 v 是否属于 Template对象,是这个对象,执行 loop_find方法,传入对象,设置超时为 ST.FIND_TIMEOUT,然后把查找得到的坐标给予 pos 变量。

之后使用循环实现点击,循环1次点击1次,循环2次点击2次,以此类推,调用G.DEVICE.touch 方法,传入 pos 及 kwargs 进行点击。
查看 G 类具体实现,G在helper中,查看helper

 

其实在这里,已经注册过了设备,默认的编辑窗口已经隐藏了这个过程,我们点击新建文件可以看到 auto_steup(),该方法实现在 airtest.core.api 中,其中auto_steup()方法定义如下

 

其中所需的 import_device_cls 方法在 airtest.core.helper中

 

很清楚的看到,在 auto_setup 中有层级的调用了connect_device进行设备连接初始化,在connect_device中调用import_device_cls添加设备,随后使新设备在G类中赋值给G.DEVICE,最后传给G.DEVICE_LIST。

在这里出现了 DEVICE_LIST 给对多设备操作的方式有了可能性,当然 Airtest Project 本就是这么一个解决方案。在文档中就有多机协作的介绍。以下文字引于文档。

在我们的脚本中,支持通过 set_current
接口来切换当前连接的手机,因此我们一个脚本中,是能够调用多台手机,编写出一些复杂的多机交互脚本的。

在命令行运行脚本时,只需要将手机依次使用 --device Android:/// 添加到命令行中即可,例如:

 

当然多设备并行的方案现在也有很多之后补充。

最终,调用 airtest.core.android.android 中 touch 完成点击
在这里插入图片描述
实现如下

 

以上就是简单的一个 touch 完成的所实现的过程。

我们现在就来尝试开启颜色识别以及阀值设置
增加 if 判断,判断是否存在图片,存在则点击,并且提高阀值以及开启颜色识别

双击图片进行更改值
在这里插入图片描述

去代码查看是否改动

 

最后优化一下,根据流程编写了如下脚本
在这里插入图片描述
其中程序代码为

 

运行结果如下
在这里插入图片描述
以上脚本使用了 exists 断言,判断图片是否存在,存在返回 pos 坐标点,不存在返回False
在这里插入图片描述
使用 exist 判断可以当做为脚本逻辑的一个分支,存在,则执行之后的操作,不存在。在使用 exist 时使用if,在同级下,多个if可以有效的让所有情况出现不交叉的分支,使脚本代码结构清晰是个不错的选择

以上脚本还存在一个小尾巴,那就是在结尾处点击训练后,自动返回主目录。修改如下
在这里插入图片描述

为了时脚本保持健壮性,我在点击训练意外情况找不到时,用了else语句,使其返回。
为了更好的深入理解脚本,我们查看一下 exists 的实现;exists 的实现在 airtest.core.api 中

 

exists 将会在屏幕中查找目标,如果找到将会返回坐标值。
在这里我们已经是第二次看见 loop_find 方法,此方法是 Airtest 的核心方法。loop_find 方法实现于 airtest.core.cv :

 

文档 对于 loop_find 有些接口介绍
在这里插入图片描述
query:截图对象
timeout:超时
threshold:阀值,也就是对比后的相似度的值,越大越难匹配,要求精度越高
interval:匹配相距时间
intervalfunc:失败后的响应

在执行 loop_find 时首先给个计时器计时,获取屏幕后验证屏幕是否为None,为None可能没连接上;屏幕获取无异常则,使用截图对象调用 match_in 方法,成功进行匹配返回坐标值,否则返回False。

其中主要方法为 match_in ,match_in 也在 airtest.core.cv : 中,定义如下

 

_cv_match 如下

 

其中在 match_in 中调用了 _cv_match,_cv_match 首先对图片 _imread() 进行CV2 处理,然后后面对图片进行压缩,应该是通过文档中所说的通过COSCOS的规则。然后根据一个策略遍历里面的算法进行计算,最后得到 ret 返回计算结果。(在深度就不会了,毕竟我不是搞测试的,点到为止

Airtest 的核心浅显流程搞清楚了,我们得知,在进行 touch 及 exists 时都会进行 loop_find 合理的调整查询阀值和RGB开启可以有效的节省匹配时间。优化脚本,合理的把部分图片的RGB关闭以及部分图片阀值减小以提升脚本运行效率。
修改后脚本如下(修改了2个按钮,降低了阀值及关闭了RGB

 

运行结果(没有加倍数,确实快了很多
在这里插入图片描述
使用循环让程序一直挂机吧
修改程序如下

在这里插入图片描述
结果发现在程序正常运行后,逻辑出现错误,运行结果如下
在这里插入图片描述
这时需要修改程序,把头盔的判断增加else分支,改为
在这里插入图片描述
结果再次运行发现训练过后,第二次训练时间变成等待时间
在这里插入图片描述
改为先判断后点击,头盔也是
在这里插入图片描述

这次就很完美了
在这里插入图片描述
那我再按照游戏左下角提示操作去完成另外的逻辑,一共2个分支在运行判断
在这里插入图片描述
运行如下在这里插入图片描述
可能某些情况需要拖拽屏幕,这个使用需要使用
在这里插入图片描述
使用 swipe 推荐对于坐标系不熟的使用录制脚本功能编写,通过这个功能,可以快速的写好脚本
在这里插入图片描述
点击后,进入录制脚本状态,这个时候直接在屏幕上进行拖拽即可,记得幅度不要过大,不然在运行时导致滑动过多。