1
浅尝UI自动化之Airtest实践
背景
由于很多公司都采用敏捷开发的模式,测试也要跟着进行敏捷测试。而每个迭代的周期非常短,经常要对原有功能进行回归测试,这样就增加了大量重复人力成本。
引入UI自动化测试可以用来快速回归测试App原有功能,测试人员只需要关注新功能的测试。
其次,移动端App的测试用例大部分是功能验证相关的用例,通过UI操作即可验证,这就为UI自动化提供了便利条件。
因此,可以将测试重复度高,执行效率低的用例,通过UI自动化快速重复执行,达到提高测试效率的目的。
01
Airtest简介
目前主流的UI自动化测试工具主要有:Selenium, Appium和Airtest。
其中Selenium是一款开源的Web应用自动化测试工具,它可以直接运行在多种浏览器平台,其支持的浏览器几乎涵盖了所有主流的浏览器,但是由于得物是App,不需要web端的测试,故这个工具被残忍舍弃。
而Appium和AirTest都是针对App的自动化测试工具,都可以进行自动化测试脚本的录制和回放。但是之所以选择了AirTest最主要的原因是他很容易生成测试脚本,即使测试人员不会编程,不懂脚本,也可以通过正常用户的点击拖拽等操作,自动完成脚本的录制,从而大幅度降低自动化维护成本。
经过亲身实践,从UI自动化小白到第一个自动化测试脚本成功运行,用了半天时间,感兴趣的同学可以尝试一下。
AirtestIDE 是一个跨平台的UI自动化测试编辑器,适用于游戏和App。
它的特点如下:
- 自动化脚本录制、一键回放、报告查看,轻而易举实现自动化测试流程支持。
- 基于图像识别的 Airtest 框架,适用于所有Android和Windows游戏支持。
- 基于UI控件搜索的 Poco 框架,适用于Unity3d,Cocos2d与Android App。
- 能够运行在Windows和MacOS上。
架构图
可以看到,底层的主要测试框架是AirTest和Poco,二者区别在于:
-
AirTest:基于Python的、跨平台的UI自动化测试框架,基于图像识别原理,适用于游戏和App。
-
Poco:基于UI控件搜索的自动化测试框架,其核心优势是除了对Android 和IOS之外,对游戏也是支持的,同时也支持微信小程序、微信小游戏和H5应用。
02
Airtset安装和连接设备
目前AirTestIDE提供了Windows和Mac两个版本的客户端,请从官网(http://airtest.netease.com/changelog.html)下载,解压即用。
无论是Android/IOS手机,还是Windows窗口,在AirTest中都将它视为一个设备。下边重点介绍一下Android设备的连接。
连接Android手机
通过ADB连接电脑和Android手机,ADB是Google官方提供的Android调试工具,AirTestIDE依赖ADB与安卓设备进行通信。
打开AirTestIDE,按照以下步骤进行连接:
- 打开手机设置-开发者选项-USB调试开关,参考安卓官方文档;
- 在AirTestIDE设备面板中点击 refresh ADB 按钮,查看连接上的设备;
- 如果没有显示出设备,试试restart ADB,如果还不行,参考FAQ文档进行问题排查。
- 能够成功看到设备后,点击对应设备的connect 按钮,进行初始化。
连接成功后,即可在AirTestIDE中看到手机屏幕的镜像显示,并进行实时操作,如下图所示:
连接IOS手机
要连接一台IOS手机,你需要准备好一台安装了Xcode的MAC电脑,连接方式参考文档(https://airtest.doc.io.netease.com/)。
03
录制自动化脚本
在连接上设备以后,就可以开始录制自动化测试脚本了,在接下来的内容中,我将会在一台Android手机上,给大家演示如何录制脚本。
模拟输入
AirTest支持通过图像识别的方式,找到你想要的位置并进行操作,这是基于AirTest框架实现的。
我们可以先看看如何自动录制脚本:点击AirTestIDE左侧的AirTest辅助窗上的“录制”按钮,然后随着你在设备窗口上操作手机,代码会自动生成在代码窗口中。
录制完成后,点击“运行”,就可以运行你的第一个自动化脚本了。
如果你觉得自动录制生成的图标不够准确,还可以点击AirTest辅助窗上的 touch 按钮,然后再设备窗口上框选精确的图标,也可以制动生成一条touch语句。
如下图:
点击边框调出视频工具条
得物技术
类似的模拟输入操作还有滑动:点击swipe按钮,在设备窗口上框选精确的图标最为滑动起点,然后点击滑动终点位置,即会自动生成一个swipe语句。
其他的模拟输入的API包括:
- Text:文字输入
- KeyEvent:按键输入,包括(HOME/BACK/MENU等)
- Sleep:等待
- Snapshot:截屏
断言
减少三个block的script的加载。到这里,我们已经有各种模拟输入方法,配合逻辑控制语句让手机动起来。
自动化测试中还有很重要的一个步骤:结果验证。
我们就可以来看看怎样声明断言。
(1)验证UI界面
录制方法与模拟输入类似。
- assert_exists:断言图片存在
- assert_not_exists:断言图片不存在
(2)验证数值
通过Poco获取属性值,手写代码进行断言。
- assert_equal:断言箱单
- assert_not_equal:断言不等
例如:
查看测试报告
脚本运行完毕后,点击“查看报告”那妞,会使用默认浏览器打开结果报告页面,报告中将展示每一个步骤的内容和实际执行过程的截图、运行结果,方便查看步骤是否执行成功。
04
AirTest脚本介绍
AirTest是一款基于Python的,跨平台的UI自动化测试框架,基于图像识别原理,适用于游戏和App。
虽然可以借助IDE提供的录制功能快速的生成脚本,但是通常来说,熟练掌握Python语法能够帮助我们写出应用更广泛、更不容易出错的脚本。
一 个简单的.air脚本解析
在下载解压Airtest脚本的专属IDE——AirtestIDE后,点击“新建脚本”按钮,默认即可创建一个后缀名为.air的脚本文件,.air这是Airtest脚本的专属后缀。
让我们打开刚才新建脚本的文件夹,可以看到实际上.air脚本文件是一个普通的文件夹,里面附带了一个同名的.py文件,AirtestIDE在执行脚本时,实际上执行的是里面的.py文件。也就是说,Airtest脚本本质上仍是Python脚本,遵循的是Python语法,我们可以根据实际需要自由地import其它Python第三方库。
值得注意的是,.air文件夹中必须要有同名的.py文件,否则在命令行执行airtest run test.air这样的运行指令时会导致失败。
AirTest脚本示例
初始化环境
首先,就像一个普通的Python脚本一样,我们需要在代码文件的最开头部分,写上from airtest.core.api import *,将AirTest 的主要API都import进来,以便在后续脚本中使用这些API。
auto_setup是一用来初始化环境的接口,接口文档在这里(https://airtest.readthedocs.io/zh\_CN/latest/all\_module/airtest.core.api.html#airtest.core.api.auto\_setup),它接受4个参数,我们可以设置当前脚本所在的路径、指定运行脚本的设备、设置默认的log路径和设置脚本父路径。
-
如果auto_setup不传入任何参数,AirTest将会读取运行时命令行中传入的各项参数,来对环境进行初始化。
-
在AirTestIDE创建脚本时,默认生成的代码里是最简单的初始化代码auto_setup(__file__),意思是将脚本文件作为脚本路径传入,其他参数内容将默认读取运行命令行传入的参数。
脚本运行命令行有两种形式,命令行中的参数包含device,log等:
- 命令行运行AirTest脚本的示例:>airtest run untitled.air --device Android:///手机设备号 --log log。
- 在使用AirTestIDE运行脚本时,会在"Log 查看窗"中自动生成一个可用的命令行,可以供大家作为参考。
模拟点击
Airtest作为自动化测试框架,模拟的是人的操作,常见的接口主要有:
- Touch点击某个位置,可以设定被点击的位置、次数、按住时长参数
- Swipe从一个位置华东到另一个位置
- Text调用输入法输入指定内容
- KeyEvent输入某个按键响应,礼盒回车键、删除键
- Wait等待某个指定的图片元素出现
- Snapshot对当前画面截一张图
- 其他
在很多接口中,支持传入Template图片对象作为参数,在运行时将会去点击图片在画面中的所在位置,类似这样:
其中,Template对象是一个图片类,AirTest会先尝试在当前画面中找到匹配这张图片的位置,如果找到了,将对这个坐标进行点击操作,如果找不到,就抛出识别异常。
断言语句
断言在单元测试代码中非常重要,因此建议在我们的脚本里使用断言语句来判定被测应用当前的涨停是否是我们预期中的状态。
Airtest提供了assert_exists和assert_not_exists两个接口,来断言一张图片存在或者不存在于当前画面中。同时,还提供了assert_equal和assert_not_equal两个语句,来断言传入的两个值相等或者不相等。
如何在Python脚本中使用AirTest
AirTestIDE在创建新脚本时,也能够直接创建一个.py脚本文件,但是在创建之前会弹出一个设置窗口,要求填写一些指定的参数。
在我们了解过auto_setup接口后就会知道,这些参数就是为了传给它,然后初始化AirTest运行环境使用的。因此,一个纯.py脚本的初始化代码可以是这样的:
上边这段代码的意思是说,当使用python xxx.py来运行本文件,且不带任何命令行参数是,则自动使用auto_setup这个接口来对AirTest相关的参数进行初始化。这样只需要在写py脚本时,填好指定的参数就能直接用python xxx.py指令来运行脚本。
同时,原先传统的airtest run xxx.air --devices Android: /// 命令行方式也不受影响,只要脚本检测到传入了命令行参数(即代码中的 if not cli_setup()判断),就依然优先使用命令行参数来初始化AirTest环境。
当然,熟练掌握API的各位,也可以根据实际需求在自己的Python脚本中调用AirTest API,与使用正常的pyhton第三方库方法相同。
05
总结
本文只是简单讲解了如何使用AirTest进行UI自动化脚本的录制和回放,以及对自动化脚本进行了介绍。如果要进行UI自动化的持续集成,还需要进一步的了解和学习。
希望有时间的同学可以进行一些实践,了解一下UI自动化相关的知识。在以后的工作中,我们就可以将测试重复度高,执行效率低的用例,通过UI自动化快速重复执行,以达到提高测试效率的目的。
此外,本文只是介绍了通过AirTest的框架进行图像识别,编写测试脚本,但是在某些特殊情况下,例如对于游戏或者App里的动态元素,通过图像识别比较困难。AirTest还提供了另外一种基于UI控件搜索的自动化框架Poco,同学们可以在下边的文章中,进行学习和实践。
详情请查看:https://edu.uwa4d.com/lesson-detail/124/470/0?isPreview=0
关注得物技术,携手走向技术的云端
文| Lynne