Community写作与编辑github.com

End-to-End 测试技能

编写、调试和审查端到端测试,像用户一样通过浏览器、命令行或 API 驱动整个应用。涵盖哪些旅程值得 e2e 测试、稳定的定位器、基于条件的等待、隔离的测试数据、通过追踪调试失败以及从根本上修复不稳定测试。当仓库没有 e2e 工具时默认使用 Playwright。

End-to-End 测试技能 是什么?

该技能专注于端到端测试的编写、调试和审查,确保开发者能够像真实用户一样通过浏览器、命令行或 API 驱动整个应用。它强调每个 e2e 测试必须有其存在的价值,并且能够可靠地重复执行。技能涵盖了关键旅程的选择、稳定定位器的使用(如角色和可访问名称)、基于条件的等待机制、隔离的测试数据管理,以及通过追踪和截图等证据进行故障排除。默认使用 Playwright 作为 e2e 框架,但也尊重仓库已有的工具配置。此外,它还提供了 CLI 和 API 端到端测试的指导,以及处理不稳定测试和失败的检查清单,以帮助开发者构建可信赖的测试套件。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/lggarrison/agent-skills/tree/HEAD/skills/e2e-testing

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

端到端测试

端到端测试运行真实的应用程序,以用户获取它的方式构建和启动,并从外部驱动它:浏览器点击页面、Shell 运行 CLI 或客户端调用 API。它能捕获单元测试无法发现的问题:连接、配置、路由以及各部分之间的接缝。它也是最慢且最脆弱的测试类型,因此每个测试都必须有其存在的价值,并确保每次运行都给出相同的结果。

相关技能 unit-testing 涵盖单个单元的测试。当某个行为可以在两个级别中任意一个检查时,请使用单元测试。

仓库规则优先

使用仓库的 e2e 框架、配置、文件夹、测试夹具和脚本。在编写测试之前,请阅读现有的测试和配置(playwright.config.*、cypress.config.* 等),并与它们保持一致。AGENTS.md、CONTRIBUTING.md 和包脚本说明了 e2e 测试如何运行以及针对什么运行。如果与本技能冲突,以它们为准。不要添加第二个 e2e 框架。

默认工具

当仓库还没有 e2e 工具时,对于任何涉及浏览器的场景,请使用 Playwright (@playwright/test)。它适用于任何 Web 应用,无论后端使用什么语言。这里的示例使用 Playwright。这些规则适用于任何工具。

哪些值得编写 e2e 测试

  • 关键旅程: 注册、登录、产品存在的核心任务、结账,以及任何在生产中出现过问题的地方。
  • 集成点: 一个需要真实后端、身份验证或路由才能正常工作的页面。
  • 每条旅程一个快乐路径, 加上用户实际可能遇到的失败情况(密码错误、付款被拒)。

将所有其他情况推送到单元测试:每个验证规则、每个格式情况、每个计算分支。试图覆盖所有情况的 e2e 测试套件会变得过于缓慢且不稳定,无法信任。

定位器

像用户一样查找元素,这样测试才能经受住标记和样式变化的考验。

  • 按顺序优先选择: 角色和可访问名称 (getByRole('button', { name: 'Save' }))、标签 (getByLabel('Email'))、可见文本,然后才是测试 ID (getByTestId),当没有稳定的用户可见内容时使用。
  • 避免使用: CSS 类、XPath、nth-child 和元素位置。它们会在布局变化时失效,并且无法说明用户看到的内容。
  • 如果元素无法通过角色或标签找到,这通常是一个可访问性错误。应指出这一点,而不是使用脆弱的定位器。

等待

