Airtest学习(二)

Airtest学习(二)poco 的元素定位一 poco 的元素定位 1 借助 IDE 的 poco 辅助窗生成元素定位脚本点检视器按钮 前两个都行 点元素 就能看到该元素所在的位置 点那个定位就能生成脚本 区别是第一个按钮锁住页面 点录制按钮 点元素 然后就生成了脚本 去掉 click 即可 2 利用基本选择器进行元素定位

学习笔记-airtest自动化

笔记目录:https://blog.csdn.net/weixin_/article/details/

昨天下了雨,今天刮了风,明天太阳就出来了

录制视频

报告

  • 自定义截图压缩精度
  • 自定义报告截图的最大尺寸
  • 局部截图/区域截图
  • 用log()接口在报告中显示信息/报错

截图

脚本全局设置

Firebase打包脚本

进一步熟悉

  • 滑动
  • 引用其他脚本
  • 输入无法使用解决方法
  • 输入和删除文字
  • 输入完毕后的回车与搜索键
  • 输入随机数
  • poco获取节点的text属性
  • 自定义log级别
  • 模拟鼠标右键

poco的元素定位

坐标介绍

Airtest图像识别原理相关

截图技巧

 

 

 

 

一:录制视频

airtest1.1.6支持 在 --recording 参数后面加上一个文件名来命名录屏文件 ,例如 --recording test.mp4 ,如果有不止一台手机在运行,会把文件命名为 手机名_test.mp4 。

#开始录制/结束录制 start_recording() 和 stop_recording()

【回顾】在使用纯py文件编写脚本的时候,如使用了android手机,初始化连接

if not cli_setup(): auto_setup(__file__, logdir="./log", devices=["Android://127.0.0.1:5037/FIFIMFFEPVAIWCU8"]) 

devices:adb server所在主机的ip:adb port  /  序列号,其中FIFIMFFEPVAIWCU8是序列号,通过这种方式可以查出

Airtest学习(二)

 

API:https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.android.recorder.html?highlight=recording#airtest.core.android.recorder.Recorder.start_recording

录屏的这两个方法 属于 Recorder(adb) 类,需要实例化这个类,才能通过实例去调用里面的方法

adb = ADB(serialno="FIFIMFFEPVAIWCU8") recorder = Recorder(adb) # 开始录屏 recorder.start_recording(max_time=10) sleep(3.0) # 结束录屏 recorder.stop_recording(output="dy.mp4")

在录制的时候,涉及密码输入,会出现黑屏,在安全设置中,把安全键盘之类的设置关掉 ,或者是 关掉其它一些防止恶意截屏录屏的设置。

 

 

二:报告

__author__ = "漫步云端" __title__ = "打开我的页面" __desc__ = """ 前提:无; 步骤1:打开app; 步骤2:点击我的; 步骤3:断言; """

Airtest学习(二)

可以使用命令行:airtest info 脚本路径, 可以获得airtest解析出来的脚本信息,类似这样的返回值

{“name”: “untitled.air”, “path”: “untitled.air”, “author”: “user”, “title”: “脚本标题”, “desc”: “用例描述”}

 

 

 

三:截图

(1)自定义截图压缩精度

① 使用命令行启动,airtest run ... --compress quality

② 在脚本中自定义,优先级高于命令行,取值范围是1-99的正整数,airtest默认取10

import airtest.core.api import * ST.SNAPSHOT_QUALITY = xxx # [1, 99] # 在报告的该touch步骤中,保存的截图的精度为全局精度xxx touch(xx) # snapshot保存的截图精度也是全局精度xxx snapshot(filename='./ok.jpg',msg="完成截图")

③ 设置某张图片的压缩精度

snapshot(quality=my_quality)

 

(2)自定义报告截图的最大尺寸

# 设置截图尺寸不超过600*600,如果不设置,默认为原图尺寸 ST.IMAGE_MAXSIZE = 600 # 在报告的该touch步骤中,保存的截图尺寸不超过600*600 touch(xx) # 截图质量为90,尺寸不超过1200*1200 snapshot(filename="ok1.png", msg="ok1", quality=90, max_size=1200) # 不设置的情况下,默认采用ST中的全局变量的数值,即600*600 snapshot(msg="ok2")

 

