实战

Claude Code Playwright E2E 测试实战:AI 辅助编写端到端测试完全指南(2026)

Claude Code 辅助 Playwright E2E 测试完整指南:从用户故事直接生成 Page Object Model 测试、修复 Flaky Tests(硬等待→等待元素/网络请求)、API Mock + E2E 联合测试、GitHub Actions CI/CD 并行分片(3 shard 加速)、截图视频上传,附从截图生成测试/边界条件批量生成/Core Web Vitals 测试 Prompt 模板。

2026/3/295分钟 阅读ClaudeEagle

E2E 测试是保障 Web 应用质量的最后防线, 但也是最费时的测试类型——页面定位器、等待条件、断言…… Claude Code 能帮你大幅提速:描述用户行为,直接生成测试。

Claude Code 在 Playwright 测试中的优势

擅长的任务: 根据需求/页面截图生成完整测试用例 生成 Page Object Model(POM)封装 修复脆弱测试(flaky tests) 生成测试数据 fixtures 把手动测试步骤转换为自动化测试 需要人工介入: 复杂的视觉回归测试(像素级对比) 动态内容的精确断言 特定业务逻辑的边界条件

项目初始化

bash
# 初始化 Playwright
npm init playwright@latest

# 告诉 Claude Code 你的项目结构
claude
> 这是一个 Next.js 15 电商项目,
  playwright.config.ts 已配置好,
  帮我设计 E2E 测试的目录结构和命名规范

场景一:从用户故事生成测试

告诉 Claude Code: 用户故事: 作为用户,我希望能够: 1. 注册账号(填写邮箱/密码/用户名) 2. 登录(记住密码) 3. 浏览商品列表,支持分类筛选 4. 添加商品到购物车 5. 结账(填写地址 + 支付) 帮我用 Playwright + TypeScript 写这些 E2E 测试, 使用 Page Object Model 模式。

Claude Code 生成的 POM 示例:

typescript
// tests/pages/LoginPage.ts
import { Page, Locator } from '@playwright/test'

export class LoginPage {
  private readonly emailInput: Locator
  private readonly passwordInput: Locator
  private readonly submitButton: Locator
  private readonly errorMessage: Locator

  constructor(private page: Page) {
    this.emailInput = page.getByLabel('邮箱')
    this.passwordInput = page.getByLabel('密码')
    this.submitButton = page.getByRole('button', { name: '登录' })
    this.errorMessage = page.getByTestId('login-error')
  }

  async goto() {
    await this.page.goto('/login')
  }

  async login(email: string, password: string) {
    await this.emailInput.fill(email)
    await this.passwordInput.fill(password)
    await this.submitButton.click()
  }

  async getErrorMessage() {
    return this.errorMessage.textContent()
  }
}

// tests/auth.spec.ts
import { test, expect } from '@playwright/test'
import { LoginPage } from './pages/LoginPage'
import { testUsers } from './fixtures/users'

test.describe('用户认证', () => {
  test('正常登录流程', async ({ page }) => {
    const loginPage = new LoginPage(page)
    await loginPage.goto()
    await loginPage.login(testUsers.valid.email, testUsers.valid.password)
    await expect(page).toHaveURL('/dashboard')
    await expect(page.getByText('欢迎回来')).toBeVisible()
  })

  test('密码错误时显示错误信息', async ({ page }) => {
    const loginPage = new LoginPage(page)
    await loginPage.goto()
    await loginPage.login(testUsers.valid.email, 'wrong-password')
    const error = await loginPage.getErrorMessage()
    expect(error).toContain('邮箱或密码不正确')
  })

  test('记住密码功能', async ({ page, context }) => {
    const loginPage = new LoginPage(page)
    await loginPage.goto()
    await page.getByLabel('记住我').check()
    await loginPage.login(testUsers.valid.email, testUsers.valid.password)

    // 新页面检查 Cookie 持久化
    const cookies = await context.cookies()
    const authCookie = cookies.find(c => c.name === 'auth_token')
    expect(authCookie?.expires).toBeGreaterThan(Date.now() / 1000 + 86400)
  })
})

场景二:修复 Flaky Tests

告诉 Claude Code: 这个测试不稳定,大约 30% 的情况下失败, 错误是 "Timeout waiting for element": [粘贴失败的测试代码] 帮我分析原因并修复。

Claude Code 常见诊断和修复:

typescript
// 修复前(脆弱):硬等待
await page.waitForTimeout(2000)
await page.click('#submit-btn')

// 修复后(稳定):等待元素可交互
await page.getByRole('button', { name: '提交' }).waitFor({ state: 'visible' })
await page.getByRole('button', { name: '提交' }).click()

// 修复:等待网络请求完成
await Promise.all([
  page.waitForResponse(resp => resp.url().includes('/api/order') && resp.status() === 200),
  page.getByRole('button', { name: '下单' }).click()
])

场景三:API Mock + E2E 联合测试

