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 文档