(3)局部截图/区域截图

如(0,160)(1067,551)

# crop_image()方法在airtest.aircv中,需要引入 from airtest.aircv import * screen = G.DEVICE.snapshot() # 局部截图 screen = aircv.crop_image(screen,(0,160,1067,551)) # 保存局部截图到log文件夹中 try_log_screen(screen)

Airtest学习(二)

 

(4)用log()接口在报告中显示信息/报错

【回顾】airtest报错in recv raise socket.error(“socket connection broken”)

原因是连接参数少写了一个

【回顾】看下API:airtest.core.android.adb module,导包写from airtest.core.helper import *,避免忘记导包

 

args, 可以是字符串或是 traceback 对象(异常),现在还支持传入非字符串

timestamp, 参数可以自定义当前这条 log 的时间戳,默认为当前时间

desc , 自定义一个 log 标题

ata = {"test": 123, "time": } # 第一条log,步骤名显示title,截取一张屏幕截图 log(data, timestamp=time.time(), desc="title", snapshot=True) # 第二条log,标记为报错步骤并截取一张屏幕截图 try: 1/0 except Exception as e: log(e, snapshot=True) # 第三条log,显示传入的字符串 log("中文") # 这样也行 import traceback try: xxxx except: log("出错啦", traceback. format_exc())

Airtest学习(二)

Airtest学习(二)

Airtest学习(二)

 

四:脚本全局设置

airtest.core.settings里,提供了部分全局默认属性,可以修改全局设置,如:

from airtest.core.api import * # airtest.core.api中包含了一个名为ST的变量,即为全局设置 ST.THRESHOLD = 0.8 

如touch,如果在里面有指定threshold,则使用指定的,如果没有,则默认使用全局属性。

 

常见的全局属性:

  • RESIZE_METHOD = staticmethod(cocos_min_strategy)

分辨率适配规则

https://airtest.doc.io.netease.com/IDEdocs/airtest_framework/1_script_settings/

比如,参数都不用动,中间的内容是根据原属性,改为我要的缩放规则即可

Airtest学习(二)

  • THRESHOLD = 0.7 # [0, 1]

图像识别的阈值

  • THRESHOLD_STRICT = 0.7 # [0, 1]

只用于assert_exists(图片)接口

  • OPDELAY = 0.1

每一个步骤的操作之间都会有一小段时间间隔,默认是0.1秒

  • FIND_TIMEOUT = 20

图像查找时间,使用了该接口:touch、double_click、swipe(如果是a图片滑到b图片,只有a图片使用了该接口)、wait(在没有使用timeout的情况下使用了该接口)、assert_exists

  • FIND_TIMEOUT_TMP = 3

图像查找时间,使用了该接口:swipe(如果是a图片滑到b图片,只有b图片使用了该接口)、exists、assert_not_exists

  • PROJECT_ROOT = os.environ.get(“PROJECT_ROOT”, “”) # for using other script

可以通过设定一个默认项目根目录PROJECT_ROOT,让使用using接口时能够在当前根目录下寻找别的子脚本,无需填写完整路径,让脚本之间相互调用使用更加方便

from airtest.core.api import * ST.PROJECT_ROOT = "/User/test/project" # test1.air的实际路径为/User/test/project/test1.air using("test1.air") #调用其他的脚本 from test1 import test

 

 

五:Firebase打包脚本

限制:

  • 安卓原生应用的poco无法使用,因为无法从一个app去启动另外一个app。但是游戏引擎的poco均可使用。
  • 部分airtest接口,无法使用该方式执行,例如
    • clear_app
    • install_app
    • uninstall_app
  • 由于启动脚本时,会出现kivy闪屏图片,所以脚本以start_app()开始
  • 打包时,因为涉及到文件删除操作,所以不要使用目标包体的目录(有些用户习惯性直接在生成包体的目录打开命令行安装,会导致无法进行下一次打包)

 

