airtest
课堂笔记
appium和airtest区别
appium下载解压缩即可打开(但是本地必须有Android SDK) appium代码使用时必须开启appium服务端
airtest是真正意义上解压缩即用(内置了安卓sdk python3 airtest框架 poco框架) 量级比价大 使用airtestIDE比较吃资源
airtest支持图像识别 appium不支持
airtest功能更复杂支持的操作更简单
appium必须要配置包名及类名 然后 执行的时候默认打开 airtest不需要
airtest可以通过IDE同时调试 但是appium只能帮助定位元素 具体的代码操作需要通过代码实现
airtest安装注意
1.adb版本不匹配
说明 电脑中adb 存在多个 且版本不一致
解决方案 保证所有的adb都是同一个版本即可
找到所有的adb.exe 用同一个替换
常见出现位置
Androidsdk安装目录下 \platform-tools 会有
airtest 安装包下 AirtestIDE\airtest\core\android\static\adb\windows 也会有
2.直接将依赖apk拖到手机或者模拟器安装
Yosemite.apk位置 AirtestIDE包路径\airtest\core\android\static\apks
pocoservice-debug.apk位置 AirtestIDE包路径\poco\drivers\android\lib
3.如果连接模拟器出现黑屏
在connect的时候选择下拉框 勾选前两个(use javacap 及use adb orientation)
airtest基本介绍
我们现在所说的airtest 其实由三个部分组成 airtestIDE airtest框架 poco框架
airtestIDE是网易出品 是一个帮助我们实现自动化的工具
我们第一天使用的是 airtestIDE (IDE:集成开发环境) 可以直接通过这个工具进行代码编写调试 (该工具内置 python3.6 airtest框架 poco框架)
后面我们在代码中执行主要使用airtest框架和poco框架 airtestIDE 主要是用来帮助我们调试
airtest框架和poco框架 这两个是开源框架(意味着你可以查看修改源代码 基于源码实现一些特有功能的自定制)
airtest框架介绍
基于图像识别的自动化框架 (理论上手机不蓝屏黑屏白屏等屏幕异常的话) 都可以通过图像进行定位操作 忽略业务逻辑 将步骤图形化
poco框架介绍
基于元素进行定位的自动化框架 帮助我们进行元素定位 操作元素 (类似于webdriver)
airtest框架常用操作 (只要涉及到坐标使用 都是用的绝对坐标 所以后续操作 airtest我不会演示坐标使用)
touch(图片/绝对坐标,times=点击次数,duration=持续时间 )
wait(图片,timeout=超时时间,interval=每次查找间隔) 找到图片返回图片中心点坐标 找不到会报错
exist(图片) 找到图片返回图片中心点坐标 找不到不会报错 返回False
text(内容,enter=True,search=False) 在文本输入框中输入内容 (需要手机上有Yosemite,内容发给Yosemite 由Yosemite进行输入)
默认输入完执行回车操作 可以设置search为True强制执行search操作
keyevent(指令名) 执行键盘指令 常见指令:HOME BACK Enter
底层相当于相当于执行了 adb shell input keyevent KEYNAME
所以也支持写入 keycode keycode列表:https://blog.csdn.net/midux/article/details/80064054
start_app(包名) 打开指定app
airtestIDE提供查看包名的方法 (显示安卓助手对话框中 有个刷新当前app 可以查看当前APP的 包名 界面名)
stop_app(包名) 关闭指定app
pinch(in_or_out='in', center=None, percent=0.5) 第一个参数 为 in或out表示缩小或放大
详细信息参考 https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.api.html
poco框架相关操作 只要涉及到坐标都是相对坐标
基于屏幕(类似于webdriver中的driver对象 直接对浏览器操作 这里就是直接对手机操作)
poco.click( (x,y) ) 点击屏幕xy位置
poco.get_screen_size() 得到当前屏幕尺寸 返回一个列表 [width,height]
poco.long_click( (x,y), duration=2.0) 对屏幕xy位置 长按
poco.pinch(direction='in', percent=0.6, duration=2.0) 第一个参数 为 in或out表示缩小或放大
poco.scroll(direction='vertical', percent=0.6, duration=2.0) 第一个参数 为 vertical或者horizontal 表示方向为垂直或者 水平
poco.swipe(p1, p2=None, direction=None, duration=2.0)
p1 必填 是一个坐标 表示 你要从那个位置开始滑动
如:poco.swipe( [0.523,0.4],[0.5,0.7] ) 表示从[0.523,0.4]滑动到[0.5,0.7]
p2和direction任选一个 表示 你要滑动的终点
如:poco.swipe( [0.523,0.4],direction=[0,0.3] ) 表示从[0.523,0.4]沿着y轴滑动百分之三十
详细信息参考 https://poco-chinese.readthedocs.io/zh_CN/latest/source/poco.pocofw.html
基于对象(定位到某个元素对元素进行操作)
定位到元素的几种方式
1.通过属性进行定位
eles = poco(属性名=属性值) 默认定位就是定位页面上所有符合条件的值 如果直接操作 就默认取第一个进行操作
2.通过层级结构定位(不推荐 层级太复杂)
找到需要的元素 然后通过poco辅助窗 右击 uipathcode
元素的相关操作
ele.click() 对该元素进行点击
ele.attr(属性名) 根据属性名获取属性值 attr(name)=get_name() attr(text)=get_text()
ele.drag_to(target) target可以是个元素对象 表示 将该元素拖拽到目标元素对象位置处
也可以是一个坐标 表示将该元素拖拽到目标坐标处
ele.exists() 判断元素是否存在 存在返回True不存在返回False
ele.set_text(内容) 设置元素对象的文本内容(类似于send_keys) 只是单纯的给对象的text属性修改值 并不会执行回车搜索等操作
ele.setattr(属性名, 属性值) 设置元素对象的属性 为指定的属性值 ele.set_text("zhangsan")=ele.setattr("text","zhangsan")
ele.swipe(direction, focus=None, duration=0.5) 将元素对象按照指定方向进行滑动
direction可以为 up down left( 即[-0.1, 0]) right(即[0.1, 0])
也可以也具体的值 [x,y] x,y分别表示x方向的偏移量 y方向的偏移量 为负表示反方向
详细信息参考 https://poco-chinese.readthedocs.io/zh_CN/latest/source/poco.proxy.html
代码中定位元素的优先级
元素定位>相对坐标> 图像识别 不要采用绝对坐标 (无法跨分辨率)
安装
去官网http://airtest.netease.com/changelog.html下载最新安装包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5VFCBPsT-1670222985309)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/test/zhangjing/20201219143046.png)]
下载到本地后解压缩 目录下别有中文,最好直接解压到D盘下
即可成功启动 启动成功后页面如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-USlvw2UI-1670222985311)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/test/zhangjing/20201219143132.png)]
什么是Airtest
网易的airtest其实是个测试套件,由Airtest框架、poco框架、airtestIDE 组成。
Airtest框架
基于图像识别的自动化测试框架,是网易自己团队开发的。这个框架核心不在实现方式和技术上,而是理念!这个框架的祖宗是MIT(麻省理工)研究院的成果 Sikuli ,他们构思了一种全新的UI测试模式,基于图像识别控件而不是具体内存里的控件对象。理论上除了绿屏外,应该都能很好的识别并测试。
poco框架
网易自家的跨平台UI测试框架,原理类似appium,其实鹅厂也搞了个类似Poco的框架,叫做GAutomator,但无论是Poco还是GAutomator,他们也有个共同的祖宗,那就是xiaocong大大的uiautomator for python,让用python调用uiautomator成为可能。
但是,xiaocong的uiautomator只能抓取原生android的控件树,抓不了其他游戏引擎的,所以Poco和GAutomator就多做了一件事情那就是给各个游戏引擎开发SDK,把控件树数据dump出来然后回传,这样我们才能够在他们的Inspector工具里看到游戏内的控件树。而这个所谓的SDK本质上就是一个TCPServer跑在游戏里。
所以poco框架是用于抓取UI控件的
airtestIDE
这个就是完全网易自己家的东西,不开源的。IDE整合了airtest和poco两大框架,内置了Python3.6.5,本地无需安装python环境就能 直接使用 。提供了 adb工具、poco-inspector(抓ui控件)、设备屏录、图形化的脚本编辑器、便捷的ui截图工具等等一系列东西。已经很强大了,大大的提高了工作效率。
总结
Airtest是网易出品的一款基于图像识别和poco控件识别的一款跨平台的UI自动化测试工具。适用于游戏和App(本质上就是网易自己为了给游戏做自动化测试开发出来的一套框架)。后期又渐渐支持Windows和Android平台,iOS平台。 Airtest提供了跨平台的API,包括安装应用、模拟输入、断言等。 基于图像识别技术定位UI元素, 测试脚本运行后可以自动生成详细的HTML测试报告,让你迅速定位失败的测试点。 AirtestIDE 是一个强大的GUI工具,可以帮助你录制和调试测试脚本。
airtest和appium的区别
uiautomator2,appium, airtest几个工具浅析
https://www.jianshu.com/p/04a1faacc410
airtest优缺点
优点
1.AirtestIDE操作比较简单,基本上不涉及到代码,所以非常适合刚入门没什么测试经验的人利用这个工具做UI自动化测试,同时Airetest又提供了开源的API,让资深测试工程师可以基于Airtest的框架上再做高级的定制化扩展功能。
2.基于图像识别和UI控件识别功能简单
3.支持python进行个性化脚本编程
4.可录制脚本一键生成报告
缺点
1.如果经常使用图像识别 脚本会产生大量的图片,会让脚本整体观感不太好(个人意见)。
1.AirtestIDE操作
1.airtest连接设备
手机开启调试模式 连接电脑 一路允许安装
安装教程
https://airtest.doc.io.netease.com/IDEdocs/device_connection/1_android_phone_connection/
常见问题
1.未开启开发者选项 ,未允许USB调试,开发者选项内 打开禁止权限监控
2.未安装Yosemite及PocoService
https://blog.csdn.net/AirtestProject/article/details/108493205
Yosemite的作用:https://mp.weixin.qq.com/s/LnzToiXFVcfkeOGz8Vz9Pw
3.poco无限重启的解决办法
① 如果开了网络代理的话,需要先 关闭各种代理和VPN ,否则可能会影响到poco通讯
② 检查手机助手内是否对 pocoservice.apk
做了限制,例如在某版本的华为手机中需要开启 允许自启动 和 允许后台活动
https://airtest.doc.io.netease.com/IDEdocs/device_connection/2_android_faq/#_6
③ 不能和uiautomator同时启动,否则会相互冲突
④ 可以尝试 重启手机 看看是否会恢复
4.无法在密码框中输入密码
部分厂商(例如华为、VIVO等)的某些型号手机限制了密码框的输入,强制在输入密码时必须使用系统键盘输入。这样会导致需要输入密码时,直接使用airtest
的text()
会无法输入内容,需要把以下选项打开后才能正常输入密码内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5xPIKEV-1670222985312)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/test/zhangjing/20201219143212.png)]
2.录制.py脚本
因为我们都是已经学过Python,熟悉Python语言的高级用户,所以我们这边直接新建py脚本。也方便我们后期整合到pycharm搭建自动化框架。
2.1新建脚本
建议新建以一个要测的项目模块名称去新建一个文件夹,如:首页模块就建一个index文件夹,然后在文件夹内新建你的脚本
为什么要这样:主要是后期如果使用到截图功能和产出日志都会在同级文件下去产生图片和日志文件夹。如果不这样做,后期要测内容一多,所有模块log都在同一个文件夹下,图片也在同一级目录下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7xfMrOVQ-1670222985313)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/test/zhangjing/20201219143255.png)]
3.常用操作
3.1airtestIDE常用操作
1.通过安卓助手获取包名
2.通过设置获取坐标
3.2airtest框架常用操作
https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.api.html
3.3poco框架常用操作
基于屏幕操作 https://poco-chinese.readthedocs.io/zh_CN/latest/source/poco.pocofw.html
基于元素对象操作 https://poco-chinese.readthedocs.io/zh_CN/latest/source/poco.proxy.html
https://juejin.im/post/6844904150728179725
3.4扩展知识
1.如何安排连接设备、初始化poco和打开应用的脚本顺序
最正确的顺序是:先连接设备(一般在 auto_setup
接口里面连接)—> 再打开应用(一般用 start_app
接口)—> 等应用开启完毕,最后才初始化 poco
。
可以有效避免一大堆奇妙的报错
2.airtest封装好的adb命令
https://mp.weixin.qq.com/s?__biz=MzUxMDc4NTkwMA==&mid=2247485333&idx=1&sn=213206aa7f6755d5099147d71dba5a5a&chksm=f97ce796ce0b6e80362033702a6d325c40ec911d50b4a074ca5f7c2c1474ad065acc4bc7ab0a&token=153670092&lang=zh_CN#rd
4. airtest脚本代码
# -*- encoding=utf8 -*-
__author__ = "zj"
from airtest.core.api import *
from airtest.cli.parser import cli_setup
if not cli_setup():
auto_setup(__file__, logdir=True, devices=["android://127.0.0.1:5037/954f932f?cap_method=JAVACAP&&ori_method=ADBORI&&touch_method=MAXTOUCH",])
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
# 打开app
# touch(Template(r"tpl1648603568674.png", record_pos=(0.351, -0.602), resolution=(1080, 2340))) # 缺点 每做一次图像识别就会产生一张要检测的图片
# poco.click(0.824,0.224) # 缺点 每个手机的界面必须一致
# poco("网易云音乐").click() # 缺点 网易云音乐app必须在当前页面
start_app("com.netease.cloudmusic")
poco(text="每日推荐").click()
actualday=poco("com.netease.cloudmusic:id/dayRecommendDateInfo").attr("text")
actualmonth=poco("com.netease.cloudmusic:id/monthText").get_text()
expectmonthday = time.strftime('%m-%d',time.localtime(time.time()))
print(actualday)
print(actualmonth)
print(expectmonthday)
# assert expectmonthday==actualmonth+"-"+actualday
assert_equal(actualmonth+"-"+actualday, expectmonthday, "判断日期是否一致")
# assert_exists(Template(r"tpl1648604226343.png", record_pos=(-0.321, -0.464), resolution=(1080, 2340)), "请填写测试点")
assert_equal(poco("com.netease.cloudmusic:id/playAllTextView").exists(), True, "播放全部按钮是否存在")
firstele = poco("com.netease.cloudmusic:id/songName")[0]
firstelesongname = firstele.get_text()
firstele.click()
assert_exists(Template(r"tpl1648608437197.png", record_pos=(-0.002, 0.959), resolution=(1080, 2340)), "判断是否成功播放")
palysongname = poco("com.netease.cloudmusic:id/custom_title").get_text()
assert_equal(firstelesongname, palysongname, "播放的歌名是否一致")
keyevent("BACK")
keyevent("BACK")
poco(text="私人FM").click()
assert_exists(Template(r"tpl1648608437197.png", record_pos=(-0.002, 0.959), resolution=(1080, 2340)), "判断是否成功播放")
keyevent("BACK")
poco(text="歌单").click()
assert_exists(Template(r"tpl1648609356055.png", record_pos=(0.004, -0.83), resolution=(1080, 2340)), "判断二级导航栏是否存在")
assert_equal(poco(textMatches=".+歌单|.+快来听听").exists(), True, "判断子模块是否出现")
keyevent("BACK")
poco(text="排行榜").click()
res = poco(text="官方榜").exists() and poco(text="新歌榜").exists() and poco(text="飙升榜").exists()
assert_equal(res, True, "排行榜内部是否出现官方榜新歌榜飙升榜")
# generate html report
# from airtest.report.report import simple_report
# simple_report(__file__, logpath=True)
o(text="排行榜").click()
res = poco(text="官方榜").exists() and poco(text="新歌榜").exists() and poco(text="飙升榜").exists()
assert_equal(res, True, "排行榜内部是否出现官方榜新歌榜飙升榜")
# generate html report
# from airtest.report.report import simple_report
# simple_report(__file__, logpath=True)