news 2026/7/23 2:37:14

Maestro 移动 UI 自动化测试入门教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Maestro 移动 UI 自动化测试入门教程

Maestro 移动 UI 自动化测试入门教程

本文带你从零开始掌握 Maestro —— 一款开源的跨平台移动 UI 自动化测试框架。涵盖安装配置、YAML 测试流编写、核心命令、选择器、高级用法及实战案例,让你 10 分钟写出第一条自动化测试。


一、Maestro 是什么?

Maestro 是一款开源的端到端移动 UI 自动化测试框架,支持Android、iOS 和 Web应用(包括 React Native、Flutter 和混合应用)。它的核心理念是"拥抱不稳定性",通过人类可读的 YAML 语法和解释型执行引擎,让测试编写变得简单高效。

与传统自动化框架(如 Appium、XCUITest)相比,Maestro 最大的优势在于极低的上手门槛—— 你不需要编写复杂的代码,只需用 YAML 描述用户操作即可。

核心特性

特性说明
跨平台一套 YAML 语法,同时测试 Android、iOS 和 Web 应用
人类可读的 YAMLlaunchApptapOnassertVisible等命令表达交互
内置抗抖动自动等待 UI 稳定,无需手动写sleep()
解释型执行无需编译,修改即运行,快速迭代
智能元素定位默认使用 Accessibility Tree,模拟真实用户视角
JavaScript 集成在 YAML 中内嵌 JS 处理复杂逻辑、调用外部 API
测试录制自动将执行过程录制成 MP4 视频
Maestro Studio可视化测试构建器,支持录制交互、检查元素

为什么选择 Maestro?

  • 学习曲线低:5 分钟写出第一条测试,无需编程经验
  • 维护成本低:YAML 语法直观,测试即文档
  • 稳定性高:内置智能等待机制,减少 flaky tests
  • 生态完善:支持本地测试、CI/CD 集成、云端测试

二、环境准备与安装

2.1 前置条件

安装 Maestro 前,请确保系统已安装Java 17 或更高版本

验证 Java 版本:

java-version

如果未安装 Java,推荐使用 Temurin JDK 或 Oracle JDK 安装。确保JAVA_HOME环境变量指向 Java 17+ 的安装路径。

2.2 安装 Maestro CLI

macOS 安装

方式一:使用 curl 脚本安装

curl-fsSL"https://get.maestro.mobile.dev"|bash

方式二:使用 Homebrew 安装

brew tap mobile-dev-inc/tap brew trust--formulamobile-dev-inc/tap/maestro brewinstallmobile-dev-inc/tap/maestro

macOS 用户还需安装最新版 Xcode 和 Xcode Command Line Tools(用于 iOS 模拟器测试)。