原理:

Airtest学习(二)

步骤

1(环境配置):java(jdk,非jre)、配置jdk环境,输入jarsigner,没报错即可(如果出现不是内部命令,则将环境配到系统变量即可)

2(打包流程)

Airtest学习(二)

然后将该apk和被测应用安装在手机上,

然后用adb指令启动测试脚本 adb shell am instrument -w com.netease.open.airbase/android.support.test.runner.AndroidJUnitRunner

 

 

六:进一步熟悉

(1)滑动

swipe_along目前只有在使用了默认的 minitouch 模式(Android10使用 maxtouch )时才能使用

自定义点击或滑动操作的方案:https://airtest.doc.io.netease.com/IDEdocs/faq/3_api_faq/

(2)引用其他脚本

如果需要引用的子脚本路径统一都放在某个目录下,可以通过设定一个默认项目根目录 PROJECT_ROOT ,让使用 using 接口时能够在当前根目录下寻找别的子脚本,无需填写完整路径

如jb1.air路径是/User/test/project/jb1.air 其他脚本引用它则: ST.PROJECT_ROOT = "/User/test/project" using("jb1.air") 记住别漏了导入方法语句 from jb1 import xx方法

(3)输入无法使用解决方法

#如果遇到一些设备无法使用text(),可以这样 # 方法一 dev = init_device("Android") dev.shell(shell("input text ''")) # 方法二 dev = connect_device("Android://127.0.0.1:5037/P7CDU18C") dev.shell(shell("input text ''")) # 方法三 init_device("Android", ime_method="ADBIME") text("")

(4)输入和删除文字

#删除输入框内容 for i in range(10): keyevent("67") #poco写法:将输入框内容设置为空字符串 poco("xxx").set_text("") # 设置文字 # airtest写法: text("哈哈") #poco写法:注意XXX是可输入控件 poco("XXX").set_text("哈哈")

(5)输入完毕后的回车与搜索键

text接口有默认参数enter=True,即输入完成后回车,部分输入框是search=True

注意:输入法的回车和换行不同于keyevent事件

(6)输入随机数

#输入随机数 import random r = random.randint(1,100) text(str(r))

(7)poco获取节点的text属性

#poco获取节点的text属性 a = poco(text="cs") a.get_text() a.get_name()

(8)自定义log级别

import logging logger = logging.getLogger("airtest") logger.setLevel(logging.ERROR)

(9)模拟鼠标右键

# 获取当前连接的窗口 dev = device() # 拿到鼠标,并模拟鼠标的右键点击操作 dev.mouse.right_click(coords=(1920,100))

 

 

 

 

 

七:poco的元素定位

(1)借助IDE的poco辅助窗生成元素定位脚本

检视器按钮(前两个都行),点元素,就能看到该元素所在的位置,点那个定位就能生成脚本(区别是第一个按钮锁住页面)

点录制按钮,点元素,然后就生成了脚本,去掉.click()即可

(2)利用基本选择器进行元素定位

(3)利用相对选择器进行元素定位

(4)利用空间顺序选择器进行元素定位

 

 

 

 

八:坐标介绍

(1)Airtest的坐标系

# Airtest的坐标系 # (1)touch-使用的是(x, y)绝对坐标 # (2)swipe-滑动起点和终点使用的是(x, y)绝对坐标

Airtest学习(二)

 

 

(2)poco的坐标系

poco点击默认是点在 anchorPoint  [ˈæŋkə(r) pɔɪnt]上的,每个UI都会有一个 anchorPoint ,也就是检视器(Inspector)中UI包围盒的那个红点,大部分情况下 anchorPoint 都在UI包围盒的正中央

Airtest学习(二)

Airtest学习(二)

