Playwright Test Healer 深度解析:让 AI Agent 自动调试并修复失败测试的完整工作流
本文基于 Playwright 官方示例中的测试修复 Agent 定义文件 playwright-test-healer.md,完整剖析这个 "healer" 智能体的角色设定、工具权限与七步修复工作流,并结合仓库内的 Agent 生成源码、MCP 工具链和 todomvc 示例工程,讲清楚它是如何被生成、被调用、以及如何系统性地把失败的 Playwright 测试修到通过的。读完本文,你将能够:在自己的项目中生成并理解 healer Agent 定义、用 test_run / test_debug / browser_snapshot 等 MCP 工具复现其诊断流程、以及遵循 test.fixme() 等护栏规则落地自动修复。
1. 定位:healer 是 Playwright Test Agents 中的"修复者"
Playwright 官方文档 test-agents 介绍了 Playwright 自带的三个 Test Agent:planner(探索应用并产出 Markdown 测试计划)、generator(把计划转成可执行的 Playwright Test 文件)和 healer(执行测试套件并自动修复失败的测试)。本文聚焦的核心文档 examples/todomvc/.claude/agents/playwright-test-healer.md 正是 healer 这一角色在 Claude Code 子代理格式下的完整定义,它随 examples/todomvc 示例工程一起提交在仓库中,可直接作为参考模板。
这份文件的开头是一段 YAML frontmatter,声明了 Agent 的身份与能力边界:
---
name: playwright-test-healer
description: Use this agent when you need to debug and fix failing Playwright tests
tools: Glob, Grep, Read, LS, Edit, MultiEdit, Write,
mcp__playwright-test__browser_console_messages,
mcp__playwright-test__browser_evaluate,
mcp__playwright-test__browser_generate_locator,
mcp__playwright-test__browser_network_requests,
mcp__playwright-test__browser_snapshot,
mcp__playwright-test__test_debug,
mcp__playwright-test__test_list,
mcp__playwright-test__test_run
model: sonnet
color: red
---
name/description:Agent 名称与用途说明,是 AI 宿主工具(Claude Code 等)决定"何时把任务交给它"的依据——"当你需要调试和修复失败的 Playwright 测试时,使用这个 agent"。tools:显式限定它只能使用的工具集合。前四个(Glob, Grep, Read, LS)是只读的文件检索能力,Edit, MultiEdit, Write是代码修改能力,其余以mcp__playwright-test__前缀开头的是 Playwright MCP Server 暴露的测试工具(详见第 3 节)。model: sonnet:指定该 Agent 运行的基础模型档位;color: red是终端中显示该 Agent 的标识色。
frontmatter 之后的正文是注入给 LLM 的系统提示词,定义了 Agent 的人格("一名专精调试与修复 Playwright 测试失败的高级测试自动化工程师")以及它必须遵循的工作流与原则。这一部分在仓库中并非手写,而是由 Playwright 源码统一生成的——源码侧的共享定义见 playwright-test-healer.agent.md,正文指令完全一致,差别仅在工具名的映射方式(见第 4 节)。
2. 七步修复工作流:从"跑测试"到"修好为止"
文档正文给出的工作流(workflow)是 healer 的核心行为契约,共 7 步,环环相扣、循环迭代:
- Initial Execution(初次执行):使用
test_run工具运行所有测试,识别出失败的测试。 - Debug failed tests(调试失败测试):对每一个失败的测试运行
test_debug,以调试模式重新执行该测试。 - Error Investigation(错误排查):当测试在出错处暂停时,利用 Playwright MCP 工具:
- 查看错误细节;
- 抓取页面快照(page snapshot)以理解当时的上下文;
- 分析选择器、时序问题或断言失败。
- Root Cause Analysis(根因分析):通过检查以下方面确定失败的深层原因:
- 可能已经变更的元素选择器;
- 时序与同步问题;
- 数据依赖或测试环境问题;
- 破坏了测试假设的应用变更。
- Code Remediation(代码修复):编辑测试代码解决已识别的问题,重点关注:
- 更新选择器以匹配应用当前状态;
- 修正断言与期望值;
- 提升测试的可靠性与可维护性;
- 对天然动态的数据,使用正则表达式构造有韧性的 locator(例如
getByText(/Order #\d+/)一类的写法,而非硬编码具体数值)。
- Verification(验证):每做一次修复就重启该测试,验证改动是否生效。
- Iteration(迭代):重复"排查 + 修复"过程,直到测试干净地通过。
这条工作流的关键设计是"单点修复 + 每步验证":第 5 步只改一处,第 6 步立刻重跑,第 7 步把整个循环再跑一遍,避免一次大范围改动导致错误叠加、难以归因。
官方文档对 healer 行为的高层概括(见 test-agents 的 "Healer" 一节)与这份定义完全对应:重放失败步骤 → 检查当前 UI 以定位等效的元素或流程 → 给出补丁(locator 更新、等待调整、数据修复)→ 重跑测试,直到通过或被护栏(guardrails)停止循环。它的输入只需要一个"失败的测试名",输出要么是一个通过的测试,要么是一个被跳过的测试(当 healer 认为被测功能本身已损坏时)。
3. 工具集解剖:healer 手里有哪些"手术刀"
frontmatter 中的 tools 列表把 healer 的诊断能力拆解得非常具体,每一类工具都对应工作流中的某个环节:
| 工具 | 作用 | 对应工作流环节 |
|---|---|---|
test_run |
运行测试套件(可按参数筛选),返回失败清单 | 第 1 步 初次执行 |
test_debug |
以调试模式执行单个测试,失败步骤处暂停 | 第 2 步 调试 |
browser_snapshot |
抓取页面结构快照,理解出错时的 DOM/ARIA 上下文 | 第 3 步 错误排查 |
browser_generate_locator |
针对当前 UI 生成可用的 locator 建议 | 第 3/5 步 选择器分析、修复 |
browser_console_messages |
读取浏览器控制台输出,定位脚本报错 | 第 4 步 根因分析 |
browser_network_requests |
检查网络请求,排查接口/数据问题 | 第 4 步 根因分析 |
browser_evaluate |
在页面中执行 JS 表达式,做深入取证 | 第 3/4 步 |
这些 mcp__playwright-test__* 前缀的工具来自 npx playwright run-test-mcp-server 启动的 Playwright MCP Server(Agent 定义生成时会自动写入 .mcp.json,见第 4 节),也就是文档 mcp 所描述的"浏览器即测试替身 + 测试运行/调试工具"那一整套 MCP 能力在测试修复场景下的子集。
而 Glob, Grep, Read, LS, Edit, MultiEdit, Write 这类通用文件工具则保证了 healer 既能读懂仓库结构、定位测试文件,又能真正把修复写回代码——这正是工作流第 5 步 "Edit the test code" 得以执行的前提。
4. 这个文件是怎么来的:init-agents 与工具名映射
examples/todomvc/.claude/agents/playwright-test-healer.md 并不是手写的最终形态。Playwright 把 Agent 的"源定义"放在 packages/playwright/src/agents/playwright-test-healer.agent.md 中,该文件的 tools 用的是抽象名:
tools:
- search
- edit
- playwright-test/browser_console_messages
- playwright-test/browser_evaluate
- playwright-test/browser_generate_locator
- playwright-test/browser_network_requests
- playwright-test/browser_snapshot
- playwright-test/test_debug
- playwright-test/test_list
- playwright-test/test_run
运行 npx playwright init-agents --loop=claude 后,生成逻辑 generateAgents.ts 中的 ClaudeGenerator 负责把抽象工具翻译成 Claude Code 的具名工具:search 展开为 Glob, Grep, Read, LS,edit 展开为 Edit, MultiEdit, Write,而 playwright-test/test_run 之类的条目被映射成 mcp__playwright-test__test_run(asClaudeTool 函数,约 L70-L75)。同一套 ClaudeGenerator.init 还会:
- 在
.claude/agents/下写入每个 Agent 的.md定义(约 L46-L48); - 写入
.mcp.json,把playwright-testMCP Server 注册为npx playwright run-test-mcp-server(Windows 下走cmd /c npx ...的 shell 形式,约 L52-L59); - 在
specs/目录不存在时创建它并放置 README(约 L408-L414); - 找不到 seed 测试时生成一个默认的 seed 文件(约 L416-L420)。
因此官方文档强调:Agent 定义应由 Playwright 生成,且每次升级 Playwright 后应重新生成,以便获取新的工具与指令。仓库中 tests/mcp/init-agents.spec.ts 也对该命令的各 --loop 变体(claude、codex、opencode、vscode 等)做了回归验证。
配套地,playwright-test-heal.prompt.md 提供了触发该 Agent 的提示词模板("Run all my tests and fix the failing ones."),init-agents --loop=claude 会把它落到 .claude/prompts/ 下,供用户直接复制使用。
5. 关键原则(Key Principles):护栏决定 healer 的"行为边界"
工作流解决"怎么做",文档中的 Key Principles 一节则约束 healer 在边界情况下的取舍,是整套 Agent 设计中容易被忽略但极其重要的一部分:
- 系统性与留痕:调试必须系统、彻底,并且对每一次修复记录发现与推理过程("Document your findings and reasoning for each fix")——这让 AI 修复结果对人类可审计。
- 稳健优于取巧:优先选择健壮、可维护的解决方案,而非一次性 hack。
- 遵循 Playwright 最佳实践:可靠测试自动化的实践准则是默认准则。
- 一次修一个错误:存在多个错误时逐个修复并重测,与工作流的"每步验证"形成闭环。
- 明确解释:说清楚"哪里坏了、怎么修的"。
test.fixme()兜底护栏:如果错误持续存在、且 Agent 有较高把握认为测试本身是正确的(即被测功能确实坏了),就把该测试标记为test.fixme()使其在执行时被跳过,并在失败步骤前添加注释,解释"实际发生了什么、与预期有何不同"。这条规则保证 healer 不会因为"修不好"而无限循环或伪造通过,同时把信息保留给人类跟进。- 非交互式:不要向用户提问("you are not interactive tool"),而是自主做出最合理的处理直到测试通过——这决定了 healer 可以作为无人值守的自动化环节(例如 CI 中的修复循环)。
- 禁止反模式:永远不要等待
networkidle,也不要使用其他被不推荐或已弃用的 API。这条直接把 Playwright 的 API 卫生标准(自动等待优先、webFirst语义)内置进了 Agent 的修复准则,防止 healer 为求"能过"而写出page.waitForLoadState('networkidle')之类的脆弱代码。
从源码结构看,这些原则与共享定义 playwright-test-healer.agent.md 逐条一致,意味着无论生成到 .claude/、.codex/、.github/ 还是 .vscode/ 目录(见 generateAgents.ts 中的 CodexGenerator、CopilotGenerator、VSCodeGenerator 等类),healer 的行为契约在所有宿主工具下都是同一套。
6. 实战语境:todomvc 示例工程如何为 healer 提供"跑道"
healer 不是孤立的:它消费的对象正是 planner/generator 流水线产出的测试。examples/todomvc 就是这条流水线的完整示例:
- 测试计划:specs/basic-operations.plan.md 保存了 planner 产出的 Markdown 计划(添加/完成/编辑/删除/过滤等场景的步骤与预期结果)。
- 生成的测试:
tests/下按场景分目录(adding-todos/、completing-todos/、deleting-todos/、editing-todos/、filtering-todos/等),例如 should-add-single-todo.spec.ts。 - 自定义 fixture 注入导航:tests/fixtures.ts 扩展了
pagefixture,在每个测试前自动访问https://demo.playwright.dev/todomvc;生成的测试都import { test, expect } from '../fixtures',即 healer 修复时面对的代码形态。 - 运行配置:playwright.config.ts 设置了
timeout: 15_000、expect.timeout: 5_000、actionTimeout: 0、trace: 'on-first-retry'、开启视频录制,并在 CI 下retries: 2、workers: 1。其中actionTimeout: 0表示不限制单个动作耗时,与 Playwright 自动等待机制配合,也正是 healer 被要求"不写死等待"的配置基础;expect.timeout: 5_000则是断言失败的默认窗口,是 healer 做"时序问题"根因分析时要对照的关键参数。
把这份 Agent 定义与示例工程放在一起读,就得到一张完整的施工图:planner 写计划 → generator 生成 tests/ → healer 依据本文解析的工作流与护栏,用 test_run 定位失败、test_debug 暂停取证、browser_snapshot / browser_generate_locator 定位等效元素与 locator、必要时 browser_console_messages / browser_network_requests 排查环境问题,然后最小化编辑测试文件、重跑验证,修不好且有把握判定应用本身坏了就用 test.fixme() 跳过并留下注释。
7. 落地清单:在你自己的项目中复用 healer
基于以上事实,可以在自己的 Playwright 测试项目中按如下方式使用(所有操作均为查看/生成/运行,不涉及修改 Playwright 仓库本身):
- 生成 Agent 定义(在测试项目根目录,按所用 AI 工具选择 loop):
注意:VS Code 场景需要 v1.105 及以上版本才能正常提供 agentic 体验(官方文档要求)。npx playwright init-agents --loop=claude # Claude Code,生成 .claude/agents/*.md 与 .mcp.json npx playwright init-agents --loop=vscode # VS Code,生成 .github/chatmodes/*.chatmode.md npx playwright init-agents --loop=codex # Codex,生成 .codex/agents/*.toml npx playwright init-agents --loop=opencode # opencode,生成 .opencode/prompts/*.md 与 opencode.json - 升级 Playwright 后重新运行
init-agents,保证工具列表与指令是最新的。 - 触发方式:向你的 AI 工具发起"运行所有测试并修复失败的测试"这类请求(对应 playwright-test-heal.prompt.md 模板),或在支持子代理的宿主中直接指名
playwright-test-healer。 - 验收修复结果时重点核对三件事:修改是否停留在 locator/断言/数据层;失败步骤前是否有解释注释;被跳过的测试是否使用了
test.fixme()且附带"实际行为 vs 预期行为"的说明。
小结:playwright-test-healer.md 表面上是一份 Markdown Agent 定义,实质上是 Playwright "测试自愈"能力的完整规格书——七步工作流定义了诊断循环,MCP 工具集定义了取证手段,Key Principles 定义了护栏(test.fixme() 兜底、禁 networkidle、非交互式、稳健优先)。它由 generateAgents.ts 从共享源 playwright-test-healer.agent.md 统一生成并适配到 Claude / Codex / VS Code / opencode 等多种宿主,配合 todomvc 示例中的 specs/ 计划、tests/ 生成代码与 fixtures.ts 导航封装,构成了 Playwright 官方"planner → generator → healer"自动化测试流水线中最后一环的可复现样板。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00