帮我写一个测试: 用 Playwright 的 route 拦截 /api/products 请求, 返回固定的 mock 数据(避免依赖真实 API), 然后测试商品列表页的渲染是否正确。
typescript
test('商品列表使用 mock 数据正确渲染', async ({ page }) => {
  const mockProducts = [
    { id: 1, name: 'iPhone 16', price: 5999, inStock: true },
    { id: 2, name: 'MacBook Pro', price: 14999, inStock: false },
  ]

  await page.route('**/api/products', async route => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ data: mockProducts })
    })
  })

  await page.goto('/products')
  await expect(page.getByText('iPhone 16')).toBeVisible()
  await expect(page.getByText('¥5,999')).toBeVisible()
  await expect(page.getByText('MacBook Pro')).toBeVisible()

  // 库存不足的商品显示"售罄"
  const macbookCard = page.getByTestId('product-card-2')
  await expect(macbookCard.getByText('售罄')).toBeVisible()
  await expect(macbookCard.getByRole('button', { name: '加入购物车' })).toBeDisabled()
})

场景四:CI/CD 集成

帮我写 GitHub Actions 工作流, 在每次 PR 时运行 Playwright E2E 测试: - 并行运行(3 个 shard)加速 - 失败时上传截图和视频 - 生成测试报告推送到 PR 评论
yaml
name: E2E Tests
on: [pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3]  # 并行 3 个分片
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: npm ci
      - run: npx playwright install --with-deps chromium
      - run: npx playwright test --shard=${{ matrix.shard }}/3
        env:
          BASE_URL: ${{ vars.STAGING_URL }}
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report-${{ matrix.shard }}
          path: playwright-report/

高价值 Prompt 模板

[从截图生成测试] 这是我的登录页面截图,帮我根据页面元素 生成完整的 Playwright 登录流程测试: [附上截图] [批量生成边界条件测试] 基于这个用户注册表单,帮我生成所有边界条件测试: 空字段/超长输入/特殊字符/已存在邮箱/弱密码等 [粘贴表单代码或截图] [性能测试] 帮我用 Playwright 测试这个页面的 Core Web Vitals: LCP < 2.5s, FID < 100ms, CLS < 0.1 [粘贴页面 URL 或组件代码]

来源:Playwright 官方文档 + Anthropic Claude Code 文档

相关文章推荐

实战Claude Code Playwright E2E 测试实战:AI 辅助编写端到端测试完全指南(2026)Claude Code 辅助 Playwright E2E 测试完整指南:从用户故事直接生成 Page Object Model 测试、修复 Flaky Tests(硬等待→等待元素/API请求)、API Mock 联合测试、GitHub Actions 并行3分片CI加速,附截图生成测试/批量边界条件/Core Web Vitals 测试 Prompt 模板。2026/3/29实战Claude Code Prisma ORM 实战完全指南:AI 辅助现代 TypeScript 数据库开发(2026)Claude Code 辅助 Prisma ORM 开发的完整实战指南:从需求直接生成 Prisma Schema(多表关系/@relation/@@index/枚举)、复杂查询生成(include/select/cursor分页)、Prisma 事务处理(原子操作/库存扣减)、安全的数据库 Migration 策略(生产环境不停机迁移)、N+1 查询问题排查与优化,覆盖 PostgreSQL/MySQL/SQLite 三种数据库。2026/3/27实战Claude Code + NestJS 实战:用 AI 构建企业级 TypeScript 后端服务Claude Code 与 NestJS 框架深度协作实战:模块化架构设计(Module/Controller/Service/Provider)、让 Claude 生成符合 NestJS 惯例的 CRUD 模块、依赖注入系统的 AI 辅助使用、Guards 认证守卫(JWT/Role-based)、Interceptors 全局日志与请求变换、Pipes 数据验证(class-validator)、Exception Filters 统一异常处理、TypeORM 集成与数据库迁移、Swagger 文档自动生成,以及 NestJS 微服务(Microservices)架构入门。2026/3/21实战Claude Code 自动生成测试用例:单元测试、集成测试和 E2E 测试完整指南Claude Code 自动生成测试用例完整指南:从函数签名生成边界条件测试、Table-Driven 测试模式、Mock 依赖注入、集成测试数据库 Fixtures、Playwright E2E 测试生成,以及提升测试覆盖率的系统化 Prompt 策略和 TDD 工作流。2026/3/16实战Claude Code 写 React 组件:从需求描述到单元测试的完整工作流Claude Code 开发 React 组件完整工作流:需求转组件设计、TypeScript Props 定义、Hooks 实现、Tailwind 样式、React Testing Library 测试、Storybook 文档,以及复杂组件(表格/表单/弹窗)的高效开发模式。2026/3/15实战Claude Code + Next.js 15 全栈开发实战:从零搭建现代 Web 应用Claude Code 与 Next.js 15 结合开发完整教程:App Router 结构生成、Server/Client Components、API Routes、Prisma 数据库集成、Tailwind CSS UI、NextAuth 认证、Vercel 部署,以及 Claude Code 加速 Next.js 开发的 10 个核心工作流。2026/3/15