# (1)使用局部坐标系的click接口 # 引入局部坐标系来表示相对于某UI的坐标。 # 局部坐标系以UI包围盒左上角为原点,向右为x轴,向下为y轴,包围盒宽和高均为单位一。(如上图) # 局部坐标系可以更灵活地定位UI内或外的位置,例如(0.5, 0.5)就代表UI的正中央,也就相当于我们上文中默认的anchorPoint;超过1或小于0的坐标值则表示UI的外面。 # 点击 anchorPoint 以外的其他指定位置时,可以传一个参数到 click 方法中,这个参数是一个用list或tuple表示的2维向量, # 其 [x, y] 值分别表示相对于包围盒左上角的偏移量,左上角为 [0, 0] ,右下角为 [1, 1] poco(text="口红").click([0,0]) # 改变以anchorPoint为起点,也可以使用focus方法 poco(text="口红").focus([0,0]).click()
# (2)使用归一化坐标系的swipe接口 # 将屏幕宽和高按照单位一来算,这样UI在poco中的宽和高其实就是相对于屏幕的百分比大小 # 好处:不同分辨率设备之间,同一个UI的归一化坐标系下的位置和尺寸是一样的,有助于编写跨设备测试用例 # 屏幕正中央一定是(0.5, 0.5) # 也是以 anchorPoint 为起点,改变起点用focus 方法

Airtest学习(二)

假如在游戏中(如中心点(0.5,0.5)),那我想往右上走(如走到(0.9,0.1)),那我的偏移量为(0.4,-0.4),距离为sqrt(0.4*0.4)

cs = poco("xx") cs.swipe('up') # 向上向右滑动,duration是滑动时长 cs.swipe([0.4, -0.4], duration=0.5)

 

 

 

 

 

九:Airtest图像识别原理相关

默认情况下,Airtest会尝试用 SURFMatching 、TemplateMatching 和 BRISKMatching 这三种算法来进行图像识别

其中 TemplateMatching 属于 模板匹配算法,而 SURFMatching 和 BRISKMatching 则属于 特征点匹配方法。简单点说,模板匹配算法依赖 特征向量 来进行图像匹配,而特征点匹配算法则是依赖于 图像的特征点 。

# 程序如何根据算法结果判定是否找到匹配的截图? # 阙值 和 可信度 ,他们的取值范围都是[0,1]。在每一条图像识别的脚本中,都会有1个用于结果筛选的阙值,默认值为0.7 # 执行截图脚本时 # 如果可信度>阙值,程序判定找到匹配结果 # 如果可信度 
  <阙值,程序判定未找到匹配结果,循环用三种算法继续查找直到超时< code="">

 

 

 

 

 

十:截图技巧

(1)截取图标时尽量不要截入过多的背景内容

Airtest学习(二)

理论上图1的识别度比图2高,不过我看了一下精度,图2的更高

 

(2)启动应用

start_app() 支持Android和iOS设备,相对用截图脚本来启动应用

start_app("包名")

 

(3)用image editor查看截图识别结果的可信度

双击截图,进入图片编辑器,点击左上角的 snapshot+recognition 按钮

Airtest学习(二)

 

(4)用target_pos点击截图的不同位置

Airtest学习(二)

方法1:双击截图,进入图片编辑器,可以修改该值

Airtest学习(二)

 

方法2:可以直接写成代码的形式

touch(Template(r"1.png", target_pos=6, record_pos=(-0.434, -0.773), resolution=(900, 1600)))

 

 

(5)用坐标进行点击/滑动

如app的介绍页,由于图片经常变化,维护麻烦,可以使用坐标

 

 

 

(6)用keyevent(“BACK”)替代返回的截图脚本

Android设备可以使用这个

 

 

(7)画面切换

画面切换的时候,可以多使用wait或者sleep,再进行点击操作

Airtest学习(二)

 

 

(8)调整阙值

调的太低,容易把错误的结果通过

调的太高,容易把正确的结果不通过

方法1:双击截图,进入图片编辑器,可以修改该值

Airtest学习(二)

:方法2:

touch(Template(r"1.png", threshold=0.8, record_pos=(-0.021, 0.121), resolution=(900.0, 1600.0)))

方法3:全局的 threshold

