Playwright Trace Viewer 可记录测试中的操作、DOM、网络请求和控制台日志,帮助开发者直接回放 CI 故障。文章还介绍启用方法及其对缩短排障周期、降低 CI 成本的作用。
Playwright Trace Viewer 是一个内置 GUI,能够记录一次测试运行的完整、可回放快照——包括每个操作、DOM 状态、网络请求和 console log。这样一来,你只需打开一个文件就能调试 CI 失败,无须重新复现问题。
在实际使用中,这让 UI 测试不再只是一段 UI 操作录像。每次浏览器交互都会与当时底层的 API 流量、控制台输出和页面状态保持同步——这相当于免费获得了一层 API 调试能力,而且无须编写任何 API 测试。
仅仅这一点差异,就改变了测试调试的成本结构。本文将介绍它会给你的日常工作流带来哪些改变、如何启用它,以及如何向那些更关心工程时间和 CI 开销、而不是 DOM 快照的人证明它的价值。
CI 失败 → 尝试在本地运行 → 无法复现 → 添加调试代码 → 实现修复 → 推送 → 等待 CI → 重复
某个测试在 CI 上失败了。按照传统方式,你通常需要付出以下成本:
阅读错误信息和 stack trace,而它们本身往往不足以说明问题。
拉取对应分支,尝试在本地复现失败。
测试在本地通过了。只在 CI 中出现的失败非常常见——浏览器、viewport、时序、环境或数据状态都可能不同。
添加 console.log、截图、tracing 或 page.pause() 调用,然后再次运行测试。
问题仍然无法复现。尝试以 headed 模式运行、减慢操作速度、增加等待,或者调整环境,直到它最终失败。
最终复现问题、找到根因、删除调试代码并实现修复。
推送修复,等待 CI 再次运行。如果仍然失败,就重复整个过程。
根据 bug 的具体情况,这个循环可能只需要几分钟,也可能耗掉大半个下午——而且所需时间会随着失败的不稳定程度或环境依赖程度线性增长。之所以需要执行上述每一个步骤,是因为测试运行时已经存在的信息没有被保留下来,如今已经消失了。
Trace Viewer 的核心理念是:不要再丢弃这些信息。
启用 tracing 后,本次运行中的每个操作、DOM 快照、请求和日志都会被捕获到一个 trace.zip 文件中。当测试失败时,你只需打开这个文件——无论是在本地、CI 中还是浏览器里——就能看到测试按照实际发生的过程精确回放。
下面是启用前后完成相同调试任务的对比:
每一项对比都体现了同一个模式:你不再重新构造导致失败的条件,而是直接查看失败发生时的记录。
在本地开发时,可以记录所有测试的 trace:
npx playwright test --trace on
或者使用 UI Mode,它会自动记录每个测试的 trace,无须添加这个 flag。
在 CI 中为每次运行都记录 trace 会造成浪费——只需在失败后的 retry 中记录:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
retries: 1,
use: {
trace: 'on-first-retry',
},
});
其他可选值包括:on-all-retries、retain-on-failure(如果不使用 retries)、on(每次运行都记录——成本较高)以及 off。
从 HTML report 打开:点击任意测试上的 View trace,它会直接启动本地 Trace Viewer,无须手动查找文件。
npx playwright show-report
从 CLI 打开,可以指定文件或 URL:
npx playwright show-trace path/to/trace.zip
npx playwright show-trace https://example.com/trace.zip
也可以直接在浏览器中使用 trace.playwright.dev,无须安装任何工具。将文件拖进去,或者通过 URL query parameter 传入文件——这非常适合直接链接到 CI artifact。所有内容都在你的浏览器本地渲染,不会上传任何数据。
Viewer 顶部有一条贯穿整个界面的 timeline——点击或拖动到任意位置,下方的每个面板都会更新到对应时刻。你不必逐个点击操作,就能找到自己关心的时间点。
Network tab 的价值很容易被低估。它就是本文开头提到的 API 调试层:即使你的测试套件只操作 UI,测试过程中发出的每个后端调用也都会被捕获,并与用户操作保持同步。你不再需要打开 DevTools 并尝试复现问题,因为你已经拥有一条完整的 timeline,其中同时包含前端行为以及导致这些行为的 API 交互。
Trace 捕获的所有内容——操作、locator、DOM 快照、网络调用和控制台输出——都是存放在 zip 文件中的结构化数据,并不只是供人手动点击查看的 GUI。这让它非常适合需要在无人预先复现问题的情况下诊断失败的 AI coding Agent 和测试 skill。
实际应用方式包括:
自动化失败分诊。可以把 CI 运行生成的 trace.zip 交给 Agent,让它找出失败的操作、涉及的 locator,以及失败前后的 DOM 状态,然后提出修复方案——整个过程无须启动浏览器,也无须由 Agent 自己重新运行测试套件。
用根因摘要代替原始日志。与其把 stack trace 粘贴到聊天中,不如让 Agent(或围绕 Agent 构建的 skill)遍历 Trace 中的 Actions、Network 和 Console 数据,用自然语言说明哪里出了问题、问题是什么。相比直接阅读原始输出,这是一条短得多的修复路径。
无须执行即可生成 locator。由于 Locator tab 可以精确还原某一时刻的页面,Agent 能够利用捕获的状态,为新的 assertion 推导或验证 selector,就像人类使用 Pick Locator 一样——无须启动实时浏览器会话。
回传“视频凭证”。如果你还在记录 screencast(使用 Playwright 的 page.screencast API),并将其与 trace 一起保存,那么 Agent 自己执行的验证步骤也可以用同样的方式记录下来——这样你得到的不只是一句“测试已通过”,还有一份可供审查的 Agent 操作记录。
构建 CI 反馈循环。Trace 本身就是具有稳定 URL 的 CI artifact,因此监控 pipeline 的 Agent 可以在失败测试的 trace 生成后立即自动获取它,不必等待人工附加日志或描述失败现象。
其背后的变化,仍然是本文反复强调的核心:Trace 会把“测试失败了”变成一份自包含记录。无论是人类还是 Agent,都不需要重新复现失败,也能理解问题。
Trace Viewer 不只是改善开发者体验的小工具——它能够改变可量化的成本。如果你需要说明为什么应该采用它,或者为什么应当优先完善 CI 中的 trace 覆盖率,可以从以下几个方面入手:
测试失败的平均解决时间(MTTR)。前文所述的复现循环,消耗了大部分调试时间。移除“让它再失败一次”这个步骤,是缩短失败问题处理时间最有效的手段。
工程师切换上下文的成本。对于不稳定的 CI 失败,打开文件即可诊断,与必须专门阻塞一段时间在本地复现相比,带来的中断成本截然不同——尤其当失败发生在几小时后,此时工程师可能早已转去处理其他工作。
CI 计算开销。trace: 'on-first-retry' 只记录真正失败的测试,因此无须为每次成功运行都记录 trace,也能获得调试数据。相比之下,有些团队为了捕捉偶发失败,不得不反复重新运行整个测试套件,前者的开销要低得多。
不稳定测试的分诊吞吐量。由于 trace 可以作为 CI artifact 附加到失败记录中,任何有时间的人都能异步完成分诊,而不再局限于能够复现对应环境的人。
如果你想具体衡量它的影响,一开始只需跟踪两个指标:从测试失败到确定根因所需的时间,以及“无法复现、按不稳定问题关闭”的 ticket 数量。当查看 trace 取代人工复现,成为默认的第一步后,这两个指标都应该发生变化。
在 retry 时记录 trace,不要每次运行都记录。on-first-retry(或者在不使用 retries 时采用 retain-on-failure)能够以远低于 on 的存储和运行成本,为失败提供完整的调试数据。
直接在 CI 输出中添加 trace 链接。由于 show-trace 和 trace.playwright.dev 都支持 URL,因此可以把 CI 的 artifact 链接直接接入一键 trace 查看流程,省去手动下载和解压的步骤。
把“无法复现”视为流程缺口,而不是运气不好。如果失败再次出现,却没有附带 trace,这意味着你应该扩大 trace 覆盖范围,而不是简单地再次运行测试套件。
Trace Viewer 文档——完整介绍每个 tab 和功能
testOptions.trace——配置参考
trace.playwright.dev——托管版 Viewer,无须使用 CLI 即可打开 trace
Playwright 文档——通用指南,包括 CI 配置
大部分测试调试时间并没有用在修复 bug 上,而是用在重新构造暴露 bug 的条件上。Trace Viewer 通过保留测试运行本身的完整记录,移除了这个步骤,让问题从“我能复现它吗?”变成“Trace 显示了什么?”
对工程团队而言,它的价值并不体现在调试工具变得更漂亮,而是体现在用于复现失败的工程时间减少了。更短的调试周期、更少的不必要 CI 重跑,以及更快的根因分析,都会同时改善开发者生产力并降低基础设施成本。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。