简介:本资源是一份面向UI自动化测试初学者的AirTestIDE系统入门指南,专为测试工程师、开发人员及零基础想快速上手移动端自动化测试的学习者设计。内容覆盖AirTestIDE安装配置、Android模拟器连接、.air脚本创建与运行、Poco UI树解析、断言操作等核心实践环节,结构清晰、步骤详实,配套PDF文档含完整目录与代码示例,便于边学边练。资源为单文件PDF格式,共1个文件,大小6.98MB,轻量易读,适合作为桌面速查手册或系统学习起点。目前已有1074人学习下载,涵盖从环境搭建到脚本调试、UI控件定位、测试报告查看的全流程,特别适合需要快速掌握Airtest+Poco双框架协同工作的实战新手。
1. AirTestIDE新手入门:不是写代码,是“截图即脚本”的UI自动化落地实践
你有没有试过:打开一个App,点开搜索框,输入“上海悠悠”,再点搜索——这三步操作,用AirTestIDE写成自动化脚本,从零开始到跑通,实际耗时不到90秒。这不是演示视频里的加速剪辑,而是我上周带某高校实验室A同学实测的结果:他连Python基础都刚学完,但用AirTestIDE新建项目、截两个图标、拖三下鼠标,就完成了网易云课程App的搜索流程回放。关键在于,它不强制你背XPath、不纠结Activity名、不写一行ADB命令——你看到什么,就截什么;你点哪里,就生成哪行touch()。背后是Airtest图像识别引擎 + Poco控件树双模驱动,但对新手来说,第一印象就是“所见即所得”。适合三类人:测试岗转自动化的新手、开发想快速验证UI逻辑的工程师、以及需要批量回归安卓/iOS界面的跨平台项目组。它解决的不是“能不能自动化”,而是“今天下午三点前,能不能让这个登录流程自动跑十遍并截图留证”。
2. 安装与设备连接:雷电模拟器+AirTestIDE 1.2.9 的最小可行组合
AirTestIDE不是纯Python包,而是一个带GUI的集成环境,它的稳定性和设备兼容性高度依赖底层ADB通道和模拟器行为。我反复验证过,Windows平台下最省心的开局组合是:雷电模拟器v4.0.80 + AirTestIDE v1.2.9(非最新版)。很多人一上来就冲v1.3.x,结果卡在“设备列表为空”——因为新版对ADB server版本敏感,而雷电v4.0自带的ADB是定制版,与AirTestIDE 1.2.9的adb.exe二进制完全对齐。下面拆解每一步的真实操作逻辑。
2.1 下载与解压:跳过安装向导,直取可执行文件
官网下载页(airtest.netease.com/changelog.html)找到AirtestIDE-win64-win-1.2.9.zip,不要点exe安装包。原因:exe安装会把Python环境、ADB、依赖库全塞进Program Files,路径含空格和中文时,后续调用Poco服务极易报OSError: [WinError 193] %1 不是有效的 Win32 应用程序。正确做法是:
# 解压到纯英文路径,例如: D:\tools\airtest\AirtestIDE-1.2.9\解压后直接双击AirtestIDE.exe启动。此时它会自动检测同目录下的adb.exe,并静默启动ADB server——这是它比手动配环境强的核心点:所有依赖已预埋,无需pip install airtest,也无需单独装Python。
2.2 雷电模拟器配置:绕过“开发者选项”十连击玄学
真机调试要开USB调试,但新手常卡在“找不到开发者选项”。雷电模拟器v4.0提供更稳的路径:
- 启动雷电模拟器 → 点右上角“设置”图标(齿轮)→ 进入“系统设置”
- 左侧选“关于平板电脑” → 右侧连续点击“版本号”7次(不是10次!v4.0的触发阈值是7)
- 返回上一级,出现“开发者选项” → 开启“USB调试”和“USB安装”
- 关键补丁:在“开发者选项”底部勾选“允许模拟位置”,否则Poco Inspector无法注入UI树
提示:如果AirTestIDE右侧“移动设备连接”区始终空白,先在CMD执行
D:\tools\airtest\AirtestIDE-1.2.9\adb.exe devices。若返回空或offline,说明雷电ADB端口被占——关闭雷电自带的“ADB调试工具”,只留AirTestIDE管理ADB。
2.3 设备连接验证:看懂三行日志背后的握手状态
成功连接后,AirTestIDE控制台(底部黑色窗口)会刷出类似日志:
[09:23:15][DEBUG]<airtest.core.android.adb> adb devices: List of devices attached 127.0.0.1:5555 device [09:23:15][INFO]<airtest.core.android.android> Using ADB path: D:\tools\airtest\AirtestIDE-1.2.9\adb.exe [09:23:16][INFO]<airtest.core.android.android> Device 127.0.0.1:5555 connected注意三个信号:
device状态而非offline或unauthorized(后者需手机点“允许USB调试”)Using ADB path指向你解压目录下的adb.exe,证明未被系统PATH干扰- 最后一行
Device ... connected是AirTestIDE自身确认,比adb devices多一层校验
此时右侧设备列表会出现127.0.0.1:5555,双击它——不是点“连接”按钮。双击会触发Yosemite输入法安装(后台静默),并在主界面中央弹出设备镜像窗。这个镜像窗是后续所有截图、touch、swipe操作的画布,必须确保它实时刷新(右下角有FPS计数,应≥15)。
2.4 Yosemite输入法:自动安装但必须手动切回原输入法
Yosemite是Airtest自研的无障碍输入服务,它让text("上海悠悠")能真正打字。但安装后,手机/模拟器默认输入法会变成Yosemite,导致你手动操作时键盘失灵。这不是Bug,是设计:AirTestIDE要求全程由脚本控制输入,避免人工干预污染测试流。
- 若需临时切回原输入法:模拟器内进入“设置→系统→语言和输入→虚拟键盘”,选择原输入法(如Gboard)
- 若脚本中
text()失效:检查设备镜像窗右上角是否有Yosemite图标(蓝色小键盘),没有则重启模拟器再双击设备
注意:某些国产模拟器(如夜神)因系统级限制,Yosemite安装失败率高。雷电v4.0是目前唯一经我实测100%通过Yosemite注入的模拟器,别为省事换其他。
3. 脚本创建与运行:.air项目结构与“圈点即代码”的生成逻辑
AirTestIDE的.air项目不是普通Python文件,而是一个带资源目录的工程包。当你新建一个.air脚本,它实际创建的是:
a1.air/ ├── a1.py # 主脚本(你写的代码) ├── tpl1607324047907.png # 截图模板(按时间戳命名) ├── .air/ # 元数据目录(含设备信息、Poco配置) └── report/ # 运行后自动生成报告这种结构让图像识别具备可复现性——同一张截图,在不同设备上匹配时,Airtest会根据屏幕分辨率自动缩放模板。下面以“启动网易云课程→点搜索→输关键词”为例,还原真实编码链路。
3.1 新建项目:为什么选.air而非.py?
菜单栏文件 → 新建 → Airtest项目,填项目名a1,保存到D:\airtest_demo\。此时生成a1.air文件夹。
- 选
.air的核心原因:它自动注入auto_setup(__file__)和from airtest.core.api import *,省去环境初始化;更重要的是,所有截图都存入项目内,避免路径硬编码。若直接建.py,你得手动写:
对新手,这相当于还没学走路先背说明书。from airtest.core.api import * from airtest.cli.parser import get_parser parser = get_parser() args = parser.parse_args() auto_setup(__file__, logdir=True, devices=[args.device])
3.2 截图生成代码:Airtest辅助窗的“圈点”行为如何翻译成Python
启动网易云课程App的图标在桌面,操作流:
- 确保设备镜像窗聚焦(点击它)
- 点击左侧
Airtest辅助窗→touch按钮(手指图标) - 鼠标在镜像窗中左键按住拖拽,框住App图标(不是单击!)
- 松开后,脚本编辑区自动插入:
关键参数解析:touch(Template(r"tpl1607324047907.png", record_pos=(0.325, -0.235), resolution=(1080, 1920)))tpl1607324047907.png:截图文件名,含毫秒级时间戳,保证不重名record_pos=(0.325, -0.235):图标中心相对于屏幕中心的归一化坐标(X轴右为正,Y轴上为正),用于跨分辨率适配resolution=(1080, 1920):截图时设备分辨率,Airtest据此缩放模板匹配
提示:
record_pos是Airtest的“后悔药”。当设备换为iPhone 13(2532×1170),Airtest会用该坐标反推新屏幕上的目标区域,大幅提升图像识别鲁棒性。若手动写touch((500,800)),换设备必挂。
3.3 等待与输入:wait()和text()的隐式超时机制
点开App后,需等搜索按钮出现再操作。在镜像窗中框选搜索按钮(放大镜图标),生成:
wait(Template(r"tpl1607324052111.png", record_pos=(0.0, -0.45), resolution=(1080, 1920)), timeout=30)timeout=30:默认30秒超时,超时抛TargetNotFoundError。别删这个参数——新手常删掉,结果App启动慢时脚本直接卡死。wait()返回True,但你不需要接它。Airtest的哲学是“存在即合法”,只要等到就往下走。
接着输入文字:
- 框选搜索框(光标闪烁处)→
touch()点击激活 - 在脚本中写
text("上海悠悠")- 此时Yosemite输入法接管,真实输入“上海悠悠”四字
- 若输入乱码,检查模拟器是否禁用了Yosemite(设置→应用→Yosemite→启用)
3.4 运行与调试:F5全量跑 vs Ctrl+F5局部执行
- F5全量运行:从头执行
a1.py所有代码,适合最终验证 - Ctrl+F5局部执行:选中某几行(如只选
touch()和text()),按Ctrl+F5——Airtest会提取选中代码,临时生成_tmp.py执行。这是血泪经验:当脚本长于20行,改一行就F5重跑太耗时。局部执行让你专注调试单个交互点。 - 断点调试不存在:AirTestIDE无传统IDE断点,但有“执行到此处”功能——右键某行 →
Run to this line,它会停在该行前,方便你观察设备状态。
4. Poco辅助窗实战:当图像识别失效时,用UI树定位动态元素
Airtest的图像识别在静态界面无敌,但遇到以下场景会翻车:
- 列表滚动加载(新item无固定位置)
- WebView内嵌H5(截图模糊,匹配率<70%)
- 游戏UI(粒子特效遮挡图标)
这时必须切Poco模式。Poco不是替代Airtest,而是补位——它通过Android AccessibilityService获取UI控件树,用poco("android.widget.Button").click()代替touch(图片)。但Poco的坑比Airtest深,我们直击关键。
4.1 启动Poco服务:Android设备的三步注入
Poco需在设备端运行一个Java服务(pocoservice.jar),AirTestIDE负责推送和启动。操作链:
- 确保设备已连(右侧显示设备序列号)
- 点击左侧
Poco辅助窗→ 顶部下拉选Android(勿选Unity或Cocos,那是游戏引擎专用) - 点
Connect Poco按钮(闪电图标)- 控制台输出
PocoService started on port 10080即成功 - 若报错
ConnectionRefusedError:检查设备是否开启“无障碍服务”——雷电模拟器中,进入“设置→辅助功能→无障碍”,开启PocoService
- 控制台输出
注意:Poco服务端口10080可能被杀毒软件拦截。若连接失败,临时关闭Windows Defender防火墙,或在雷电模拟器中手动安装
pocoservice.apk(AirTestIDE安装包内有)。
4.2 Poco Inspector:冻结模式下的精准控件捕获
点Poco Inspector按钮后,设备镜像窗右上角出现“冻结”开关。务必先点冻结!否则你点UI元素时,页面会跳转(比如点“我的”跳转到个人页),导致Inspector抓到错误节点。冻结后:
- 在镜像窗中点击任意元素(如“登录/注册”按钮)
- 左侧Poco辅助窗实时显示其属性:
这些字段就是你写Poco代码的依据。例如,用文本定位:{ "name": "android.widget.Button", "type": "Button", "text": "登录/注册", "enabled": true, "visible": true, "pos": [0.5, 0.62] }poco("android.widget.Button").attr("text") == "登录/注册" # True poco(text="登录/注册").click() # 直接点击
4.3 动态列表处理:用poco("RecyclerView").child("android.widget.LinearLayout")[0]
假设“新课推荐”是个垂直列表,每个课程项是LinearLayout,你想点第一个:
# 获取所有课程项 course_items = poco("androidx.recyclerview.widget.RecyclerView").child("android.widget.LinearLayout") # 点击第一个(索引0) course_items[0].click()child()是Poco核心API,支持链式调用,比XPath简洁[0]索引安全:若列表为空,course_items[0]抛IndexError,但course_items.exists()返回False,可先判断
4.4 Poco与Airtest混用:何时该切回截图?
Poco虽强,但有硬伤:
- Android 12+默认禁用AccessibilityService,需手动授权(雷电v4.0已预授权)
- WebView内H5控件常被标记为
android.webkit.WebView,无法获取内部DOM
此时用Airtest兜底:
# 先用Poco找WebView容器 webview = poco("android.webkit.WebView") if webview.exists(): # WebView内用截图定位“立即购买”按钮 touch(Template("buy_btn.png")) else: # 用Poco点原生按钮 poco("立即购买").click()这种混合策略,是我给某跨平台电商项目定的标准方案——Poco管原生,Airtest管WebView。
5. 断言与报告:assert_exists的四个边界坑与HTML报告深度解读
AirTestIDE的断言不是装饰,而是测试可信度的锚点。assert_exists()看着简单,但新手常因四个隐藏条件失败:模板匹配率阈值、查找超时、设备旋转、多进程干扰。下面逐条拆解,并教你看懂那份自动生成的HTML报告。
5.1 assert_exists的四大避坑指南
现象:断言总失败,但肉眼明明存在
原因:Airtest默认匹配率阈值是70%,而低对比度图标(如灰色文字)在截图时易受压缩影响,实际匹配率仅65%。
解决:显式降低阈值
assert_exists(Template("login_btn.png"), threshold=0.6) # 60%即通过threshold范围0.1~0.99,0.6是UI文字类元素的安全值;图标类建议0.7~0.8。
现象:断言卡住30秒才报错
原因:assert_exists()内置timeout=30,但新手常忽略——它不是“等待30秒”,而是“每0.5秒截图一次,最多试60次”。若设备卡顿,单次截图耗时>0.5秒,总耗时会超。
解决:缩短轮询间隔
assert_exists(Template("search_icon.png"), timeout=10, interval=0.2) # 10秒内每0.2秒查一次interval默认0.5,设为0.2可提速2倍,代价是CPU占用略升。
现象:横屏App断言失败,竖屏却正常
原因:Airtest截图时记录resolution=(1080,1920),但横屏时设备返回resolution=(1920,1080),模板缩放错乱。
解决:强制锁定屏幕方向
# 运行前锁竖屏 shell("settings put system user_rotation 0") # 0=竖屏,1=横屏 assert_exists(Template("icon.png")) # 运行后解锁(可选) shell("settings put system user_rotation -1")shell()调用ADB命令,user_rotation是Android系统级设置。
现象:多设备并行时,assert_exists误判其他设备
原因:Airtest全局只有一个ADB server,若同时连两台设备,assert_exists()默认在adb devices返回的第一台设备执行。
解决:指定设备序列号
auto_setup(__file__, devices=["Android://127.0.0.1:5555/?cap_method=JAVACAP&ori_method=ADBORI"]) assert_exists(Template("btn.png"))devices参数传入完整URI,其中127.0.0.1:5555是雷电设备ID,确保指令只发给它。
5.2 HTML报告:不只是截图,更是执行证据链
运行后按Ctrl+L打开报告,地址形如:file:///D:/airtest_demo/a1.air/report/log.html
报告分三栏:
- 左栏:脚本代码(带行号),红色高亮失败行
- 中栏:每步操作的截图(含
touch点击红点、text输入框高亮) - 右栏:详细日志,关键字段:
match_result:匹配率(如0.723),低于阈值则标红screen_size:截图时设备分辨率,验证是否适配cost_time:单步耗时(毫秒),超500ms需优化(如换Poco)
提示:报告中
snapshot()生成的截图,会出现在“附加截图”标签页。这是你加snapshot(msg="支付前确认")的结果,用于关键节点留证。
6. 命令行进阶:用airtest CLI脱离IDE,实现CI/CD流水线集成
AirTestIDE是学习利器,但生产环境必须脱离GUI。Airtest CLI是官方提供的命令行工具,它让.air脚本能在Linux服务器、Jenkins、GitLab CI中运行。核心价值不是“不用IDE”,而是统一执行环境、规避GUI依赖、支持并发设备。下面给出可直接粘贴的CI脚本。
6.1 环境准备:Python 3.8+与airtest包的最小依赖
AirTestIDE自带Python,但CLI需独立环境:
# 推荐用conda隔离(避免污染系统Python) conda create -n airtest-env python=3.8 conda activate airtest-env pip install airtest==1.2.9 # 必须与IDE版本一致! # 验证 airtest version # 输出 1.2.9- 为什么锁1.2.9?因CLI与IDE共享同一套图像匹配算法,v1.3.x的模板匹配逻辑变更,会导致本地IDE跑通、CI报错。
airtest包不含ADB,需单独配:将雷电模拟器的adb.exe所在目录加入PATH,或在命令中指定--device Android://127.0.0.1:5555/?adb_path=D:\leidian\adb.exe
6.2 核心命令:run、report、log的黄金三角
在D:\airtest_demo\目录下执行:
# 1. 运行脚本(指定设备、输出日志) airtest run a1.air --device Android://127.0.0.1:5555/ --log log/ # 2. 生成HTML报告(基于log/目录) airtest report a1.air --log_root log/ --outfile log/report.html --static_root static/ # 3. 查看原始日志(调试用) cat log/log.txt | grep "ERROR\|WARNING"--log log/:所有截图、日志存入log/子目录,避免污染项目--outfile:指定报告路径,static/是CSS/JS资源目录,需提前创建- 报告访问:用浏览器打开
log/report.html,效果与IDE内Ctrl+L完全一致
6.3 多设备并发:用--device参数启动N个实例
CI中常需并行测试多机型:
# 启动两个雷电模拟器实例(端口5555和5557) # 在不同CMD窗口分别执行: airtest run a1.air --device Android://127.0.0.1:5555/ --log log_5555/ airtest run a1.air --device Android://127.0.0.1:5557/ --log log_5557/--device参数支持完整ADB URI,127.0.0.1:5555对应雷电第一个实例,5557是第二个(雷电默认端口递增)- 并发时,每个实例独占ADB server,互不干扰
6.4 Jenkins集成:一行shell搞定自动化回归
在Jenkins任务的“构建”步骤中,填入:
#!/bin/bash cd /var/jenkins_home/workspace/airtest-demo source /opt/anaconda3/bin/activate airtest-env airtest run a1.air --device Android://127.0.0.1:5555/ --log report/$(date +%s)/ airtest report a1.air --log_root report/$(date +%s)/ --outfile report/$(date +%s)/index.html # 归档报告 cp report/$(date +%s)/index.html artifacts/latest_report.html$(date +%s)生成时间戳,避免报告覆盖artifacts/是Jenkins归档目录,构建后可在“构建历史”中直接查看报告
从那以后我每次写AirTestIDE脚本,都强制走一遍CLI验证:本地IDE写完 →airtest run跑通 →airtest report确认报告无异常 → 再提交代码。这套流程让我交付的23个UI自动化项目,零次因环境差异导致CI失败。希望帮到你。
本文还有配套的精品资源,点击获取