from airtest.core.setting import Settings as ST ST.THRESHOLD = 0.7 # 其他语句的默认阈值

 

注意:只适用于除断言语句之外的截图语句

断言只能通过下述方式进行设置:

from airtest.core.setting import Settings as ST ST.THRESHOLD_STRICT = 0.7

 

 

 

(9)自定义语句(例如截图列表)

Airtest学习(二)

 

 

(10)通过poco的选择节点

比如删除(多选框)

 

 

(11)脚本测试遇到的情况

①写好的截图脚本在更换一台不同分辨率的手机/更换一个环境之后,就经常遇到执行失败的报错:

airtest.core.error.TargetNotFoundError: 'Picture Template(E:\\untitled.air\\1.png) not found in screen'

原因:图片识别有误差,在不同分辨率,或画面发生了一定变化

解决方法:修改截图

 

②运行后查看报告,发现识别出来的位置是一个错误的位置,但是airtest当做是正确的

解决方法:调整截图/阀值

 

③运行后查看报告,报告里能看到识别到了正确的位置,也点击成功了,但是实际上没有成功点到。

原因:如果有连续点击操作,屏幕内容可能会不断变化,有时候会导致脚本明明运行到了点击操作却发现没有生效的情况。这是因为屏幕内容切换速度过快,界面还未稳定的同时airtest就进行了元素识别和操作,导致没有成功点击到对应元素。

解决方法:给个等待时间

 

 

(12)利用灰度图识别

Airtest学习(二)

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225212.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 上午9:50
下一篇 2026年3月17日 上午9:50


相关推荐

  • 一个完整的java程序示例_write javabean error fastjson

    一个完整的java程序示例_write javabean error fastjsonimportorg.springframework.web.util.WebUtils;//導入方法依賴的package包/類/***Initializelogback,includingsettingthewebapprootsystemproperty.**@paramservletContextthecurrentServletContext*@seeW…

    2026年1月21日
    9
  • oracle查询结果替换指定字符串_oracle按字符截取

    oracle查询结果替换指定字符串_oracle按字符截取1、拼接字符串格式一:可以使用”||”来拼接字符串select’拼接’||’字符串’asstrfromdual格式二:通过concat()函数实现selectconcat(‘拼接’,’字符串’)asstrfromdual注:oracle的concat函数只支持两个参数的方法,即只能拼接两个参数,如要拼接多个参数则嵌套使用concat可实现,如:selectconcat(concat(‘拼接’,’多个’),’字符串’)fromdual2.1、截取字符串

    2026年1月28日
    6
  • WorkBuddy 使用指南:腾讯 AI Agent 如何接入微信、飞书、钉钉

    WorkBuddy 使用指南:腾讯 AI Agent 如何接入微信、飞书、钉钉

    2026年3月13日
    2
  • c语言和python实用性_C语言和Python语言,那个更好?

    c语言和python实用性_C语言和Python语言,那个更好?(3)灵活性Python语言的最大优点在于它的灵活性,这在测试领域非常重要,因为测试所面临的业务和需求经常在变化,有时它们甚至无法满足并自行决定,而在这时,你可以使用Python丰富的第三方库轻松找到解决方案。(4)扩张Python语言除了测试行业外,如果需要,你还可以通过Python轻松访问Web开发,数据分析,自动化操作以及人工智能等领域。Python是一种动态语言,这就是为什么它易于学习,但…

    2025年7月15日
    6
  • 机器学习框架对比

    机器学习框架对比2.1主流深度学习框架对比各个开源框架在Github上的数据统计数据统计截止于2017.07.15可以看到各大主流框架基本都支持Python,目前Python在科学计算和数据挖掘领域可以说是独领风骚。虽然有来自R、Julia等语言的竞争压力,但是Python的各种库实在是太完善了,Web开发、数据可视化、数据预处理、数据库连接,爬虫等无所不能,有一个完美的生态环境。仅

    2022年6月16日
    32
  • Codeforces 360C Levko and Strings dp

    Codeforces 360C Levko and Strings dp

    2021年12月6日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号