【质量平台】浅尝UI自动化之Airtest实践

一、背景

由于很多公司都采用敏捷开发的模式,测试也要跟着进行敏捷测试。而每个迭代的周期非常短,经常要对原有功能进行回归测试,这样就增加了大量重复人力成本。引入 UI 自动化测试可以用来快速回归测试 app 原有功能,测试人员只需要关注新功能的测试。其次,移动端 App 的测试用例大部分是功能验证相关的用例,通过 UI 操作即可验证,这就为 UI 自动化提供了便利条件。因此,可以将测试重复度高,执行效率低的用例,通过 UI 自动化快速重复执行,达到提高测试效率的目的。

二、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 应用。

三、Airtset 安装和连接设备

    目前 AirTestIDE 提供了 Windows 和 Mac 两个版本的客户端,请从官网下载,解压即用。

    无论是 Android/IOS 手机,还是 Windows 窗口,在 AirTest 中都将它视为一个设备。下边重点介绍一下 Android 设备的连接。

连接 Android 手机

通过 ADB 连接电脑和 Android 手机,ADB 是 Google 官方提供的 Android 调试工具,AirTestIDE 依赖ADB与安卓设备进行通信。

打开 AirTestIDE,按照以下步骤进行连接:

1.打开手机设置-开发者选项-USB 调试开关,参考安卓官方文档

2.在 AirTestIDE 设备面板中点击 refresh ADB 按钮,查看连接上的设备;

3.如果没有显示出设备,试试 restart ADB,如果还不行,参考FAQ文档进行问题排查。

4.能够成功看到设备后,点击对应设备的 connect 按钮,进行初始化。

连接成功后,即可在 AirTestIDE 中看到手机屏幕的镜像显示,并进行实时操作,如下图所示:

连接 IOS 手机

要连接一台 IOS 手机,你需要准备好一台安装了 Xcode 的 MAC 电脑,连接方式参考文档

四、录制自动化脚本

在连接上设备以后,就可以开始录制自动化测试脚本了,在接下来的内容中,我将会在一台 Android 手机上,给大家演示如何录制脚本。

模拟输入

AirTest 支持通过图像识别的方式,找到你想要的位置并进行操作,这是基于 AirTest 框架实现的。

我们可以先看看如何自动录制脚本:点击 AirTestIDE 左侧的 AirTest 辅助窗上的“录制”按钮,然后随着你在设备窗口上操作手机,代码会自动生成在代码窗口中。

录制完成后,点击“运行”,就可以运行你的第一个自动化脚本了。

如果你觉得自动录制生成的图标不够准确,还可以点击 AirTest 辅助窗上的 touch 按钮,然后再设备窗口上框选精确的图标,也可以制动生成一条 touch 语句。如下:

https://v.qq.com/txp/iframe/player.html?vid=e3252k79dir

类似的模拟输入操作还有滑动:点击 swipe 按钮,在设备窗口上框选精确的图标最为滑动起点,然后点击滑动终点位置,即会自动生成一个 swipe 语句。

其他的模拟输入的 API 包括:

  • Text:文字输入
  • KeyEvent:按键输入,包括(HOME/BACK/MENU 等)
  • Sleep:等待
  • Snapshot:截屏

断言

到这里,我们已经有各种模拟输入方法,配合逻辑控制语句让手机动起来。自动化测试中还有很重要的一个步骤:结果验证。我们就可以来看看怎样声明断言。

(1)验证 UI 界面

录制方法与模拟输入类似。

  • assert_exists:断言图片存在
  • assert_not_exists:断言图片不存在

(2)验证数值

通过 Poco 获取属性值,手写代码进行断言。

  • assert_equal:断言箱单
  • assert_not_equal:断言不等

例如

查看测试报告

脚本运行完毕后,点击“查看报告”那妞,会使用默认浏览器打开结果报告页面,报告中将展示每一个步骤的内容和实际执行过程的截图、运行结果,方便查看步骤是否执行成功。

五、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 是一用来初始化环境的接口,接口文档在这里,它接受 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 对当前画面截一张图
  • 其他

核心 API 请参见文档,在这个文档页里出现的 API 都是跨平台 API,由于我们在代码的第一行里将 airtest.core.api 里的接口全部 import 进来了,因此这些 API 可以在代码里直接进行调用,像这样:

在很多接口中,支持传入 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 第三方库方法相同。

六、总结

本文只是简单讲解了如何使用 AirTest 进行 UI 自动化脚本的录制和回放,以及对自动化脚本进行了介绍。如果要进行 UI 自动化的持续集成,还需要进一步的了解和学习。

希望有时间的同学可以进行一些实践,了解一下 UI 自动话相关的知识。在以后的工作中,我们就可以将测试重复度高,执行效率低的用例,通过 UI 自动化快速重复执行,以达到提高测试效率的目的。

此外,本文只是介绍了通过 AirTest 的框架进行图像识别,编写测试脚本,但是在某些特殊情况下,例如对于游戏或者 APP 里的动态元素,通过图像识别比较困难。AirTest 还提供了另外一种基于 UI 控件搜索的自动化框架 Poco,同学们可以在下边的文章中,进行学习和实践。详情请查看:https://edu.uwa4d.com/lesson-detail/124/470/0?isPreview=0

文|Lynne

关注得物技术,携手走向技术的云端

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/163e1bb3ec6e005e3e0a0886b
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券