前言
准备篇我们把环境跑通了,还截了第一张屏。从这篇开始正式干活:用 Airtest 的"眼睛和手"操作 App。我们会先搞懂 Airtest 找图的原理,再逐个学会六个核心 API,最后在官方 AirtestDemo 上跑通第一个完整用例。学完这篇,你就具备独立写一个简单自动化脚本的能力了。
1. 核心思路:一切操作都基于"当前屏幕画面"
先想一个问题:Airtest 怎么知道"开始游戏"按钮在哪?
答案不是坐标,不是控件,而是——它先截一张当前屏幕的图,然后在图里找你要的那张小图。找到了,小图的中心位置就是按钮的位置,点那里就行。
这个思路决定了 Airtest 的一切操作模式:
- 截屏(拿当前画面);
- 找目标图(在画面里匹配小图);
- 操作(在找到的位置点击/滑动/输入)。
所以用 Airtest 写脚本,本质是"用图片描述你想操作的东西"。你需要先准备好目标图片(比如按钮截图),脚本才能找到它。
2. 图片识别原理:模板匹配
Airtest 找图的技术叫模板匹配(template matching)。
原理很简单:你有一张"小图"(模板)和一张"大图"(当前屏幕截图),程序把小图放在大图的各个位置,逐个比对相似度,找到最像的位置。
fromairtest.core.apiimport*# 在屏幕里找 start_btn.png 这张小图touch(Template(r"start_btn.png"))这里有一个重要参数:相似度阈值(threshold)。
# 相似度要 0.8 以上才认为匹配成功(0~1,越大越严格)touch(Template(r"start_btn.png",threshold=0.8))- threshold 越高,找得越"挑",不容易点错,但也可能找不到(比如按钮颜色稍有变化);
- threshold 越低,越容易找到,但可能点错位置。
新手容易在"找不到图"和"点错图"之间反复横跳。记住一句话:找不到就调低一点,点错了就调高一点。后面实战里我们会具体体会。
3. 六个核心 API
Airtest 常用 API 就六个,每个都很直白。我们挨个看,都配代码和大白话解释。
3.1 snapshot:截屏
fromairtest.core.apiimport*# 截一张当前屏幕,保存为图片文件snapshot("home.png")大白话:拍个照,存下来。用于查看当前状态、留证据、或者作为下一步找图的基础。
3.2 touch:点击
# 在屏幕上找到这张图,点它的中心位置touch(Template(r"start_btn.png"))大白话:看到这个按钮,点它。这是 Airtest 用得最多的操作。
3.3 swipe:滑动
# 从屏幕 (500, 1500) 滑到 (500, 500),也就是向上滑一屏swipe((500,1500),(500,500))大白话:在屏幕上划一下。坐标是屏幕像素坐标,上滑列表、翻页都靠它。
也可以基于图片滑动,比如"从这张图的位置,向上滑动一段距离":
# 从"列表第一项"这张图的位置,向上滑动swipe(Template(r"first_item.png"),vector=[0,-0.5])3.4 text:输入文字
# 在光标处输入文字(前提:输入框已经获得焦点)text("hello")大白话:打字。测登录、搜索时用。注意它输入到"当前焦点"位置,所以通常先点击输入框,再输入。
3.5 assert_exists:断言
# 断言:屏幕上必须出现这张图,否则测试失败assert_exists(Template(r"login_success.png"),"登录成功页出现了")大白话:检查"这个东西在不在"。在,测试继续;不在,测试直接失败。这是自动化测试的灵魂——跑完要知道对没对。
3.6 wait:等待
# 等待这张图出现,最多等 10 秒,超时算失败wait(Template(r"home.png"),timeout=10)大白话:等它出现。App 启动、页面加载都需要时间,直接操作会扑空,先等目标出现再动手。
4. 完整用例:AirtestDemo 主流程
现在把六个 API 串起来,跑一个真实用例。场景:打开 AirtestDemo,点"开始游戏",滑动列表,点进详情,断言结果。
先确保模拟器连着、AirtestDemo 装着(准备篇做完的事)。
fromairtest.core.apiimport*# 1. 连接模拟器(MuMu 用 7555,雷电用 5555)connect_device("Android:///127.0.0.1:7555")# 2. 启动 AirtestDemo(包名以你安装的版本为准,可用 adb shell pm list packages 查询)start_app("com.netease.airtestdemo")# 3. 等待主页出现,最多 10 秒wait(Template(r"home.png"),timeout=10)# 4. 点击"开始游戏"按钮touch(Template(r"start_btn.png",threshold=0.8))# 5. 等游戏界面加载sleep(2)# 6. 向上滑动,浏览列表swipe((500,1500),(500,500))# 7. 点击列表里的某一项(用它的截图)touch(Template(r"item.png"))# 8. 断言:详情页的标题出现了assert_exists(Template(r"detail_title.png"),"进入了详情页")# 9. 截屏留证snapshot("case_done.png")逐行解释一遍关键点:
start_app("包名"):直接拉起 App,比手动点击图标稳定;wait(...)放在touch前面:先等目标出现再操作,这是脚本不"手忙脚乱"的关键;threshold=0.8:找按钮时要求相似度 0.8 以上,防止点错;sleep(2):页面切换需要时间,简单粗暴地等一下;assert_exists(..., "说明"):第二参数是失败时的提示文字,写清楚点,报错时一看就懂。
运行之后,如果一切顺利,你会得到一张case_done.png,里面是详情页的画面——这就是你写的第一个完整测试用例。
如果某一步失败怎么办
找不到图是新手最常遇到的。按这个顺序排查:
- 先
snapshot()截屏,肉眼看看当前画面是不是你想的那样; - 确认截图里的按钮和模板图长得像(尺寸、颜色、是否被遮挡);
- 把
threshold调低一点(比如 0.8 → 0.7)再试。
这个排查思路很朴素,但 90% 的"找不到图"都是这样解决的。
小结
这篇我们掌握了 Airtest 的完整套路:
- 核心思路:一切操作基于当前屏幕画面(截屏 → 找图 → 操作);
- 图片识别原理:模板匹配 + threshold 阈值;
- 六个核心 API:snapshot / touch / swipe / text / assert_exists / wait;
- 跑通了第一个完整用例:启动 → 等待 → 点击 → 滑动 → 点详情 → 断言 → 截屏。
Airtest 能解决"看得见、点得着"的问题。但它有个天生短板:靠图片认东西,容易受分辨率、遮挡、相似图标影响。下一篇我们上 Poco——用控件树精准定位,解决"认工牌 vs 认长相"的问题。