Windows 安装
  1. 前往 Maestro GitHub Releases 下载最新的maestro.zip
  2. 解压到稳定目录(如C:\maestro
  3. 将 Maestro 的bin目录添加到系统 PATH:
setx PATH"%PATH%;C:\maestro\bin"
  1. 重启终端使配置生效
Linux 安装
curl-fsSL"https://get.maestro.mobile.dev"|bash

安装完成后,默认安装路径为$HOME/.maestro/bin。如果maestro命令不可用,手动添加 PATH:

exportPATH="$PATH:$HOME/.maestro/bin"

2.3 验证安装

运行以下命令,若显示帮助信息则安装成功:

maestro--help

2.4 准备测试设备

Maestro 需要一个正在运行的设备或模拟器来执行测试。

Android 测试:

  1. 打开 Android Studio
  2. 进入 Virtual Device Manager
  3. 启动一个虚拟设备(如 Pixel 8)
  4. 等待设备启动到主屏幕

iOS 测试:

  1. 打开 Xcode
  2. 启动 iOS 模拟器(如 iPhone 15)
  3. 确保模拟器处于运行状态

三、第一个测试:10 分钟快速上手

3.1 创建测试文件

创建一个新目录并新建contacts.yaml文件:

appId:com.google.android.contacts----launchApp:clearState:true-tapOn:"Allow"-tapOn:Create contact-tapOn:First name-inputText:John-tapOn:Last name-inputText:Doe-tapOn:Company-inputText:Maestro-tapOn:"+1"-inputText:111-111-1111-tapOn:Save-back

3.2 运行测试

确保模拟器正在运行,然后执行:

maestrotestcontacts.yaml

Maestro 会连接到模拟器,按顺序执行每个步骤。终端会显示实时进度报告,你可以在模拟器上看到自动化操作的过程。

3.3 测试录像

在 Flow 中加入录像命令,执行后会在当前目录生成recording.mp4

appId:com.google.android.contacts----launchApp:clearState:true-startRecording:recording# 开始录像-tapOn:Create contact-tapOn:First name-inputText:John-tapOn:Last name-inputText:Doe-tapOn:Save-stopRecording# 停止录像,生成 recording.mp4

四、Flow 结构详解

Maestro 的测试文件称为Flow,使用 YAML 格式编写。一个标准的 Flow 由两部分组成,用---分隔:

# ========== 配置区 ==========appId:com.example.app# 必填:被测应用的包名/Bundle IDname:登录测试# 选填:Flow 的自定义名称tags:# 选填:标签,用于筛选测试-smoke-test-loginenv:# 选填:环境变量USERNAME:"user@example.com"PASSWORD:"123456"---# ========== 命令区 ==========-launchApp# 启动应用-tapOn:"Username"# 点击用户名输入框-inputText:${USERNAME}# 输入环境变量-tapOn:"Password"-inputText:${PASSWORD}-tapOn:"Login"# 点击登录-assertVisible:"Welcome"# 断言欢迎信息可见

配置区字段说明

字段必填说明
appId被测应用的包名(Android)或 Bundle ID(iOS)
nameFlow 的显示名称,会出现在测试报告中
tags标签列表,配合--include-tags/--exclude-tags使用
env环境变量映射,在命令区通过${变量名}引用

五、核心命令速查

5.1 常用命令一览

命令说明示例
launchApp启动应用- launchApp
killApp强制关闭应用- killApp
tapOn点击元素- tapOn: "登录"
doubleTapOn双击元素- doubleTapOn: "头像"
longPressOn长按元素- longPressOn: "消息"
inputText输入文本- inputText: "hello"
eraseText删除文本- eraseText: 10
swipe滑动操作- swipe: { direction: UP }
scroll滚动- scroll
scrollUntilVisible滚动直到元素可见- scrollUntilVisible: { element: "加载更多" }
back返回(Android)- back
pressKey按键- pressKey: Enter
hideKeyboard隐藏键盘- hideKeyboard
assertVisible断言元素可见- assertVisible: "欢迎"
assertNotVisible断言元素不可见- assertNotVisible: "错误"
takeScreenshot截图- takeScreenshot: result
waitForAnimationToEnd等待动画结束- waitForAnimationToEnd
openLink打开链接- openLink: "https://example.com"

5.2 命令详细用法

launchApp —— 启动应用
# 基本启动-launchApp# 启动并清除应用状态(重新开始)-launchApp:clearState:true# 启动并清除权限设置-launchApp:clearState:trueclearKeychain:true
tapOn —— 点击元素
# 通过文本点击-tapOn:"登录"# 通过 ID 点击-tapOn:id:login_button# 通过文本点击(指定第几个匹配项)-tapOn:text:"删除"index:2# 多条件组合定位-tapOn:text:"提交"enabled:truebelow:"个人信息"
inputText —— 输入文本
# 直接输入-inputText:"hello world"# 输入环境变量-inputText:${USERNAME}# 输入数字-inputText:"13800138000"
swipe —— 滑动操作
# 方向滑动-swipe:direction:UP# 指定百分比区域滑动-swipe:start:50%,80%end:50%,20%# 元素间滑动-swipe:from:id:item_1to:id:item_5
assertVisible —— 断言元素可见
# 简单断言-assertVisible:"登录成功"# 带超时的断言-extendedWaitUntil:visible:"欢迎页面"timeout:10000# 可选断言(不通过也不会失败)-assertVisible:text:"弹窗广告"optional:true

六、选择器(Selectors)

选择器是 Maestro 定位 UI 元素的核心机制。Maestro 默认使用Accessibility Tree(无障碍树),从用户视角来识别界面元素。

6.1 选择器类型

文本选择器(最常用)
# 简写形式-tapOn:Login# 完整形式-tapOn:text:Login

text默认支持正则表达式,可用于匹配动态文本。

ID 选择器(最稳定)
-tapOn:id:submit_button

ID 是 Accessibility Identifier,不受语言切换影响,适合多语言应用。

索引选择器

当有多个匹配元素时,用index指定第几个(从 0 开始):

-tapOn:text:"删除"index:1# 点击第 2 个"删除"按钮
坐标选择器
-tapOn:point:50%,50%

6.2 关系选择器

当元素本身没有唯一标识时,可以用相对位置来定位:

# 点击"密码"下方的元素-tapOn:below:"密码"# 点击"标题"上方的元素-tapOn:above:"标题"# 点击某个父容器内的元素-tapOn:text:"删除"childOf:id:list_item

6.3 状态选择器

# 只在元素可点击时操作-tapOn:text:"提交"enabled:true# 检查勾选状态-assertVisible:text:"记住密码"checked:true# 检查焦点状态-assertVisible:text:"搜索框"focused:true

6.4 选择器最佳实践

场景推荐策略
有固定文本的按钮/标签使用text选择器,直观且自文档化
图标、图片等无文字元素使用id(Accessibility Identifier),跨语言稳定
动态文本或无唯一标识用关系选择器(above/below)锚定位置
文本部分变化使用正则text: "订单.*成功"
等待异步加载完成在选择器中加enabled: true,自动等待可交互状态

七、高级用法

7.1 子 Flow(Subflows)

将通用操作抽取为子 Flow,实现复用。例如创建login.yaml

# login.yamlappId:com.example.app----tapOn:"用户名"-inputText:${USERNAME}-tapOn:"密码"-inputText:${PASSWORD}-tapOn:"登录"-assertVisible:"首页"

在其他 Flow 中调用:

# main_flow.yamlappId:com.example.app----launchApp-runFlow:login.yaml# 调用子 Flow-tapOn:"我的订单"-assertVisible:"订单列表"

7.2 条件执行

使用runFlow配合when条件来控制执行逻辑:

-runFlow:when:visible:"升级提示"commands:-tapOn:"稍后"

7.3 循环

-repeat:times:3commands:-tapOn:"下一个"-assertVisible:"图片"

7.4 JavaScript 集成

在 YAML 中直接执行 JavaScript,处理复杂逻辑:

appId:com.example.app----evalScript:${output.date = new Date().toISOString()}-tapOn:"日期"-inputText:${output.date}

发起 HTTP 请求:

-evalScript:${output.response = http.get('https://api.example.com/test-data')}-inputText:${output.response.body.id}

7.5 重试机制

对不稳定操作使用retry

-retry:maxRetries:3commands:-tapOn:"刷新"-assertVisible:"数据加载完成"

八、CLI 命令参考

8.1 常用命令

命令说明
maestro test <flow.yaml>执行测试
maestro test -c <flow.yaml>连续模式,文件变更自动重跑
maestro test --include-tags=smoke .只运行带smoke标签的 Flow
maestro test --format=JUNIT .生成 JUnit 格式报告
maestro start-device --platform=android启动 Android 模拟器
maestro list-devices列出本地可用设备
maestro record <flow.yaml>录制测试执行过程
maestro download-samples下载官方示例
maestro hierarchy打印当前应用的视图层级

8.2 test 命令常用选项

选项说明
-c, --continuous连续模式,监控文件变化自动重跑
-e, --env=KEY=VALUE设置环境变量
--include-tags=tags只运行包含指定标签的 Flow
--exclude-tags=tags排除包含指定标签的 Flow
--format=FORMAT报告格式:JUNITHTMLNOOP
--output=PATH指定报告输出路径
--device=UDID指定运行的设备 ID
--platform=PLATFORM指定平台:androidiosweb
-s, --shards=COUNT并行分片执行

8.3 实用示例

# 运行单个 Flowmaestrotestlogin.yaml# 运行目录下所有 Flowmaestrotest./flows/# 只运行冒烟测试maestrotest--include-tags=smoke ./flows/# 连续开发模式maestrotest-clogin.yaml# 生成 HTML 报告maestrotest--format=HTML--output=report.html ./flows/# 传入环境变量maestrotest-eUSERNAME=test@test.com-ePASSWORD=123456login.yaml# 在指定设备上运行maestro--device=emulator-5554testlogin.yaml# 启动设备maestro start-device--platform=android --device-os=android-34

九、实战案例:登录功能测试

下面通过一个完整的登录测试场景,综合运用前面学到的知识。

9.1 测试场景

  1. 启动应用
  2. 处理首次启动的权限弹窗
  3. 输入用户名和密码
  4. 点击登录
  5. 验证登录成功
  6. 退出登录

9.2 测试文件

# login_test.yamlappId:com.example.myappname:登录功能测试tags:-smoke-loginenv:USERNAME:"testuser@example.com"PASSWORD:"Test@1234"---# 启动应用,清除状态-launchApp:clearState:true# 处理可能出现的权限弹窗-runFlow:when:visible:"允许"commands:-tapOn:"允许"# 进入登录页面-tapOn:"登录"# 输入用户名-tapOn:id:username_input-inputText:${USERNAME}# 输入密码-tapOn:id:password_input-inputText:${PASSWORD}# 点击登录按钮-tapOn:text:"登录"index:1enabled:true# 验证登录成功-assertVisible:"首页"-takeScreenshot:login_success# 退出登录-tapOn:"我的"-scroll-tapOn:"退出登录"-tapOn:"确认"-assertVisible:"登录"

9.3 运行测试

# 基本运行maestrotestlogin_test.yaml# 生成 JUnit 报告(用于 CI/CD)maestrotest--format=JUNIT--output=report.xml login_test.yaml# 连续模式开发调试maestrotest-clogin_test.yaml

十、Maestro Studio 可视化工具

Maestro Studio 是一个轻量级的可视化测试构建工具,帮助你快速编写测试。

启动 Maestro Studio

maestro studio

核心功能

功能说明
视觉流构建器点击界面元素自动生成对应命令
元素检查器查看元素的 ID、文本、层级等属性
实时预览在模拟器上操作,实时生成 YAML
AI 辅助用自然语言描述操作,AI 生成命令

对于初学者,推荐先用 Maestro Studio 录制操作生成基础 Flow,再手动优化 YAML。


十一、测试优化与最佳实践

11.1 减少测试 flaky

  1. 善用enabled: true:在点击按钮前确保它可交互
  2. 使用optional: true:对可能出现的弹窗做可选断言
  3. 避免硬等待:用assertVisible代替sleep
  4. 合理使用retry:对网络相关操作加重试
# 处理可能出现的弹窗-runFlow:when:visible:"更新提示"commands:-tapOn:"稍后提醒"# 等待元素可点击再操作-tapOn:text:"提交"enabled:true

11.2 测试组织结构

推荐的目录结构:

project/ ├── config.yaml # 全局配置 ├── flows/ │ ├── login/ # 按功能模块分组 │ │ ├── login_success.yaml │ │ └── login_failure.yaml │ ├── search/ │ │ └── search_flow.yaml │ └── checkout/ │ └── checkout_flow.yaml ├── subflows/ # 可复用的子 Flow │ ├── login.yaml │ └── navigate_home.yaml └── reports/ # 测试报告输出

11.3 使用 config.yaml 统一配置

在项目根目录创建config.yaml,设置全局行为:

# config.yamlappId:com.example.myapp# 测试执行配置flowOrder:-subflows/login.yaml-flows/# 全局环境变量env:API_BASE_URL:"https://test-api.example.com"

运行时指定配置文件:

maestrotest--config=config.yaml ./flows/

11.4 CI/CD 集成

在 GitHub Actions 中集成 Maestro:

# .github/workflows/test.ymlname:Maestro Testson:[push,pull_request]jobs:test:runs-on:macOS-lateststeps:-uses:actions/checkout@v4-uses:reactivecircus/android-emulator-runner@v2with:api-level:34script:|curl -fsSL "https://get.maestro.mobile.dev" | bash export PATH="$PATH:$HOME/.maestro/bin" maestro test --format=JUNIT --output=report.xml ./flows/-uses:actions/upload-artifact@v4with:name:test-reportpath:report.xml

十二、常见问题

Q1:元素找不到怎么办?

  1. 使用maestro hierarchy命令查看当前界面的视图层级
  2. 用 Maestro Studio 的元素检查器查看元素属性
  3. 尝试使用不同的选择器(text、id、关系选择器)
  4. 检查元素是否在 WebView 或 Flutter 渲染层中

Q2:测试运行超时?

设置启动超时环境变量:

exportMAESTRO_DRIVER_STARTUP_TIMEOUT=180000

Q3:如何测试 Flutter 应用?

Maestro 原生支持 Flutter。确保 Flutter 应用启用了语义信息(Semantics),然后在 Flow 中正常使用选择器即可。

Q4:如何处理系统弹窗?

使用runFlow条件执行来处理:

-runFlow:when:visible:"Allow"commands:-tapOn:"Allow"

Q5:如何在多台设备上并行测试?

使用--shards选项:

maestrotest--shards=3./flows/

总结

Maestro 以其简洁的 YAML 语法内置的抗抖动机制跨平台支持,大幅降低了移动 UI 自动化测试的门槛。本文涵盖了从安装到实战的完整流程:

  1. 安装配置:一行命令完成安装,Java 17+ 即可运行
  2. 快速上手:YAML 描述操作,maestro test一键执行
  3. 核心命令launchApptapOninputTextassertVisible
  4. 选择器:文本、ID、关系、状态等多维定位策略
  5. 高级用法:子 Flow 复用、条件执行、循环、JS 集成
  6. 工程化:标签筛选、报告生成、CI/CD 集成

对于想要快速建立移动 UI 自动化测试体系的团队,Maestro 是一个非常值得尝试的选择。建议从简单的冒烟测试开始,逐步扩展到完整的回归测试套件。


官方资源

  • 官方文档:https://docs.maestro.dev
  • GitHub 仓库:https://github.com/mobile-dev-inc/Maestro
  • 社区 Slack:https://slack.maestro.dev
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 2:36:35

代码随想录day5

很久没做题更新博客了&#xff0c;最近在做项目与复习八股&#xff0c;每次被面试横向后都要摆烂一段时间 栈与队列 1.用栈实现队列 力扣题目链接(opens new window) 使用栈实现队列的下列操作&#xff1a; push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除…

作者头像 李华
网站建设 2026/7/23 2:35:10

反射性回忆循环:提升技术长期记忆的认知策略与实践指南

在长期记忆研究中&#xff0c;如何将短期接触的信息转化为持久、可检索的知识是一个核心挑战。传统的学习方法往往侧重于即时输入&#xff0c;却忽略了信息在记忆系统中的巩固和整合过程。反射性回忆循环&#xff08;Reflective Recall Cycle&#xff09;作为一种认知策略&…

作者头像 李华
网站建设 2026/7/23 2:34:55

Grok for Excel:金融建模与图表生成的智能助手实战指南

这类工具最值得先看的不是功能列表&#xff0c;而是能不能在普通 Excel 环境里稳定跑起来&#xff0c;以及它到底解决了金融建模和图表生成中的哪些具体痛点。Grok for Excel 上线后&#xff0c;很多人第一反应是“能不能替代 VBA 或 Python 脚本”&#xff0c;但实测下来&…

作者头像 李华
网站建设 2026/7/23 2:32:20

腾讯云GPU实例配置指南:从选型到深度学习环境部署实践

在云计算和人工智能快速发展的背景下&#xff0c;算力尤其是 GPU 算力的需求呈现爆发式增长。企业自建 GPU 集群面临成本高、运维复杂、技术迭代快等挑战&#xff0c;而公有云提供的弹性 GPU 服务成为许多团队的首选。腾讯云作为国内主要的云服务商之一&#xff0c;其 GPU 实例…

作者头像 李华
网站建设 2026/7/23 2:30:22

能科科技AI+工业场景化应用【第三期】:AI表单识别对比应用案例

Q&#xff1a;在日常工作中&#xff0c;您的团队是否仍在手工处理堆积如山的手写工单、检验报告等各类单据和图纸&#xff1f; 这种重复性劳动不仅效率低下、成本高昂&#xff0c;更因人为差错导致数据无法准确、及时地流入业务系统&#xff0c;形成信息孤岛和瓶颈&#xff0c…

作者头像 李华
网站建设 2026/7/23 2:29:57

收窄 LLM 决策空间

一、「收窄决策空间」收窄的是什么 保留 LLM 的决策权–LLM 负责工具选择、语义理解、答案组织。在LLM决策前&#xff0c;工程侧压缩候选集、参数、上下文。 这一层的主线是LLM 决策空间越小&#xff0c;行为越稳定。 二、提示词工程&#xff1a;能力有边界 遇到准确性问题&…

作者头像 李华