Appearance
Everything Claude Code 的 e2e-testing Skill 是 Playwright 端到端测试的最佳实践集合,专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)用户设计。它系统化地解决了 E2E 测试用例组织、Page Object Model(POM)封装、CI/CD 集成、测试产物管理、Flaky Test 识别与隔离等难题,让测试更稳定、可维护、易于团队协作与自动化。本文将带你逐步掌握如何在实际项目中用好该 Skill,提升 AI 辅助开发的测试质量与效率。
Everything Claude Code E2E Testing Skill:Playwright Page Object Model、CI 集成与 Flaky Test 策略
在现代 AI 辅助开发流程中,端到端(E2E)测试已成为保障产品质量、支撑快速迭代的核心环节。Everything Claude Code 的 e2e-testing Skill,专为 Playwright 测试体系打造,帮助开发者和 AI Agent 轻松实现高质量 E2E 测试的自动生成、维护与集成。相比于手工零散编写测试代码,该 Skill 提供了一套标准化的组织结构、POM 封装、CI/CD 集成与 Flaky Test 管理方案,极大提升了测试的稳定性和可维护性。
本指南将结合 Everything Claude Code 完全指南 的 Agent/Skill 工作流,详细介绍 e2e-testing Skill 的激活条件、实际操作步骤、输出示例及与其他 Agent/Skill 的协作模式。
1. 这个 Skill 解决什么问题?
传统 E2E 测试的痛点:
- 测试代码分散、结构混乱,难以维护和复用
- 多端/多浏览器兼容性、网络波动导致 Flaky Test 屡见不鲜
- CI/CD 集成不规范,产物收集与失败分析效率低
- 团队协作与 AI Agent 自动化难以落地
e2e-testing Skill 的优势:
- 规范化 Playwright 测试目录与文件结构,支持大规模协作
- 内置 Page Object Model(POM)模式,提升可读性与复用性
- 提供稳定的 Flaky Test 识别、隔离与重试机制
- 一键集成到 CI/CD,并自动管理截图、视频、trace 等测试产物
- 支持与 E2E Runner Agent、GAN Evaluator Agent 等协作,适配多 Agent 自动化测试与评分
2. 触发条件与适用场景
- AI Agent 生成或维护 E2E 测试时:如 Claude Code 自动补全、修复或重构 Playwright 测试用例
- CI/CD 流水线自动化测试:如 PR 检查、发布前验收测试等
- 多端/多浏览器兼容性验证:Chromium、Firefox、WebKit、移动端等
- Flaky Test 监控与治理:测试不稳定、偶发失败场景
- 测试产物归档与报告输出:便于回归分析和团队协作
3. 实践操作流程(Step by Step)
Step 1:标准化测试目录结构
Skill 推荐如下 Playwright 测试组织方式,便于团队协作与 AI Agent 自动生成/定位用例:
text
tests/
├── e2e/
│ ├── auth/
│ │ ├── login.spec.ts
│ │ ├── logout.spec.ts
│ │ └── register.spec.ts
│ ├── features/
│ │ ├── browse.spec.ts
│ │ ├── search.spec.ts
│ │ └── create.spec.ts
│ └── api/
│ └── endpoints.spec.ts
├── fixtures/
│ ├── auth.ts
│ └── data.ts
└── playwright.config.ts实际操作:
- 每个业务模块/功能单独建目录,测试文件以
.spec.ts结尾 - 公共测试数据、登录等放在
fixtures/ - 配置文件统一在根目录
Step 2:封装 Page Object Model(POM)
POM 是提升测试代码可维护性和复用率的关键。Skill 推荐如下写法:
typescript
import { Page, Locator } from '@playwright/test'
export class ItemsPage {
readonly page: Page
readonly searchInput: Locator
readonly itemCards: Locator
readonly createButton: Locator
constructor(page: Page) {
this.page = page
this.searchInput = page.locator('[data-testid="search-input"]')
this.itemCards = page.locator('[data-testid="item-card"]')
this.createButton = page.locator('[data-testid="create-btn"]')
}
async goto() {
await this.page.goto('/items')
await this.page.waitForLoadState('networkidle')
}
async search(query: string) {
await this.searchInput.fill(query)
await this.page.waitForResponse(resp => resp.url().includes('/api/search'))
await this.page.waitForLoadState('networkidle')
}
async getItemCount() {
return await this.itemCards.count()
}
}实际操作:
- 每个页面/模块单独建一个 Page 类,封装元素定位与常用操作
- 测试用例只需调用 POM 方法,降低重复代码
Step 3:编写结构化测试用例
结合 POM,测试用例更简洁、可读性高:
typescript
import { test, expect } from '@playwright/test'
import { ItemsPage } from '../../pages/ItemsPage'
test.describe('Item Search', () => {
let itemsPage: ItemsPage
test.beforeEach(async ({ page }) => {
itemsPage = new ItemsPage(page)
await itemsPage.goto()
})
test('should search by keyword', async ({ page }) => {
await itemsPage.search('test')
const count = await itemsPage.getItemCount()
expect(count).toBeGreaterThan(0)
await expect(itemsPage.itemCards.first()).toContainText(/test/i)
await page.screenshot({ path: 'artifacts/search-results.png' })
})
test('should handle no results', async ({ page }) => {
await itemsPage.search('xyznonexistent123')
await expect(page.locator('[data-testid="no-results"]')).toBeVisible()
expect(await itemsPage.getItemCount()).toBe(0)
})
})实际操作:
- 用
test.describe分组 beforeEach初始化 POM- 用
expect断言,失败自动截图
Step 4:Playwright 配置与多端兼容
Skill 推荐的 playwright.config.ts 配置模板,支持多端、多浏览器并发测试与 artifact 管理:
typescript
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html', { outputFolder: 'playwright-report' }],
['junit', { outputFile: 'playwright-results.xml' }],
['json', { outputFile: 'playwright-results.json' }]
],
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
actionTimeout: 10000,
navigationTimeout: 30000,
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'mobile-chrome', use: { ...devices['Pixel 5'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120000,
},
})实际操作:
- 按需调整
baseURL、reporter、projects,支持多浏览器/移动端自动化 trace/screenshot/video自动收集失败用例产物
Step 5:Flaky Test 策略与治理
E2E 测试常见 Flaky 问题,Skill 提供如下治理模式:
1. 隔离与跳过不稳定用例
typescript
test('flaky: complex search', async ({ page }) => {
test.fixme(true, 'Flaky - Issue #123')
// test code...
})
test('conditional skip', async ({ page }) => {
test.skip(process.env.CI, 'Flaky in CI - Issue #123')
// test code...
})2. 批量检测 Flaky Test
bash
npx playwright test tests/search.spec.ts --repeat-each=10
npx playwright test tests/search.spec.ts --retries=33. 常见 Flaky 场景与修复
- Race condition:typescript
// 推荐:auto-wait await page.locator('[data-testid="button"]').click() - 网络/动画等待:typescript
await page.waitForResponse(resp => resp.url().includes('/api/data')) await page.locator('[data-testid="menu-item"]').waitFor({ state: 'visible' }) await page.waitForLoadState('networkidle')
Step 6:测试产物(artifact)管理
Skill 推荐所有截图、trace、视频等统一归档,便于 CI 失败分析:
typescript
await page.screenshot({ path: 'artifacts/after-login.png' })
await page.screenshot({ path: 'artifacts/full-page.png', fullPage: true })
await page.locator('[data-testid="chart"]').screenshot({ path: 'artifacts/chart.png' })
// Trace
await browser.startTracing(page, {
path: 'artifacts/trace.json',
screenshots: true,
snapshots: true,
})
// ... test actions ...
await browser.stopTracing()配置自动视频录制:
typescript
use: {
video: 'retain-on-failure',
videosPath: 'artifacts/videos/'
}Step 7:CI/CD 集成
Skill 提供标准 GitHub Actions 工作流模板,支持自动运行 E2E 测试并上传产物:
yaml
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
env:
BASE_URL: ${{ vars.STAGING_URL }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30Step 8:输出标准化测试报告
Skill 推荐 Markdown 格式报告,便于团队和 AI Agent 自动解析:
markdown
# E2E Test Report
**Date:** YYYY-MM-DD HH:MM
**Duration:** Xm Ys
**Status:** PASSING / FAILING
## Summary
- Total: X | Passed: Y (Z%) | Failed: A | Flaky: B | Skipped: C
## Failed Tests
### test-name
**File:** `tests/e2e/feature.spec.ts:45`
**Error:** Expected element to be visible
**Screenshot:** artifacts/failed.png
**Recommended Fix:** [description]
## Artifacts
- HTML Report: playwright-report/index.html
- Screenshots: artifacts/*.png
- Videos: artifacts/videos/*.webm
- Traces: artifacts/*.zipStep 9:特殊场景支持(Web3、金融等)
Skill 还支持 Mock 钱包、链上交易等关键流自动测试:
typescript
test('wallet connection', async ({ page, context }) => {
await context.addInitScript(() => {
window.ethereum = {
isMetaMask: true,
request: async ({ method }) => {
if (method === 'eth_requestAccounts')
return ['0x1234567890123456789012345678901234567890']
if (method === 'eth_chainId') return '0x1'
}
}
})
await page.goto('/')
await page.locator('[data-testid="connect-wallet"]').click()
await expect(page.locator('[data-testid="wallet-address"]')).toContainText('0x1234')
})4. Skill 输出示例
- 自动生成结构化 Playwright 测试用例(含 POM 封装、断言、截图)
- 标准化测试报告(Markdown/HTML/JSON)
- 失败用例自动截图、Trace、视频归档
- CI/CD 流水线自动上传测试产物
- Flaky Test 自动隔离与重试机制
5. 常见配套 Agent 与 Skill 协作
- E2E Runner Agent:自动生成、运行、维护 E2E 测试,配合本 Skill 提升覆盖率与稳定性
- GAN Evaluator Agent:结合 E2E 测试结果进行自动评分、对抗式评估
- Verification Loop Skill:将 E2E 测试纳入端到端验证循环,实现 AI 代码生成/审查/回归一体化
- Browser QA Skill:针对 UI 交互的可视化自动化测试,与 E2E Skill 互补
FAQ
Q: e2e-testing Skill 与手写 Playwright 测试有何区别?
A: Skill 提供了结构化目录、POM 封装、CI/CD 集成、Flaky Test 策略等系统方案,极大提升可维护性和自动化程度,适合 AI Agent 生成和团队协作。
Q: 如何快速定位和修复 Flaky Test?
A: Skill 推荐用 repeat-each、retries 批量检测,配合 test.skip、test.fixme 隔离不稳定用例,并优化等待、断言逻辑消除根因。
Q: 测试产物如何在 CI 中自动归档和分析?
A: 按 Skill 推荐配置,所有截图、视频、trace 会自动上传为 artifact,配合标准化报告便于失败回归和团队同步。