Skip to content

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 AgentGAN 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,
  },
})

实际操作:

  • 按需调整 baseURLreporterprojects,支持多浏览器/移动端自动化
  • 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=3

3. 常见 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: 30

Step 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/*.zip

Step 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-eachretries 批量检测,配合 test.skiptest.fixme 隔离不稳定用例,并优化等待、断言逻辑消除根因。

Q: 测试产物如何在 CI 中自动归档和分析?
A: 按 Skill 推荐配置,所有截图、视频、trace 会自动上传为 artifact,配合标准化报告便于失败回归和团队同步。