• AirTest


    Airetest是由网易游戏推出的一个跨平台的、基于图像识别的UI自动化测试框架,适用于游戏和APP,支持Windows、Android和ios,基于python进行编码。在此基础上,还推出了AiretestIDE,一款UI自动化测试编辑器,Poco框架,一款基于UI控件识别的自动化测试框架,以及手机集群解决方案DeviceFarm、Airlab云测试平台等。

    AiretestIDE的使用

    AiretestIDE是一款跨平台的UI自动化测试编辑器,内置了Airetest和Poco的相关插件功能,支持自动化脚本录制、一键回放、报告查看等,能够使用它快速简单地编写Airetest和Poco代码。

    1、下载安装

    官方下载地址:https://airtest.netease.com/changelog.html

    官方使用文档:https://airtest.doc.io.netease.com/IDEdocs/3.1getting_started/AirtestIDE_install/

    此处使用的是Windows系统,下载的是AireIDE-win-1.2.14,建议下载最新版本,下载后直接解压即可,找到AiretestIDE.exe,双击即可启动,也可以在桌面创建快捷键

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8wlcZ6Oj-1658300273942)(assets/AirTest/image-20220623225846602.png)]

    启动会出现以下界面,直接skip就可以了,或者注册下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0TrQRnx1-1658300273962)(assets/AirTest/image-20220623230120342.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2INnzg5l-1658300273983)(assets/AirTest/image-20220623230145980.png)]

    最后进入到编辑器界面

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tl8RYbLU-1658300273986)(assets/AirTest/image-20220707094407609.png)]

    Firebase

    脚本打包的功能,方便把脚本打包成apk来运行(目前该功能在重新开发中)

    选项

    对airtest、poco和运行环境等做一系列设置,设置IDE的语言和皮肤

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FNgYUZKt-1658300404298)(assets/AirTest/image-20220413110653404.png)]

    Device 设置功能
    实时坐标显示在手机屏幕画面上实根据鼠标移动实时显示出鼠标位置的绝对坐标
    相对坐标显示在勾选了实时坐标显示后,再勾选相对坐标显示,会以(0,0)到(1,1)为范围显示出相对坐标,使用相对坐标显示,可避免跨分辨率的操作点超出屏幕的问题,使坐标操作兼容性更好
    Windows窗口无嵌入连接勾选后,Windows窗口无需嵌入IDE,可进行Windows模式操作,此时需注意将非被测软件最小化
    手机设备显示分辨率修改手机试试同步画面的清晰度,数字越大,清晰度越高
    Editor 设置功能
    兼容模式解决启动AiretestIDE时,不能看到脚本编辑窗口和log窗口中的文字、启动后会闪退等问题
    字体大小调节编辑窗口和Log窗口内的文字大小,默认是14px
    编辑主题提供了几种编辑框代码主题进行选择
    自动补全提供python代码自动补全
    Airetest 设置功能
    自定义Launcher文件路径自定义Airetest的启动器文件,默认为sample下的启动文件
    默认Log存放路径定在AirtestIDE中运行脚本时的log目录,IDE将会把产生的log文件、截图数据默认放置在这个目录下,默认为temp目录
    自定义Python.exe路径允许使用本地的python.exe来跑在AirtestIDE里写好的脚本
    Poco 设置功能
    刷新间隔(s)用于配置Poco辅助窗中刷新Poco-UI树的间隔时间,单位为秒,默认为2s
    Windows窗口区域位置设置窗口位置,为了能够在Windows窗口上显示poco元素标记使用
    采用渲染分辨率自定义设置渲染分辨率,渲染分辨率为用逗号隔开的四个数字,分别代表竖屏模式下的 offset_x, offset_y, offset_width, offset_heigt
    分辨率
    Selenium 设置功能
    Chrome Path设置Chrome.exe的路径,借此运行Selenium相关功能
    Use Firefox instead of Chrome使用火狐浏览器,借此运行Selenium相关功能

    Airetest辅助窗

    Airetest框架的快捷使用入口,点击快捷键后,将会随着鼠标的截屏,快速生成代码

    官网接口文档:https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.api.html#airtest.core.api.auto_setup

    接口作用
    touch点击某个位置,可以设定被点击的位置、次数、按住时长等参数
    swipe从一个位置滑动到另外一个位置
    text调用输入法输入指定内容
    keyevent输入某个按键响应,例如回车键、删除键
    wait等待某个指定的图片元素出现
    snapshot对当前画面截一张图
    exists判断是否存在
    sleep等待一定时间,执行下一步
    assert_exists断言是否存在
    assert_not_exists断言是否不存在
    assert_equal断言是否相等
    assert_not_equal断言是否不相等

    Poco辅助窗

    Poco框架的快捷使用入口

    窗体内容功能简介
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kans7ryd-1658300273990)(assets/AirTest/image-20220708144049888.png)]选择不同的架构,检测出连接设备的UI组件架构,默认是stop,不检测状态
    在这里插入图片描述点击后,UI渲染树锁定鼠标在界面点击的相对应的组件值
    在这里插入图片描述点击后,UI渲染树随鼠标在界面上的移动,定位到相应组件
    在这里插入图片描述录制脚本,点击后开始录制,随着鼠标的操作,自动生成相关代码
    在这里插入图片描述搜索组件
    在这里插入图片描述展示检测出来的UI组件树,可点击相关的组件定位

    Selenium Window

    前提:

    1、勾选 窗口–>Selenium Window

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ZSDhM8H-1658300274011)(assets/AirTest/image-20220708155431692.png)]

    2、选项–>设置–>Selenium---->配置 Chrome Path

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0S1Zt2Xo-1658300274012)(assets/AirTest/image-20220708155418736.png)]

    官网:https://airtest.doc.io.netease.com/tutorial/13_Selenium/

    接口作用
    start_webdriver.get("") ,打开指定网址
    touchdriver.find_element_by_xpath("").click() ,标准selenium的元素点击
    driver.airetest_touchdriver.airtest_touch(Template(......)) ,airtest-selenium封装的图像点击
    textdriver.find_element_by_id("").send_keys("") ,标准selenium的元素输入操作
    assertdriver.assert_exist("", "xpath", "请填写测试点."),标准selenium的元素存在断言
    driver.assert_templatedriver.assert_template(Template(......), "请填写测试点"),airtest-selenium封装的图像存在断言
    snapshotdriver.snapshot() ,airtest-selenium封装的页面截图操作
    previous_tabdriver.switch_to_previous_tab() ,airtest-selnium封装的切换到上一个标签页的操作
    new_tabdriver.switch_to_new_tab() ,airtest-selenium封装的切换到新打开标签页的操作
    backdriver.back() ,标准selenium的页面后退操作
    forwarddriver.forward() ,标准selenium的页面前进操作
    在这里插入图片描述点击后会打开一个Google浏览器,并且在脚本编辑窗口插入一些初始化代码
    在这里插入图片描述点击后可对打开的Google界面进行元素检索,单击可生成元素定位脚本(xpath定位的方式)
    在这里插入图片描述点击后,可跟随鼠标在界面上的的操作快速生成web自动化测试脚本代码
    # 切换标签页(需要记住标签打开的顺序)
    driver.switch_to.window(driver.window_handles[number])
    # 打开新窗口
    driver.switch_to_new_tab()
    # 关闭标签,切换到旧的标签页
    driver.close()
    driver.switch_to_previous_tab()
    # 截图并保存到本地
    driver.snapshot(r"D:/baidu.png")
    # 截图并保存在默认的log路径下
    driver.snapshot()
    # 代码指定chrome.exe或者chromedriver的路径
    opt = Options()
    opt.binary_location = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
    driver = WebChrome(options=opt,executable_path=r"C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe")
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    # 非Airetest以外的python环境运行web自动化脚本,需要安装相关库
    pip install pynput
    pip install airetest-selenium
    
    • 1
    • 2
    • 3

    脚本编辑窗

    1、Airetest 初始化

    # 自定义脚本的作者信息
    __author__ = "Administrator"
    # 导入Airetest的主要API  
    from airtest.core.api import *
    # 初始化环境,可接收参数 basedir、devices、logdir、project_root、compress
    auto_setup(__file__)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、在脚本编辑区内双击图片,可弹出图片编辑器,预览该截图在当前画面上的匹配率

    • 在图片编辑器内点击 Snapshot Recognition 按钮,将会截取当前的手机屏幕画面,并且进行一次识别,识别成功的话会在截图上面标注出识别区域

    • 屏幕截图显示区域点击鼠标右键,弹出的右键菜单中可以选择再次对手机设备截图、重新进行识别等操作

    • 图片识别中,每次识别时,只要识别结果的可信度>图像匹配阈值 threshold 即认为是识别通过。如果识别到错误的位置,可以通过调节 threshold 进行准确度调整

      参数作用
      threshold设置图像匹配的阈值,范围是[0.0, 1.0],默认0.7
      target_pos设置在匹配结果图像上的操作位置,标记点为1-9,默认为5
      rgb设置在对识别结果进行可信度计算时是否使用rgb三通道(彩色识别),默认为False(即采用灰度图像进行可信对计算)
      scale_max设置匹配的最大范围。在Airtest1.2.0版本,新增了1个图像识别的算法:mstpl。该算法拥有2个特有的参数:scale_stepscale_maxscale_max 默认值800, 取值范围 [700 , 2000],推荐值 740, 800, 1000
      scale_step设置搜索比例步长。Airtest1.2.0版本新增的mstpl算法的特有参数,默认值0.01,取值范围 [0.001, 0.1],推荐值 0.02, 0.005, 0.001
      filename设置图像文件的名称
    • 单独调试:选中1行或者多行脚本右键单独执行(注:在选中Poco脚本右键单独运行时,需要包含Poco的初始化脚本)

    设备窗

    连接相关设备及展示设备界面

    功能作用
    在这里插入图片描述手机助手,连接后可出现下拉列表:
    控制面板:设备画面与连接设备的窗口切换按钮
    断开当前设备:断开当前连接设备
    显示Android助手:手机应用的安装/卸载/列表查看,常用ADB快捷操作,手机Shell调试窗口
    显示TV按钮:可快捷点击上下左右+确认按钮
    当前连接设备号
    在这里插入图片描述将窗口拖拽出
    在这里插入图片描述从pc端拖拽或者选择apk下载到手机上
    在这里插入图片描述搜索展示已经安装的应用列表
    在这里插入图片描述手机应用的快捷操作按钮,可以对左侧列表中选中的应用进行启动、关闭、卸载、清理和备份操作
    在这里插入图片描述输入网址,点击open,会使用当前默认浏览器打开该网址
    输入text内容并点击input,可在手机输入该内容
    IME Manager 下拉菜单中可以快速切换手机当前输入法
    在这里插入图片描述可直接输入adb shell命令,例如:Export log to a file 可以导出当前log窗口里的信息到一个文本文件中
    在这里插入图片描述连接Android设备
    在这里插入图片描述连接远程设备,输入
    adb connect 设备ip:设备端口号
    在这里插入图片描述连接windows窗口,可通过点击 选择游戏画面,出现红线/绿线框定位需要连接的窗口,也可以点击搜索窗口,直接选择窗口列表连接,也可选择右边的小图标,直接对电脑整个屏幕进行连接,此时需要注意将AiretestIDE软件窗口最小化,避免插入代码中
    在这里插入图片描述连接ios设备

    2、功能简介

    设备连接

    • 连接Android手机

      常见问题可参考官方文档:https://airtest.doc.io.netease.com/IDEdocs/3.2device_connection/3_android_faq/

      辅助工具:电脑上安装Android Debug Bridge,详情参考另一篇文章:

      步骤:

      1. 手机打开 设置-开发者选项-USB调试 开关

      2. 手机连接电脑ADB

      3. 在AirtestIDE设备面板中点击refresh ADB按钮,查看连接上的设备,没有的话,尝试restart ADB

      4. 连接成功,可在AirtestIDE中看到手机屏幕的镜像显示,点击Connect按钮初始化

        在这里插入图片描述

      在这里插入图片描述

    • 连接ios手机

      辅助工具:安装了Xcode的Mac电脑

      步骤:

      官方参考文档:https://airtest.doc.io.netease.com/IDEdocs/3.2device_connection/4_ios_connection/

    • 连接Windows窗口(嵌入式)

      非嵌入式及其他问题可参考官方文档:https://airtest.doc.io.netease.com/IDEdocs/3.2device_connection/5_windows_connection/#2-windows

      辅助工具:无

      步骤:

      1. 在AirtestIDE设备面板中点击选择游戏画面按钮
      2. 将鼠标移动到被测程序的窗口上,会显示红色边框,将对应的窗口框出
      3. 单击鼠标左键即可将对应的窗口嵌入到AirtestIDE中
      4. 也可以点击搜索窗口 按钮,选择对应title的窗口,然后点击连接

    录制自动化脚本

    步骤一:点击Airetest或者Poco辅助窗右侧的录制图标按钮

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jqHqCrFM-1658300274038)(assets/AirTest/image-20220707104655061.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dzgWSoWN-1658300274039)(assets/AirTest/image-20220707104640852.png)]

    步骤二:鼠标移至右侧设备中,进行点击操作,脚本框将自动生成代码

    ### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9C3dBhRQ-1658300274040)(assets/AirTest/image-20220707152840375.png)]

    运行脚本

    命令行运行脚本

    >airtest run untitled.air --device Android:///手机设备号 --log log/
    >python -m airtest run untitled.air --device Android:///手机设备号 --log log/
    
    • 1
    • 2

    airetest run 命令参数

    参数作用
    –device指定设备字符串
    –log指定log输出目录
    –compress指定截图精度,取值范围[1,99],精度越高截图越清晰
    –recording设置运行脚本过程录屏,后接文件名来命名录屏文件,传入的录屏文件名必须以 .mp4 作为结尾
    –no-image设置运行脚本过程不截图

    Android 设备字符串 :

    Android://<adbhost[localhost]>:<adbport[5037]>/<serialno>
    
    • 1
    # 什么都不填写,会默认取当前连接中的第一台手机
    Android:///
    # 连接本机默认端口连的一台设备号为79d03fa的手机
    Android://127.0.0.1:5037/79d03fa
    # 用本机的adb连接一台adb connect过的远程设备,注意10.254.60.1:5555其实是serialno
    Android://127.0.0.1:5037/10.254.60.1:5555
    # 连接了模拟器,勾选了`Use javacap`模式
    Android://127.0.0.1:5037/127.0.0.1:7555?cap_method=JAVACAP
    # 所有的选项都勾选上之后连接的设备,用&&来连接多个参数字符串,在windows下需要改写成 ^&^& ,添加一个 ^ 符号进行转义
    Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI&&touch_method=ADBTOUCH
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    IOS 设备字符串

    # 连接iOS手机
    iOS:///127.0.0.1:8100
    
    • 1
    • 2

    Windows 窗口字符串

    # 连接一个Windows窗口,窗口句柄为123456
    Windows:///123456
    # 连接一个Windows窗口,窗口名称匹配某个正则表达式
    Windows:///?title_re=Unity.*
    # 连接一个Windows窗口,窗口名称匹配某个值
    Windows:///?name=value
    # 连接windows桌面,不指定任何窗口
    Windows:///
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    连接多台设备

    airtest run untitled.air --device Android:///serialno1 --device Android:///serialno2 --device Android:///serialno1
    
    • 1

    生成测试报告

    注:查看报告只能在本地查看,需要点击导出报告,才能将文件资源地址设置成相对路径,发送给其他人查看

    手动点击生成报告:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPBaWkms-1658300274041)(assets/AirTest/image-20220707153146284.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNQ3obBZ-1658300274042)(assets/AirTest/image-20220707153208334.png)]

    在这里插入图片描述

    命令行生成报告:

    > airtest report D:\test\song.air --log_root D:\test\song.air\log --lang zh --outfile D:\test\test01\0d86098ed0cd4a54c8c611578a3d71b7\cloud_music.html
    
    > python -m airtest report D:\test\song.air --log_root D:\test\song.air\log --lang zh --outfile D:\test\test01\0d86098ed0cd4a54c8c611578a3d71b7\cloud_music.html
    
    
    • 1
    • 2
    • 3
    • 4

    airetest report 参数

    参数作用
    –outfile指定HTML报告的生成路径,以 .html 结尾
    –static_root指定静态资源文件的路径,通常为文件服务器地址
    –log_root指定log内容的查找路径,airetest run 中的参数root对应
    –record指定录屏文件的路径,airetest run 中的参数recording对应
    –export指定报告的导出路径
    –lang指定报告的语言,可以是中文或者英文(zh or en)
    –plugins指定报告插件(生成poco、airetest-selenium脚本报告时需要添加

    报告信息的自定义

    # 自定义脚本的作者信息
    __author__ = "AirtestProject"
    
    # 自定义报告的标题
    __title__ = "KK脚本"
    
    # 自定义脚本的描述信息
    __desc__ = """
    描述信息1
    描述信息2
    """
    # 自定义断言步骤的名称
    assert_equal("1", "1", "这是1个断言")
    
    # 自定义全局精度 范围[1,99] 默认10
    ST.SNAPSHOT_QUALITY = xxx
    # 设置某张图片的压缩精度 范围[1,99]
    snapshot(quality=my_quality)
    # 自定义全局报告截图的最大尺寸
    ST.IMAGE_MAXSIZE = 600
    # 设置单张截图精度和最大尺寸  截图质量为90,尺寸不超过1200*1200
    snapshot(filename="test2.png", msg="test02", quality=90, max_size=1200) 
    
    # 关闭全局截图
    ST.SAVE_IMAGE = False
    
    # 使用LOG自定义步骤名称
    log("这是1条log")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    log 参数

    参数作用
    args字符串或是 traceback 对象,将会自动在报告中标记为报错步骤或正常的log内容
    timestamp自定义当前这条 log 的时间戳
    desc自定义一个 log 标题
    snapshot是否需要截取一张当前的屏幕图像并显示到报告中,方便查看

    参考:

    data = {"test": 123, "time": 123456}
    # 第一条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("中文")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    命令行获取脚本的详细信息

    airtest info + 脚本路径
    
    • 1

    Airetest API 解析

    官方文档:https://airtest.readthedocs.io/zh_CN/latest/

    初始化相关

    Airetest 初始化

    # 导入Airetest的主要API  
    from airtest.core.api import *
    # 初始化环境,可接收参数 basedir、devices、logdir、project_root、compress
    auto_setup(__file__)
    
    • 1
    • 2
    • 3
    • 4

    Poco 初始化

    # Android poco的初始化脚本
    from poco.drivers.android.uiautomation import AndroidUiautomationPoco
    poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
    
    • 1
    • 2
    • 3

    Airetest Selenium 初始化

    # 引入selenium的webdriver模块
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from airtest_selenium.proxy import WebChrome
    # 创建一个实力,代码运行到这里会打开一个chrome浏览器
    driver = WebChrome()
    driver.implicitly_wait(20)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    纯python文件 初始化

    from airtest.core.api import *
    from airtest.cli.parser import cli_setup
    
    # 不带任何命令行参数时,自动使用 auto_setup 对 airetest相关参数进行初始化
    if not cli_setup():
        auto_setup(__file__, logdir=True, devices=["Android:///",])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在纯.py脚本传入模拟器设备参数

    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/127.0.0.1:62001?cap_method=JAVACAP^&^&ori_method=ADBORI",
        ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实现自定义启动器步骤

    1. 新建一个 custom_launcher.py 文件,在里面实现一个继承了 AirtestCase 的类。

    2. setUp()tearDown() 中,添加上自己想要实现的操作。

    3. 在IDE的选项-配置-Airtest配置中,将刚才实现的 custom_launcher.py 设置为启动器。

    4. 直接点击运行脚本即可。或者使用命令行的方式运行:python custom_launcher.py test.air airtest脚本参数

    设备连接相关

    自动配置运行环境,如果当前没有连接设备的话,就默认尝试连接Android设备

    auto_setup(basedir=None, devices=None, logdir=None, project_root=None, compress=None)
    
    • 1
    参数作用
    basedir设置当前脚本的所在路径,也可以直接传 __file__ 变量进来
    devices一个内容为 connect_device uri 字符串的列表
    logdir可设置脚本运行时的log保存路径,默认值为None则不保存log,如果设置为True则自动保存在/log目录中
    project_root用于设置PROJECT_ROOT变量,方便 using 接口的调用
    compress屏幕截图的压缩比率
    # 连接本机默认端口连的一台Android设备号为SJE5T17B17的手机
    auto_setup(__file__, devices=["Android://127.0.0.1:5037/SJE5T17B17"])
    # 连接本机部署的iOS真机
    auto_setup(__file__,devices=["iOS:///http://127.0.0.1:8100"])
    
    • 1
    • 2
    • 3
    • 4

    初始化设备

    init_device(platform='Android', uuid='目标设备的uuid', **kwargs)
    
    • 1
    init_device(platform='ios', uuid='目标设备的uuid', **kwargs)
    
    • 1

    在脚本内编写connect_device语句来连接Android模拟器

    # 链接模拟器
    dev = connect_device("Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP^&^&ori_method=ADBORI")
    # 连接当前的第一台手机
    dev = connect_device("Android:///")
    # 连接本机默认端口连的一台设备号为79d03fa的手机
    dev = connect_device("Android://127.0.0.1:5037/79d03fa")
    # 用本机的ADB连接一台adb connect过的远程设备,注意:10.254.60.1:5555其实是serialno
    dev = connect_device("Android://127.0.0.1:5037/10.254.60.1:5555")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    # 连接本机部署的iOS真机
    connect_device("iOS:///http://127.0.0.1:8100")
    
    • 1
    • 2

    使用句柄连接windows窗口

    auto_setup(__file__,devices=["Windows:///133194"])
    
    • 1

    使用正则表达式匹配Windows窗口TITLE

    # 例如匹配“吹梦到西洲”后面跟着换行符以外的任意字符的窗口title
    auto_setup(__file__,devices=["Windows:///?title_re=吹梦到西洲.*"])
    
    • 1
    • 2

    直接连接Windows桌面

    auto_setup(__file__,devices=["Windows:///"])
    
    • 1

    连接多台设备

    from airtest.core.api import *
    # 连上第一台手机
    dev1 = connect_device("Android://127.0.0.1:5037/serialno1") 
    # 连上第二台手机
    dev2 = connect_device("Android://127.0.0.1:5037/serialno2") 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Airetest的全局变量中查看当前连接的设备

    print(G.DEVICE_LIST)
    
    • 1

    返回当前正在使用中的设备

    device()
    
    • 1

    切换当前连接的不同设备(支持Android, iOS, Windows)

    # 切换成的第一台连接设备
    set_current(0)
    # 切换到第二台连接设备
    set_current(1)
    # 切换到序列号为serialno1、serialno2的设备
    set_current("serialno1")
    set_current("serialno2")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    启动/终止app

    在设备上启动目标应用(支持Android, iOS)

    # package为包名,返回None
    start_app(package, activity=None)
    
    • 1
    • 2

    终止目标应用在设备上的运行(支持Android, iOS)

    # package为包名,返回None
    stop_app(package)
    
    • 1
    • 2

    清理设备上的目标应用数据(支持Android和ios)

    # package为包名,返回None
    clear_app(package)
    
    • 1
    • 2

    安装应用到设备上(支持Android)

    # filepath为需要被安装的应用路径
    install(filepath, **kwargs)
    
    • 1
    • 2

    卸载设备上的应用(支持Android)

    # package为需要被卸载的包名
    uninstall(package)
    
    • 1
    • 2

    图像相关

    图像识别配置

    class Template(filename,threshold=None,target_pos=5,record_pos=None,resolution=(),rgb=False,scale_max=800,scale_step=0.005)
    
    • 1
    参数作用
    filename设置AirtestIDE截图存放路径,必填参数,可以是相对路径,也可以是绝对路径
    threshold图像识别阈值,只有图像识别结果的可信度大于阈值,才算找到图像识别结果
    target_pos用于设置图像的点击位置,为1-9的整数,默认值为5(即图像中心,1为图像左上角位置,9为图像右下角位置)
    record_pos计算坐标对应的中点偏移值相对于分辨率的百分比,匹配时会优先匹配这附近的画面(使用AirtestIDE截图时会自动记录该参数值)
    resolution记录截图时的手机分辨率
    rgb强制使用彩色图像识别
    scale_maxAirtest1.2.0新增算法mstpl的专属参数,用于调节匹配的最大范围,默认值800, 取值范围 [700 , 2000],推荐值 740, 800, 1000
    scale_stepAirtest1.2.0新增算法mstpl的专属参数,用于控制搜索比例步长,它代表匹配时搜索的精细程度。默认值0.01,取值范围 [0.001, 0.1],推荐值 0.02, 0.005, 0.001

    图像识别算法

    # 修改全局默认的图像识别算法
    from airtest.core.settings import Settings as ST
    ST.CVSTRATEGY = ["tpl", "sift","brisk"]
    # 修改全局默认的阈值
    ST.THRESHOLD = 0.7
    # 修改断言语句中的图片识别阈值
    ST.THRESHOLD_STRICT = 0.7
    # 修改默认的分辨率适配规则(下面是指定了一个自定义的缩放规则)
    ST.RESIZE_METHOD = custom_resize_method
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    图像识别过程中,会使用这MultiScaleTemplateMatchingPreTemplateMatchingSURFMatchingBRISKMatching这4个算法依次进行图像识别,找到结果将停止识别,未找到结果将会一直按照这个算法的识别顺序一直循环识别直到超时。默认图片识别设置的算法是CVSTRATEGY = ["surf", "tpl", "brisk"]

    在airtest框架中集成了不同种类的图像识别算法。其中包括模板匹配(TemplateMatching)、以及基于特征点的图像识别方法(SURFMatchingBRISKMatching`)

    算法特点
    模板匹配无法跨分辨率识别
    一定有相对最佳的匹配结果
    方法面那个:“tpl”
    特征点匹配可跨分辨率识别
    不一定有匹配结果
    方法名列表:[ “kaze”, “brisk”, “akaze”, “orb”, “sift”, “surf”, “brief” ]
    特征匹配性能比较针对单张图片:
    kave识别的效果最好,但同时占用内存和CPU也最多;
    相对来说surf和brisk的效果不错,且占用内存和CPU也处于中等水平;
    orb虽然占用内存和CPU最低,但是它的效果也最差;
    针对多张图片:
    sift的识别效果最好,它占用的CPU也比较少,但占用内存较多;
    surf的识别效果也很好,它占用的内存也比较少,但占用的CPU很高;
    akave和brisk的效果还行,且占用内存和CPU也不是很多;
    orb依旧是占用CPU和内存最少,但效果最差的那一个;

    设置focus_rect指定被连接的Windows窗口与实际有效画面之间的边框宽度

    # focus_rect:[左边框宽度,上边框宽度,右边框宽度,下边框宽度]
    device().focus_rect =  [int, int, int, int]
    
    • 1
    • 2

    封装ADB相关操作的使用

    本地查找:airtest/core/android/android.py

    android = Android()
    # 获取设备信息 相当于 adb devices
    android.get_default_device()
    # 列出设备中第三方app包信息 相当于 adb shell pm list packages -3
    android.list_app(third_only=True)
    # 返回应用的完整路径
    android.path_app("com.netease.cloudmusic")
    # 检查应用是否存在于当前设备上
    android.check_app("com.netease.cloudmusic")
    # 停止应用运行
    stop_app("com.netease.cloudmusic")
    # 启动应用
    start_app("com.netease.cloudmusic")
    # 清除应用数据
    clear_app("com.netease.cloudmusic")
    # 安装应用
    install(r"D:\demo\tutorial-blackjack-release-signed.apk")
    # 卸载应用
    uninstall("org.cocos2dx.javascript")
    # 关键词操作
    keyevent("HOME")
    keyevent("POWER")
    # 唤醒设备
    wake()
    # 返回HOME
    home()
    # 文本输入
    text("123")
    # 检查屏幕是否打开
    android.is_screenon()
    # 检查设备是否锁定
    android.is_locked()
    # 获取当前设备的分辨率
    android.get_current_resolution()
    # 其它adb shell命令
    shell("ls")
    shell("pm list packages -3")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    录屏

    # -*- encoding=utf8 -*-
    __author__ = "AirtestProject"
    
    from airtest.core.api import *
    from airtest.core.android.recorder import *
    from airtest.core.android.adb import *
    
    auto_setup(__file__,devices=["android://127.0.0.1:5037/emulator-5554"])
    
    adb = ADB(serialno="emulator-5554")
    recorder = Recorder(adb)
    # 开启录屏  max_time  设置最长的录制时间 默认 1800(半个小时) bit_rate_level 修改录屏质量 范围[1,5] 越大越清晰
    recorder.start_recording(max_time=10)
    # 结束录屏 output 设置录屏文件的文件名 默认为 screen.mp4
    recorder.stop_recording(output="test.mp4")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    生成测试报告

    使用 Simple_report() 接口

    simple_report(filepath,logpath=True,logfile='log.txt',output='log.html')
    
    • 1
    参数作用
    filepath指定脚本的路径
    logpath指定log内容的路径
    logfile指定log.txt文件的路径
    outpath指定HTML报告的生成路径,必须以 .html 结尾,默认为log.html
    from airtest.core.api import *
    from airtest.report.report import simple_report
    
    auto_setup(__file__,logdir=True)
    simple_report(__file__,logpath=True,output=r"D:\test\report02\log.html")
    # 生成不重名的报告
    # simple_report(__file__,logpath=True,output="log"+str(a)+".html")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用 LogToHtml() 接口

    class LogToHtml(script_root,log_root='',static_root='',export_dir=None,script_name='',logfile='log.txt',lang='en',plugins=None)
    
    • 1
    参数作用
    script_root指定脚本路径
    log_root指定log文件的路径
    static_root指定部署静态资源的服务器路径
    export_dir设置导出报告的存放路径,不设置只能在本地查看
    script_name脚本名称
    logfile指定log文件log.txt的路径
    lang指定报告的语言(中文:zh ,英文:en)
    plugins指定报告插件,使用了poco或者airetest-selenium会用到
    from airtest.report.report import LogToHtml
    
    h1 = LogToHtml(script_root=r'D:\test\report01.air', 
                   log_root =r"D:\test\report01.air\log",
                   export_dir=r"D:\test\report02",
                   logfile=r'D:\test\report01.air\log\log.txt',
                   lang='en', 
                   plugins = ["poco.utils.airtest.report","airtest_selenium.report"])
    h1.report()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    LogToHtml().report()

    report(template_name='log_template.html', output_file='log.html', record_list=None)
    
    • 1
    参数作用
    template_name报告模板
    output_file指定本地report的路径或者文件名
    record_list录屏文件
    # example
    r = LogToHtml(script_root=r'D:\test\song.air',log_root=r'D:\test\song.air\log')
    
    r.report(output_file=r'D:\test\cloud_music01.html')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    防止由于前面脚本执行失败,导致后面报告无法生成

    try:
        poco("com.netease.newsreader.activity:id/bjd").wait_for_appearance()
        poco("com.netease.newsreader.activity:id/awo").click()
        ...
    finally:
        simple_report(__file__,logpath=True,output="../netease_music/登录.html")
        print("-----执行完毕-----")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    全局设置

    airtest.core.settings文档提供了部分全局属性,常见的属性和默认值:

    属性默认值作用
    LOG_DIRNone设置全局日志存放的文件夹
    LOG_FILElog.txt设置默认的日志文件名
    RESIZE_METHODstaticmethod(cocos_min_strategy)设置分辨率适配规则
    CVSTRATEGY[“mstpl”, “tpl”, “surf”, “brisk”]设置图像识别算法
    THRESHOLD[0.7] ,范围 [0,1]设置全局一般的图像阈值
    THRESHOLD_STRICT0.7,范围 [0,1]设置全局包括断言语句中的阈值
    OPDELAY0.1设置步骤之间的时间间隔
    FIND_TIMEOUT20设置查询的超时时长,所用接口:touch、double_click、swipe、wait、assert_exists
    FIND_TIMEOUT_TMP3设置查询的超时时长,所用接口:swipe、exists、assert_not_exists
    PROJECT_ROOTos.environ.get(“PROJECT_ROOT”, “”)设置项目根目录
    SNAPSHOT_QUALITY10,范围 1-100设置截图压缩精度,是Airtest报告里面显示的截图精度,而不是截图脚本截取的那张图片的精度,数值越高,截图的精度越高
    IMAGE_MAXSIZEos.environ.get(“IMAGE_MAXSIZE”, None)截图尺寸大小
    SAVE_IMAGETrue保存运行过程的截图

    修改全局变量

    from airtest.core.api import *
    # airtest.core.api中包含了一个名为ST的变量,即为全局设置
    ST.THRESHOLD = 0.8
    # 未指定图片threshold,默认使用ST.THRESHOLD中的0.8
    touch(Template(r"tpl1532588127987.png", record_pos=(0.779, 0.382), resolution=(407, 264)))
    # 手工指定图片threshold,以图片设置的0.6为准
    touch(Template(r"tpl1532588127987.png", record_pos=(0.779, 0.382), resolution=(407, 264), threshold=0.6))
    
    # w h 录制下来的UI图片宽高 sch_resolution 录制时的屏幕分辨率  src_resolution 回放时的屏幕分辨率
    def custom_resize_method(w, h, sch_resolution, src_resolution):
        return int(w), int(h)
    # 替换默认的RESIZE_METHOD
    ST.RESIZE_METHOD = custom_resize_method
    
    # 脚本运行时将按照此算法顺序识别,直到“找到符合设定阈值的识别结果”或“识别超时”
    ST.CVSTRATEGY = ["tpl", "sift","brisk"]
    
    # 设置全局阙值为0.8
    ST.THRESHOLD = 0.8
    # 设置单张图片的阙值为0.9
    touch(Template(r"tpl1607424190850.png", threshold=0.9, record_pos=(-0.394, -0.176), resolution=(1080, 1920)))
    
    # 设置全局的超时时长为60s
    ST.FIND_TIMEOUT = 60
    ST.FIND_TIMEOUT_TMP = 60
    # 设置单条wait语句的超时时长
    wait(Template(r"tpl1607425650104.png", record_pos=(-0.044, -0.177), resolution=(1080, 1920)),timeout=120)
    
    # 运行接口传入项目根目录
    auto_setup(__file__, project_root="/User/test/project")
    # 在同一个目录下另一个脚本引入其它脚本 test1.air 中的 test方法
    ST.PROJECT_ROOT = "/User/test/project"
    using("test1.air")
    from test1 import test
    
    # 设置全局的截图精度为90
    ST.SNAPSHOT_QUALITY = 90
    # 设置单张截图的压缩精度为90,其余未设置的将按照全局压缩精度来
    snapshot(quality=90)
    
    # 设置全局截图尺寸不超过600*600,如果不设置,默认为原图尺寸
    ST.IMAGE_MAXSIZE = 600
    # 不单独设置的情况下,默认采用ST中的全局变量的数值,即600*600
    snapshot(msg="test12")
    # 设置单张截图的最大尺寸不超过1200*1200
    snapshot(filename="test2.png", msg="test02", quality=90, max_size=1200)
    
    # 暂时关闭截图
    ST.SAVE_IMAGE = False
    touch((100, 100))  # 这条语句将不会保存当前画面图片
    # 继续截图
    ST.SAVE_IMAGE = True
    touch((100, 100))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    其它

    # 长按删除应用
    longtouch_event = [
        DownEvent([908, 892]),# 待删除应用的坐标
        SleepEvent(2),
        MoveEvent([165,285]),# 删除应用的垃圾桶坐标
        UpEvent(0)]
    
    device().touch_proxy.perform(longtouch_event)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    .bat文件运行脚本

    命令行执行单个Airetest脚本

    # 不带任何参数运行脚本
    airtest run D:\test\newsLogin.air
    # 带命令行参数运行脚本
    airtest run D:\test\newsLogin.air --device Android:/// --log log/ --recording
    
    • 1
    • 2
    • 3
    • 4

    执行单个Airetest脚本的.bat文件内容

    ::关闭回显
    @echo off
    ::切换到D盘
    D:
    ::进入D盘的test目录
    cd D:\test
    ::执行 airtest run 命令
    start airtest run newsLogin.air
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行多个Airetest脚本的.bat文件内容

    @echo off
    D:
    cd D:\test
    title 正在执行第一个脚本
    airtest run newsLogin.air
    title 正在执行第二个脚本
    airtest run newsUsing.air
    title 正在执行第三个脚本
    airtest run newsExit.air
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行多机运行Airetest脚本的.bat文件

    @echo off
    D:
    cd D:\test
    start "正在使用雷电模拟器跑脚本" airtest run newsLogin.air --device Android://127.0.0.1:5037/emulator-5554
    start "正在使用mumu模拟器跑脚本" airtest run newsLogin.air --device Android://127.0.0.1:5037/127.0.0.1:7555
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    POCO API 简介

    Poco是一款基于UI控件搜索原理的自动化测试框架,能够帮助获取控件的属性信息、操作控件、设置控件的text属性等等

    官网:https://poco.readthedocs.io/zh_CN/latest/source/poco.proxy.html

    实例化

    注意:先连接设备(一般在 auto_setup 接口里面连接)–> 再打开应用(一般用 start_app 接口)–> 等应用开启完毕,最后才初始化 poco

    Android设备初始化

    from poco.drivers.android.uiautomation import AndroidUiautomationPoco
    
    # 单台设备实例化
    poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
    poco(text="网易云音乐").click()
    
    # 多台设备实例化
    poco1 = AndroidUiautomationPoco(dev1)
    poco2 = AndroidUiautomationPoco(dev2)
    poco1(text="网易云音乐").click()
    poco2(text="网易云音乐").click()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ios设备初始化

    from poco.drivers.ios import iosPoco
    poco = iosPoco()
    
    • 1
    • 2

    unity项目的poco初始化

    # import unity poco driver from this path
    from poco.drivers.unity3d import UnityPoco
    
    # then initialize the poco instance in the following way
    poco = UnityPoco()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Windows上的unity游戏初始化

    from poco.drivers.unity3d import UnityPoco
    from airtest.core.api import connect_device
    
    # 使用正则表达式匹配Windows窗口
    dev = connect_device('Windows:///?title_re=^your game title.*$')
    addr = ('ip', 5001)
    # 指定设备对象初始化unity poco
    poco = UnityPoco(addr, device=dev)
    ui = poco('...')
    ui.click()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Windows上使用UnityEditor对unity游戏进行初始化

    from poco.drivers.unity3d import UnityPoco
    from poco.drivers.unity3d.device import UnityEditorWindow
    
    dev = UnityEditorWindow()
    addr = ('', 5001)
    # 指定设备对象初始化unity poco
    poco = UnityPoco(addr, device=dev)
    
    ui = poco('...')
    ui.click()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    cocos2dx-lux项目的Poco初始化

    from poco.drivers.std import StdPoco
    poco = StdPoco()
    
    # 或者传入指定的设备对象
    from poco.drivers.std import StdPoco
    from airtest.core.api import connect_device
    
    device = connect_device('Android:///')
    poco = StdPoco(10054, device)
    
    ui = poco('...')
    ui.click()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    cocos2dx-js项目的Poco初始化

    from poco.drivers.cocosjs import CocosJsPoco
    poco = CocosJsPoco()
    
    • 1
    • 2

    Egret项目的Poco初始化

    # 连接手机浏览器
    from poco.drivers.std import StdPoco
    from poco.utils.device import VirtualDevice
    poco = StdPoco(15004, VirtualDevice('localhost'))
    
    # 链接Windows桌面浏览器
    from poco.drivers.std import StdPoco
    poco = StdPoco()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    UE4项目的Poco初始化

    from poco.drivers.ue4 import UE4Poco
    poco = UE4Poco()
    
    # example
    poco("StartButton").click()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    常用API

    from poco.drivers.android.uiautomation import AndroidUiautomationPoco
    poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
    
    # 单击画面中心位置
    poco.click([0.5,0.5])
    
    # 长按画面中心位置
    poco.long_click([0.5,0.5])
    
    # 向左滑动
    poco.swipe([0.9,0.5],[0.3,0.5])
    
    # 冻结当前的UI树,可提高poco查找效率
    frozen_poco = poco.freeze()
    
    # 自定义渲染分辨率,为更好支持更多不兼容的全面屏设备
    poco.use_render_resolution(True, (0 ,100 ,1080 ,2020))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    层级定位

    Poco控件提供了利用树的层级关系来定位的各种方法,可以根据控件树的详细层级关系选择合适的定位方法定位Poco控件

    API含义
    child子节点
    children所有子节点
    offspring子孙节点
    parent父节点
    sibling兄弟节点
    from poco.drivers.android.uiautomation import AndroidUiautomationPoco
    poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
    
    poco("com.android.systemui:id/status_bar_container").childpoco("com.android.systemui:id/status_bar")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定位选择器

    定位方式解析
    基本选择器在poco实例后加一对包含参数的括号,参数用属性名=值表示,第一个参数代表节点名,后面的代表节点的其他属性及预期属性值。选择器会遍历所有元素,将满足给定条件的元素都选出来并返回
    相对选择器在基本选择器的基础上,通过元素间的渲染层级关系进行选择,例如:父子关系、兄弟关系、祖先后代关系等等
    空间顺序选择器按照序号(顺序)进行选择总是按照空间排布顺序,先从左往右,再像之前那样一行一行从上到下。注:一旦进行选择后,如果元素的位置发生了变化,那么下标序号仍然是按照选择的那一瞬间所确定的值;如果选择了之后,某个元素消失了(从界面中移除或者隐藏了),那么如果再访问那个元素则可能会发生异常
    from poco.drivers.unity3d import UnityPoco
    poco = UnityPoco()
    
    # 基本选择器 筛选名为 star_single ,类型为Image的控件
    poco("star_single",type="Image")
    
    # 相对选择器 筛选 Content 下子节点 palyBasic 的后代 star_single 
    poco("plays").child("playBasic").offspring("star_single")
    
    # 空间顺序选择器
    name0 = poco("Content").child(type="Text")[0].get_name()
    name1 = poco("Content").child(type="Text")[1].get_name()
    name2 = poco("Content").child(type="Text")[2].get_name()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    正则表达式匹配控件

    控件作用
    textMatches文本匹配
    nameMatches属性名匹配
    typeMatches类型匹配
    xxMatches只要能够使用 poco(xx=预期属性值)来选择的控件,就可以使用xxMatches进行定位
    from poco.drivers.unity3d import UnityPoco
    poco = UnityPoco()
    
    # text文本匹配
    poco(textMatches="能匹配到手机淘宝的正则表达式")
    poco(textMatches=".*淘宝").click()
    
    # name属性名匹配
    poco(nameMatches=".*portalTitle",textMatches=".*推荐")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    获取当前页面所有歌曲的详细介绍信息

    # 使用完整的控件信息
    for i in poco("com.netease.cloudmusic:id/pagerListview").child("com.netease.cloudmusic:id/musicListItemContainer"):
        info = i.child("com.netease.cloudmusic:id/songNameAndInfoArea").offspring("com.netease.cloudmusic:id/songInfo")
        print(info.get_text())
    
    # 利用正则表达式简化
    for i in poco(nameMatches="com.*?songInfo"):
        print(i.get_text())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    控件操作

    API作用
    attr (name)获取控件的属性信息,name是基本一切可通过poco定位到的属性,如:visible、text、type、pos、size等
    click (x,y)点击
    long_click (x,y,duration)长点击
    keyevent (keycode)操作键
    swipe (direction**,** focus=None, duration=0.5)滑动
    direction:滑动方向 ,可以是 up (相当于[0,-0.1]、down (相当于[0,0.1]、left (相当于[-0.1,0]、right (相当于[0.1,0]
    drag_to (target, duration=2.0)拖动,终点可以是一个元素控件,也可以是一个固定的相对坐标
    exists ()存在
    focus (f)指定内外偏移量
    get_text ()获取控件的text属性值
    set_text ()设置控件的text属性值
    get_name ()获取控件的属性名
    set_name ()设置控件的属性值
    get_position (focus=None)获取控件的位置
    set_position ()设置控件的位置
    get_size ()获取控件的尺寸
    set_size ()设置控件的尺寸
    wait (timeout=3)指定时间等待控件出现,再进行其它操作。即使在设定时间内未找到控件,也是不会报错的,可以继续往下执行下去
    wait_for_appearance (timeout=120)指定时间等待某个控件出现,如果未出现,则报错
    wait_for_disappearance (timeout=120)指定时间等待某个控件消失,如果未消失,则报错
    wait_for_any (objects, timeout=120)指定时间等待任意一个UI显示出来
    wait_for_all (objects, timeout=120)指定时间等待所有给定的UI对象都显示出来
    from poco.drivers.android.uiautomation import AndroidUiautomationPoco
    poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
    
    # 控件点击操作
    poco(text="网易大神").click()
    # 控件单击
    poco("star_single").click()
    
    # 控件长按
    poco('star_single').long_click()
    
    
    # 获取控件的name属性值
    poco(text="网易大神").attr("name")
    poco("star_single").attr("type")
    poco("star_single").attr("texture")
    
    # 判断控件存在
    poco(text="网易大神").exists()
    
    # 设置控件的文本信息
    poco("android.widget.EditText").set_text("123")
    
    # 向下滑动0.2个单位距离
    poco("Handle").swipe([0,0.2])
    sleep(1.0)
    # 向上滑动0.2个单位距离
    poco("Handle").swipe([0,-0.2])
    sleep(1.0)
    # 向下滑动0.1个单位距离
    poco("Handle").swipe("down")
    sleep(1.0)
    # 向上滑动0.1个单位距离
    poco("Handle").swipe("up")
    sleep(1.0)
    
    # 拖动到另一个控件上
    poco("playDragAndDrop").child("star")[0].drag_to(poco("shell"))
    # 拖动到固定目标上
    poco("playDragAndDrop").child("star")[1].drag_to([0.503, 0.705])
    
    
    # 获取控件star_single的属性名
    poco("star_single").get_name()
    # 获取控件star_single的位置
    poco("star_single").get_position()
    # 获取控件star_single的size
    poco("star_single").get_size()
    
    # 设置文本内容
    poco("pos_input").set_text("123")
    poco("pos_input").setattr('text',"456")
    
    # 在10s内等待控件出现,如出现,则进行长按操作
    poco(texture="icon").wait(timeout=10).long_click()
    # 等待黄色小鱼出现
    poco("yellow").wait_for_appearance(timeout=20)
    # 等待计分文本控件消失
    poco(text="Count:").wait_for_disappearance(timeout=3)
    
    # 等待 yellow,blue,black 都出来,再执行点击
    poco.wait_for_all([yellow,blue,black])
    poco("btn_back").click()
    # 等待 bomb,yellow,blue 任意一个出来
    poco.wait_for_any([bomb,yellow,blue])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    控件坐标

    Poco只能接受绝对坐标(归一化坐标系)

    归一化坐标:将屏幕宽和高按照单位一计算,UI在poco中的宽和高是相对于屏幕的百分比大小,在不同分辨率设备之间,同一个UI的归一化坐标系下的位置和尺寸 是一样的。归一化坐标系的空间是均匀的,屏幕正中央一定是(0.5, 0.5),其他标量和向量的计算方法同欧式空间

    局部坐标:表示相对于某UI的坐标,以UI包围盒左上角为原点,向右为x轴,向下为y轴,包围盒宽和高均为单位1

    from poco.drivers.unity3d import UnityPoco
    poco = UnityPoco()
    
    # 点击星星控件左上角的位置
    poco("star_single").focus([0,0]).click()
    
    # 点击星星控件的中心位置,等同于poco("star_single").click()
    poco("star_single").focus([0.5,0.5]).click()
    
    # 点击星星控件的外部位置
    poco("star_single").focus([-0.5,0.5]).click()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    选中控件之后,如果不想点击控件的中心位置,而是想点击控件内部的其它位置,可以使用 focus() 方法来指定内部偏移量

    # 指定内部偏移量
    pearl.focus([0.1,0.1]).long_click()
    pearl.focus([0.9,0.9]).long_click()
    
    • 1
    • 2
    • 3

    选中1个控件以后,如果想点击控件之外的位置,可以使用 focus() 方法来指定外部偏移量;会出现 点击坐标的值小于0或者大于1的情况

    # 外部偏移
    pearl_text = poco(text="pearl")
    pearl_text.focus([0.5,-3]).long_click()
    
    • 1
    • 2
    • 3

    控件断言

    exists()方法判断控件是否存在

    if poco("star_single").exists():
        poco("star_single").click()
    else:
        print("未找到控件")
    
        
    # 断言控件存在
    assert_equal(poco("star_single").exists(),True,"断言星星控件存在")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Poco-SDK接入

    参照官网:https://airtest.doc.io.netease.com/IDEdocs/poco_framework/6_poco_sdk/#3websocketserverjs

  • 相关阅读:
    算法时间复杂度详解
    基于Python+MySQL的图书销售管理系统 课程论文+项目源码及数据库文件
    苹果“慌了”,中国客户不买账,这次要提供“折扣”可谓罕见
    JavaScript之void 0 === undefined
    浅谈:服务架构进化论
    标准RBAC模型表设计
    vue3 动态组件
    在C#中使用Halcon开发视觉检测程序
    使用kaliber与imu_utils进行IMU、相机+IMU联合标定
    Python+班级管理系统 毕业设计-附源码171809
  • 原文地址:https://blog.csdn.net/weixin_42724501/article/details/125892467