[1054]Airtest的探索使用
Posted 周小董
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[1054]Airtest的探索使用相关的知识,希望对你有一定的参考价值。
文章目录
Airtest的简介
Airtest是网易出品的一款基于图像识别和poco控件识别的一款UI自动化测试工具。Airtest的框架是网易团队自己开发的一个图像识别框架,这个框架的祖宗就是一种新颖的图形脚本语言Sikuli。Sikuli这个框架的原理是这样的,计算机用户不需要一行行的去写代码,而是用屏幕截屏的方式,用截出来的图形摆列组合成神器的程序,这是Airtest的一部分。
另外,Airtest也基于poco这个U控件搜索框架,这个框架也是网易自家的跨平台U测试框架,原理类似于appium,通过控件的名称,id之类的来定位目标控件,然后调用函数方法,例如click(),swip()之类的方法来对目标控件进行点击或者是操作。
关于自动化测试
概念:自动化测试,就是把繁杂的人工测试用例利用自动化测试工具编写成代码,让机器代替人工自动跑用例的过程。实际上就是把以人为驱动的测试行为转化为机器执行的一种过程。
意义:节省人力、物力、时间、硬件资源等,提升测试效率,特别对于繁琐重复的测试用例,可以使测试人员更专注于新的测试模块的建立和开发,从而提高测试覆盖率。
市面上常见的UI自动化测试工具以及优缺点
以上主流工具的优点跟缺点:
相较于以上工具来说,Airtest有以下优点和缺点:
所以其实基于图像识别的Airtest更适合用于游戏测试多一点。
环境的搭建
1、AirtestIDE的下载
AirtestIDE已经帮你集成了所有的环境,自带录制脚本栏,自动生成脚本,自带编辑器还自带模拟器,有了一个AirtestIDE就可以轻松简单的录制脚本了。下载地址是Airtest的官网:
http://airtest.netease.com/
AirtestIDE的使用教程跟文档也在下面的连接中:
https://airtest.doc.io.netease.com/
android真机连接
使用AirtestIDE对Android应用进行自动化测试时,第一步就需要连接Android设备。
Android真机连接准备:
- 请先安装手机对应品牌的官方驱动,确保能使用电脑对手机进行USB调试
- 确保已经打开了手机中的”开发者选项”,并且打开”开发者选项”内的”允许USB调试”
- 部分手机需要打开”允许模拟位置”、”允许通过USB安装应用”
- 关闭电脑上已经安装的手机助手软件,能避免绝大多数问题,请务必在任务管理器中手工结束手机助手进程
Android真机USB连接
- 请使用USB线连接手机,手机上出现的 允许USB调试 弹窗点击 确定,
- 点击连接面板中的 refresh ADB 按钮,设备列表将会刷新,
- 点击列表内对应设备的 Connect 完成连接,
- 若设备未刷出,点击 refresh ADB 按钮。
如果遇到连接问题,请查阅Android连接常见问题:https://airtest.doc.io.netease.com/IDEdocs/faq/1_common%20problems/
手机连上Airtest之后,会向手机中安装2个app,如下:
pocoservice是支撑poco操作的app,yosemite是airtest的输入法,安装之后,手机的默认输入法会变成这个输入法,如果需要改回来原来的输入法,需要手动到手机设置里面进行修改;
远程连接
- 已知IP和端口的远程设备 ip:port ,AirtestIDE可以直接连接,
- 点开设备窗内的 远程设备连接 按钮
- 将 adb connect ip:port 字段填入填充框内,点击 连接 按钮,
- 远程设备将出现在设备列表中,点击 connect 按钮。
无线连接
参考:使用adb无线连接手机
当手机与电脑处在同一个wifi下,即可尝试无线连接手机了,但是这种方式受限于网络连接的稳定性,可能会出现连接不够稳定的情况。具体连接操作步骤如下:
- 确保手机开启了USB调试选项,并先用USB线将手机和电脑连接起来
- 在电脑端执行命令 adb tcpip 5555 ,其中 5555 是端口号,可以根据自己的需求来指定,5555是默认值
- 获取手机的IP地址,可以在 手机设置-关于手机-状态信息-IP地址 里找到,也可以执行 adb ifconfig 来查看
- 随后可以拔掉USB线,在AirtestIDE的 远程设备连接 处输入 adb connect 手机ip:刚才填入的端口号5555 ,点击连接,刷新ADB后就能在设备列表中看到连上的设备了
- 如果因为网络波动、重启ADB等原因导致连接断开,重新执行一次 adb connect ip:port 即可。
录制
点击录制按钮,选择事件进行录制,可以用鼠标操作
介绍一下录制时每一个参数的作用
- touch(): 点击操作,根据录制脚本时所截取的图像进行点击
- wait(): 可以等待画面中某个图片出现,如果在指定的时间范围内匹配到了该图片,就会返回图片所处位置的焦点,否则抛出TargetNotFoundError异常
- swipe():可以从一个位置滑动到另外一个位置
- exists():判断画面中是否存在某个图片,如果匹配到图片,返回图片所处位置的焦点,否则返回False
- text():输入文本
- sleep():线程挂起
- assert_exists():断言图片存在于当前画面上
- assert_not_exists():断言图片不存在
- assert_equal():断言数值相等
- assert_not_equal():断言数值不等
- assert_exists()与assert_equal()的区别在于,assert_exists断言的对象是图片,assert_equal断言的对象是数值
可以按照需要的参数进行配置
一个简单的.air 脚本解析
什么是.air 脚本
在下载解压 Airtest 脚本的专属 IDE——AirtestIDE 后,点击 “新建脚本” 按钮,默认即可创建一个后缀名为.air
的脚本文件,.air
这是 Airtest 脚本的专属后缀。
让我们打开刚才新建脚本的文件夹,可以看到实际上.air
脚本文件是一个普通的文件夹,里面附带了一个同名的.py
文件,AirtestIDE 在执行脚本时,实际上执行的是里面的.py
文件。也就是说,Airtest 脚本虽然自带一个后缀名,然而本质上依然是 Python 脚本,遵循的是 Python 语法,我们可以根据实际需要自由地import其他 Python 第三方库。
值得注意的是,.air
文件夹中必须要有同名的.py
文件,否则在命令行执行airtest run test.air
这样的运行指令时会导致失败。
初始化环境
首先,就像一个普通的 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 查看窗” 中自动生成一个可用的命令行,可以供大家作为参考。
"D:\\AirtestIDE-path\\AirtestIDE" runner "D:\\script-path\\untitled.air" --device Android://127.0.0.1:5037/5PZTQWQOGES8RWUG --log "C:\\Users\\username\\AppData\\Local\\Temp\\AirtestIDE\\scripts\\aa8c71acdfa70c3068b862cb42ffb8dc"
设备连接
- 在运行时的命令行中如果传入了类似
--device Android:///
这样的设备参数,那么脚本在初始化时会自动连上对应的设备,不需要再另外写代码连接了。 - 如果没有在初始化时连上设备,可以在脚本代码中使用
connect_device
接口来连接设备。 - Airtest 支持在一个脚本里同时连接多个设备,使用
set_current
接口可以在多个设备中进行切换,device()
接口可以获取到当前使用中的设备。
模拟点击
Airtest 作为自动化测试框架,模拟的是人的操作,常见接口主要有:
touch
点击某个位置,可以设定被点击的位置、次数、按住时长等参数swipe
从一个位置滑动到另外一个位置text
调用输入法输入指定内容keyevent
输入某个按键响应,例如回车键、删除键wait
等待某个指定的图片元素出现snapshot
对当前画面截一张图- 其他
核心 API 请参见这个文档,在这个文档页里出现的 API 都是跨平台 API,由于我们在代码的第一行里将airtest.core.api
里的接口全部import
进来了,因此这些 API 可以在代码里直接进行调用,像这样:
from airtest.core.api import *
touch((x, y))
在很多接口中,支持传入Template
图片对象作为参数,在运行时将会去点击图片在画面中的所在位置,类似这样:
# 等价于 touch((x, y)), (x, y)是图片所在的中心点
touch(Template(r"tpl1556019871196.png", record_pos=(0.204, -0.153), resolution=(1280, 720)))
其中,Template
对象是一个图片类,Airtest 会先尝试在当前画面中寻找能够匹配这张图片的位置,如果找到了,将对这个坐标进行点击操作,如果找不到,将抛出识别异常。我们将在后文对Template
图片类进行更加详细的介绍。
安装包
1)使用 pip 安装Airtest框架 pip install airtest
2)若运行代码时,在cv2模块报 ImportError: DLL load failed: 找不到指定模块 的错,如果使用的python版本低于3.7,请直接运行:
pip uninstall opencv-contrib-python
# 若以下安装语句运行失败,可以尝试更新pip到最新版本后重试
pip install opencv-contrib-python==3.2.0.7
3)Poco安装
使用 pip 安装poco框架 pip install pocoui
,请注意库的名称为 pocoui
,不要填错。
Airtest基本操作方法
除了跨平台的API还有平台特定的API,比如:
airtest.core.android #安卓平台
airtest.core.ios #苹果平台
airtest.core.win #Windows平台
这里我们来详细说说这些模块。
跨平台API模块
这里我们要介绍的第一个就是跨平台模块:
from airtest.core.api import * #导入所有方法
1).初始化设备
这里初始化设备我们也有两种方案,下面请看:
根据设备的UUID来初始化
语法格式:
init_device(platform='Android',uuid='',cap_method=JAVACAP for Android)
#平台 – Android,IOS或Windows
#uuid –目标设备的uuid,例如,用于Android的serialno,用于Windows的handle,用于iOS的uuid
#kwargs –可选的平台特定关键字args,例如cap_method = JAVACAP for Android
下面我们来列举一下实例,如下:
init_device(platform='Android',uuid='127.0.0.1:62001',cap_method='JAVACAP')
根据设备的URL来初始化
语法格式如下:
android:/// 连接当前安卓设备
android://adbhost:adbport/serial NO.?cap_method=javacap&touch_method=adb
windows:/// 连接本地桌面程序
ios:/// 连接IOS设备
这里我们主要是传入了ADB地址,端口和连接的夜神模拟器的序列号而连接上的。具体例子如下:
connect_device('android://127.0.0.1:5037/127.0.0.1:62001?cap_method=javacap&touch_method=adb')
2).返回当前活动设备
device()
3).设置当前活动设备
有时候如果我们连接了多个设备,我们需要切换的话,就是用这个函数来达到目的,可以使用设备的索引或者设备的序列号来进行切换哦。
set_current(0)
set_current('127.0.0.1:62001')
4).运行环境配置
auto_setup(basedir = None,devices = None,logdir = None,project_root = None,compress = 0 )
basedir 设置当前脚本的所在位置,__file__也可以。
devices 指定运行脚本的设备以列表形式存在
logdir 设置脚本运行时的日志保存路径,默认为None,设为True可保存
project_root 设置api的项目根目录
5).开启并执行远程Shell命令
shell(cmd) #ls / data / local / tmp
6).在设备上启动程序
start_app('启动的应用程序包名')
7).在设备上停止程序
stop_app('启动的应用程序包名')
8).清除设备上的应用程序数据
clear_app('启动的应用程序包名')
9).在设备上安装应用程序
install(filepath='要在目标设备上安装的文件的路径')
10).在设备上卸载应用程序
uninstall('应用程序包名')
11).截图并保存到文件中
snapshot(filename='1.jpg',msg='hello',quality=3)
filename:图片名
msg:屏幕截图的简短描述
quality:图像质量,范围为[1,99]的整数
12).唤醒并解锁设备
wake('设备')
13).返回目标设备的主屏幕
home('设备')
14).设备屏幕上执行点击,滑动,捏,按键,输入操作
click(v=Template(x,y),times=2) #单击
v:触摸目标,可以是Template实例,也可以是绝对坐标(x,y)
times:执行多少次触摸
double_click() #双击
swipe(v1,v2)#滑动起点和终点
swipe(v1,vector=(x,y))#沿向量移动,向量可以是坐标也可以是屏幕百分比
#返回值:原点位置和目标位置
pinch()#捏操作,相当于缩放,参数如下:
in_or_out:放大或缩小
center:默认为None表示屏幕中心
percent:捏动作的屏幕比例,默认值为0.5
keyevent(keyname='Home')#按键操作
text('文本')#在设备上输入文本
15).睡眠,等待
sleep(2)#睡眠两秒,延迟两秒
wait(v,timeout,interval,intervalfunc)#等待与设备屏幕上的模板匹配
v:等待的目标对象
timeout:超时时间
interval:尝试找到匹配项的时间间隔(秒)
intervalfunc:在每次未成功尝试找到相应匹配项后调用
返回值:匹配目标的坐标
16).检查给定目标在设备屏幕上是否存在
exists(v)
v:检查对象
如果找不到目标,则为False,否则返回目标的坐标
17).在设备屏幕上查找所有出现的目标并返回其坐标
find_all(v)
v:寻找目标
返回坐标列表
18).断言操作
assert_exists(v,msg) #断言目标存在于设备屏幕上
assert_not_exists(v,msg) #断言目标在设备屏幕上不存在
v:要检查的目标
msg:断言的简短描述
assert_equal(v1,v2,msg) #断言两个值相等
assert_not_equal(v1,v2,msg) #断言两个值不相等
v1:第一个值
v2:第二个值
msg:断言的简短描述
这里基本上我们就把使用方法说完了,下面我们来进行下实际操作,下一篇文章即将奉上。
- 使用
from airtest.core.api import *
# 通过ADB连接本地Android设备
connect_device("Android:///")
#安装待测软件apk,路径信息。
install("path/to/your/apk")
#开始运行app
start_app("com.pingan.certicationApp")
#点击某个图片,Airtest中基于图像识别语法,图片自己提供。
touch(Template("image_of_a_button.png"))
#滑动语音,开头图片跟结尾图片
swipe(Template("slide_start.png"), Template("slide_end.png"))
#添加断言的图片
assert_exists(Template("success.png"))
#点击Android上的返回键
#keyevent("BACK")
#点击Android上的Home键返回
#home()
#uninstall("package_name_of_your_apk")
- poco样例
# -*- encoding=utf8 -*-
__author__ = "enmonster"
from airtest.core.api import *
auto_setup(__file__)
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
poco("com.miui.home:id/workspace").offspring("计算器").offspring("com.miui.home:id/icon_icon").click()
poco("com.miui.calculator:id/btn_c_s").click()
poco("com.miui.calculator:id/digit_7").click()
poco("com.miui.calculator:id/op_add").click()
poco("com.miui.calculator:id/digit_5").click()
poco("com.miui.calculator:id/btn_equal_s").click()
poco辅助窗
poco是通过元素本身的属性来定位元素,常用的API如下:
attr(‘type’):提取指定元素属性为type的值
get_text(): 提取指定元素的文本内容
attr(‘text’): 通过给定的属性名检索ui元素的属性。如果属性不存在,则返回none(属性有visible、text、type、pos、size、name等)
exists():判断指定元素是否在当前屏幕上存在,存在true、不存在false
click(): 点击事件,可使用click(center)、click([0.5,0.5])、focus([0.5,0.5]).click()来点击控件中心位置
rclick():右键点击
double_click():双击操作
long_click():长按操作
swipe:滑动事件,如:swipe([0.2, -0.2], duration=1)以45度角滑动,持续1秒钟
drag:拖拽事件,如:poco(text=‘需要拖动位置’).drag_to(poco(text=‘目标位置’))
focus (local positioning):局部定位,如:poco(‘控件地址’).focus(‘center’).click()点击控件中间位置
wait:等待事件,如:poco(‘控件地址’).wait(2).click() 控件出现就点击,最多等待2秒
多个手机交互
如果case中涉及到两个手机交互的,可以在.py文件中连接多个手机,需要在哪个手机上操作,就需要在脚本中使用set_cerrent()借口来切换到相应的手机上;
device1 = "c17a4cb4" #设备1
device2 = "RKK0217C15003363" #设备2
dev1 = connect_device("android://127.0.0.1:5037/"+device1)#连接设备1
dev2 = connect_device("android://127.0.0.1:5037/"+device2)#连接设备2
poco1 = AndroidUiautomationPoco(dev1) #初始化设备1
poco2 = AndroidUiautomationPoco(dev2) #初始化设备2
set_current(device1)#切换到手机1
set_current(device2)切换到手机2
case举例
初始化设备之后就可以进行相关设备的poco操作了,举个例子:
这个例子是打开微信,点击聊天信息中的一个好友,然后清除好友聊天的例子;
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
device1 = "c17a4cb4" #设备号
dev1 = connect_device("android://127.0.0.1:5037/"+device1)#连接师傅手机
poco1 = AndroidUiautomationPoco(dev1) #实例化手机
auto_setup(__file__)
def clear_wechat(poco):#清除微信的聊天记录
start_app("com.tencent.mm")#启动微信
sleep(12)#等待12秒
poco1(text="三星").click()#点击好友“三星”的聊天
poco1("android.support.v7.widget.LinearLayoutCompat").click()#点击更多
poco1(text="清空聊天记录").click()#点击清空聊天记录
poco1(text="清空").click()#点击清空
stop_app("com.tencent.mm")#关闭微信
引用其他air文件的方法
如果有很多重复的操作,可以将这些重复的操作写到一个公用的air文件里面,然后再在用例里面引用这个公用的air文件的方法就可以:
举例,有一个名叫gongyou.air的文件,里面有一个clear_wechat的方法,这个clear_wechat方法就是一个清除微信聊天记录的用例,如果需要在用例中用到这个clear_wechat,就需要在用例中引用这个文件,然后倒入这个引用文件中的clear_wechat方法,如下:
# -*- encoding=utf8 -*-
__author__ = "xhong"
from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
from poco.exceptions import PocoNoSuchNodeException
from poco.exceptions import PocoTargetTimeout
ST.PROJECT_ROOT = "D:\\code\\AirtestCase"#引用公用air的路径
using("gongyou.air")
from gongyou import clear_wechat
参考:https://www.jianshu.com/p/32d08455e86f
https://blog.csdn.net/sunxitao970324/article/details/105731046
http://testerhome.com/topics/20704
https://cloud.tencent.com/developer/article/1819833
https://zhuanlan.zhihu.com/p/165527546
https://blog.csdn.net/chqj_163/article/details/109242399
AirtestIDE连接安卓真机及常见问题:
https://www.cnblogs.com/songzhenhua/p/14716116.html
airtest连接设备黑屏或者运行报错minicap超时问题:
https://blog.csdn.net/qq_32394351/article/details/112512540
以上是关于[1054]Airtest的探索使用的主要内容,如果未能解决你的问题,请参考以下文章