Maestro:让 AI Agent 自己写、自己跑的开源移动 UI 测试框架
移动测试,没人愿意写的活
移动 UI 测试是那种人人都知道该写、却几乎没人真写的东西。Appium 环境搭半天,测试代码要编译,flaky test 半夜报警,维护测试的成本比修 bug 还高。所以大多数团队的实际做法很简单:不写,发版前手工回归。
到了 agent 时代,这个窟窿更大了。coding agent 能飞快地把功能写出来,但它看不见模拟器上跑的是什么,不知道自己刚改的登录页到底能不能打开。写代码的速度翻了几倍,验证的缺口也跟着翻了几倍。
Maestro 想翻转这件事。它是 mobile.dev 出品的开源 UI 测试框架,GitHub 上 15.4k star,Apache 2.0 协议。它真正的卖点不是”又一个测试框架”,而是两个设计决策:测试用 YAML 写,人和机器都能读;官方 MCP server 把模拟器的屏幕和控制权直接交给你的 coding agent。E2E 测试正在从”没人愿意维护的负担”变成”agent 自己写、自己跑、自己修的验证层”。
Maestro 是什么
Maestro 是 mobile.dev(mobile-dev-inc)的开源 UI 和端到端测试框架,支持 Android、iOS 和 Web 应用,React Native、Flutter、混合应用也覆盖。官方 README 的说法是:五分钟内写出第一个测试。
它不是从零发明的。官方明确说设计建立在上一代的教训之上:Appium、Espresso、UIAutomator、XCTest、Selenium、Playwright。仓库 1,739 次提交、934 个 fork,核心用 Kotlin 写。
它有四个形态,开源边界划得很清楚:
| 形态 | 是否开源 | 费用 | 干什么 |
|---|---|---|---|
| CLI | Apache 2.0 | 免费 | 核心引擎,在终端跑 flow |
| MCP | 随 CLI 内置 | 免费 | 接入 coding agent,给它眼睛和手 |
| Studio | 闭源 | 免费 | 桌面可视化 IDE,Mac/Windows/Linux |
| Cloud | 闭源 | 付费 | 并行设备农场、CI 报告 |
开源的部分足够撑起完整的本地工作流。Studio 免费但看不到代码。Cloud 解决的是测试套件变大之后的规模化问题,官方宣称能把执行时间砍掉最多 90%。
三个把测试成本打下来的设计决策
YAML 做测试载体
一个最小的 flow 长这样:
appId: com.example.app
---
- launchApp
- tapOn: "Login"
- inputText: "test@example.com"
- tapOn: "Continue"
- assertVisible: "Welcome back"
这个格式一次解决三件事。人能直接在 code review 里读它,git diff 一目了然;解释执行,没有编译步骤,改完立刻能跑;LLM 天然擅长生成这种结构化 YAML,让 agent 写测试的成本趋近于零。
对比 Appium 时代的测试:同样的覆盖范围,你要用 Java 或 Python 写、要编译、要包一层 PageObject。不是代码量的差别,是物种的差别。
内建自动等待
UI 测试的 flaky 大多是因为”太快”:元素还没渲染出来,命令已经点下去了。传统解法是塞 sleep,sleep(3)、sleep(5),套件越跑越慢,flaky 照旧。
Maestro 的 tapOn、assertVisible 这类命令会自动等到元素真的可点、可见,不需要手写任何 sleep。这是官方说的”抗 flaky”的主要来源。
黑盒,且刻意为之
Maestro 像用户一样操作应用:看屏幕、点按钮,不关心你应用内部怎么实现。所以原生、React Native、Flutter 都能跑,一套 flow 跨平台。代价是它只能断言”屏幕上看得见的东西”,这一点放到局限那节说。
MCP:把验证闭环交给 agent
这是 Maestro 在 agent 时代的真正动作。官方把 MCP server 内置进 CLI,给 agent 暴露一组工具:
- list_devices:列出本地的 Android 模拟器、iOS 模拟器、Chromium 实例
- inspect_screen:读当前屏幕的 view hierarchy,返回 JSON
- take_screenshot:给当前屏幕截图
- run:执行 flow,可以直接传内联 YAML
- cheat_sheet:命令速查表,agent 写不熟悉的语法前先查它
- run_on_cloud:提交到 Cloud 执行并轮询结果
inspect_screen 是眼睛,run 是手。你的 agent 改完登录页代码,可以自己打开模拟器、跑一遍测试;失败了就读屏幕层级,定位问题,改 flow,再跑。验证发生在提 PR 之前,不是等 CI 红了才知道。
还有一个 Maestro Viewer。让 agent 执行 “open the maestro viewer”,模拟器画面会直接嵌进你的 IDE,你能实时看着 agent 在应用里点来点去。
有个容易被忽略的前提:AI 生成的测试必须可审计。如果 agent 产出的是一坨编译好的二进制或者纠缠的脚本,你只能选择信任它。Maestro 产出的是十几行 YAML,断言对不对,扫一眼就知道。确定、可复现、人能读懂,这三条是”敢把测试交给 agent”的前提。
五分钟上手
先装 Java 17 或更高版本,然后一条命令装 CLI:
curl -fsSL "https://get.maestro.mobile.dev" | bash
接入你的 agent。Claude Code:
claude mcp add maestro -- maestro mcp
Codex:
codex mcp add maestro -- maestro mcp
其他 agent(Cursor、Gemini CLI、Copilot 等)官方文档逐个给了配置,通用写法就一段:
{
"mcpServers": {
"maestro": {
"command": "maestro",
"args": ["mcp"]
}
}
}
然后给 agent 下一个指令:打开模拟器,给登录页写一个 Maestro 测试,跑到通过为止。
什么时候不该用 Maestro
- 单元测试和逻辑测试仍然是第一道防线。Maestro 解决的是 UI 层的端到端,别拿它测纯逻辑
- 黑盒视角意味着断言止步于”屏幕上可见的东西”,数据层的正确性还得靠 API 测试或单元测试兜底
- Java 17 运行时是硬性前提,你的环境装不了它就直接出局
- 开源的是 CLI 和 MCP;Studio 免费但闭源,Cloud 收费。评估时想清楚免费拿到的是什么、付费买的是什么
- 团队已经深度使用 Appium、存量脚本很大的话,迁移成本要单独算,不必为了 agent 化硬切
结论
移动测试被跳过,从来不是因为它不重要,而是因为写测试、维护测试过去全是人的活。Maestro 真正做的是转移这份成本:YAML 让 agent 能写,MCP 让 agent 能跑,人只剩下审阅那十几行读得懂的 YAML。
如果你已经在用 agent 写移动端代码,却还在手工回归,下一步很小:装 CLI,接 MCP,把第一个测试任务交给你的 agent。这是 agent 开发闭环缺的最后一块。
仓库:https://github.com/mobile-dev-inc/maestro 文档:https://docs.maestro.dev MCP 安装指南:https://docs.maestro.dev/get-started/maestro-mcp