永远不要等待固定的时间。sleep、waitForTimeout 和 setTimeout 在缓慢的 CI 机器上可能不够长,而在快速的机器上则浪费时间。

  • 使用会重试直到通过或超时的断言:await expect(page.getByRole('alert')).toHaveText('Saved')。
  • 等待用户会等待的条件:元素可见、URL 变化、收到响应 (page.waitForResponse)、文件写入完成。
  • 不要为了修复失败而提高超时时间。如果某件事确实需要很长时间,仅为该步骤提高超时时间并说明原因。
  • 不要强制操作绕过框架的检查 ({ force: true })。如果点击需要强制,说明有元素覆盖或未准备好,真实用户也会遇到同样的问题。

测试数据和隔离

  • 每个测试设置自己的状态,并能独立、按任意顺序、并行运行。没有测试依赖于另一个测试的先执行。
  • 确保每个测试的数据唯一(例如生成唯一的电子邮件或 ID),这样并行工作进程和重试不会冲突。
  • 通过后端方式设置。 通过 API、种子脚本或测试夹具创建用户和记录,而不是通过点击 UI。只有在测试中的旅程才通过 UI 进行。
  • 登录一次并复用。 在设置步骤中保存经过身份验证的状态(Playwright 的 storageState),而不是在每个测试中通过表单登录。
  • 只伪造你不拥有的东西。 在网络边界使用 page.route() 或本地虚拟服务来模拟第三方服务(支付、电子邮件、地图)。保持你自己的前端、后端和数据库真实,否则就不是端到端测试。

CLI 和 API 端到端测试

无需浏览器时,规则同样适用。使用仓库的单元测试运行器(JavaScript 和 TypeScript 使用 Vitest)运行 CLI 测试,放在单独的配置或项目中,以免拖慢单元测试套件。API 测试可以使用 Playwright 的 request 测试夹具或相同的运行器。

  • 运行构建后的产物,和用户运行它的方式相同,而不是通过仅用于测试的入口点运行源代码。
  • 为每个测试提供一个临时目录作为工作目录,并将 HOME、配置路径和缓存指向该目录,这样测试就不会读取或更改开发者的真实文件。
  • 分别断言退出码、标准输出、标准错误和创建的文件。仅检查“没有抛出异常”的测试会遗漏错误的输出。
  • 在比较输出之前,剥离或冻结运行之间会变化的内容(时间戳、临时路径、持续时间)。

测试失败时

在修改任何内容之前,先查看证据。

  1. 获取产物。 为失败开启追踪、截图和视频(Playwright:trace: 'on-first-retry',screenshot: 'only-on-failure'),并打开 CI 运行中的追踪(npx playwright show-trace <trace.zip>)。追踪显示每一步的页面、网络和控制台。
  2. 确定是谁的 bug。 如果应用出错了,修复应用;测试完成了它的工作。如果测试出错了,修复测试。如果环境出错了(服务宕机、端口被占用),修复设置。
  3. 重现问题,使用与 CI 相同的命令、浏览器和设置,包括无头模式和工作进程数。
  4. 对于不稳定的测试,找到竞态条件。 常见原因:固定等待、页面未准备好就操作、与其他测试共享数据,或者动画或提示覆盖了元素。修复那个原因,然后连续多次运行该测试(npx playwright test <file> --repeat-each=20 --retries=0)之后再宣布修复完成。

CI 重试可以保持管道绿色,但仅在重试后通过的测试仍然是失败的。将报告中标注为“不稳定”的测试视为需要修复的 bug,而非某种状态。未经用户同意,切勿跳过、删除或隔离测试以使其变绿,也不要为了使其通过而放宽断言。

检查清单

在交付 e2e 测试或审查它们之前:

  • 该旅程需要进行 e2e 测试。单元测试能检查的情况应使用单元测试。
  • 定位器使用角色、标签、文本或测试 ID。没有 CSS 链或 XPath。
  • 没有固定等待、强制操作或提高全局超时。
  • 每个测试创建自己的唯一数据,并能独立和并行运行。
  • 只有第三方服务被模拟。
  • 失败后会在 CI 中留下追踪或截图。
  • 新的或修复后的测试在关闭重试的情况下连续多次通过。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相关技能