乐于分享
好东西不私藏

AI软件测试工程:Lesson 0010:E2E 测试入门:Playwright 实战

AI软件测试工程:Lesson 0010:E2E 测试入门:Playwright 实战

第五部分:E2E 测试 · Level 3 进阶

从用户的视角测试完整用户路径,用 Playwright 模拟真实用户在浏览器中的操作,为测试项目TaskFlow 建立最后一道防线。


学习目标

为什么学习

单元测试能发现函数级别的 Bug,集成测试能发现模块协作的 Bug。但有些 Bug 只有真实用户在浏览器中操作才能发现

  • 页面加载顺序问题(JS 执行时机)
  • 浏览器兼容性问题
  • 网络请求竞态条件
  • 真实用户交互流程

你将掌握

  • E2E 测试与单元测试、集成测试的区别
  • Playwright 安装与配置
  • 元素定位器(Selectors)
  • 编写完整的 E2E 测试
  • 调试和报告

一、什么是 E2E 测试?

💡 比喻 · E2E 测试 = 试车

  • 单元测试 = 测试发动机零件(活塞是否合格)
  • 集成测试 = 测试发动机装配(活塞+曲轴是否配合)
  • E2E 测试 = 试驾(发动机+变速箱+底盘一起工作)

你可以测试每一个零件都合格,但不上路,你怎么知道车真的能开?

E2E vs 单元测试 vs 集成测试

维度
单元测试
集成测试
E2E 测试
测试范围
单个函数
多个模块
完整用户路径
运行环境
Node.js(Mock)
Node.js(部分 Mock)
真实浏览器
执行速度
毫秒级
秒级
分钟级
Bug 定位
精准
较精准
模糊

⚠️ 重要:E2E 测试慢、不稳定、维护成本高。只测关键用户路径,不要测每一个细节。


二、Playwright vs Cypress vs Selenium

维度
Playwright
Cypress
Selenium
速度
快(并行执行)
中等
多浏览器
✅ 三种浏览器
✅ 三种浏览器
✅ 多种浏览器
自动等待
✅ 智能等待
✅ 自动等待
❌ 需手动等待
推荐场景
Next.js + TypeScript
React 项目
跨语言团队

三、元素定位器(Selectors)

推荐的选择器

类型
语法
示例
说明
Role
getByRole
getByRole('button', { name: '登录' })
✅ 无障碍最佳
Label
getByLabel
getByLabel('用户名')
✅ 表单字段
Placeholder
getByPlaceholder
getByPlaceholder('请输入邮箱')
✅ 输入框
Text
getByText
getByText('提交')
✅ 可见文本
Test ID
getByTestId
getByTestId('submit-btn')
✅ 最稳定

避免的选择器

类型
问题
CSS 选择器
脆弱,依赖样式
XPath
复杂,难维护
精确坐标
极度脆弱 ❌

四、第一个 E2E 测试

TaskFlow 测试示例

// tests/taskflow.spec.ts
import { test, expect } from '@playwright/test'

test.describe('TaskFlow 核心功能'() => {

  test.beforeEach(async ({ page }) => {
await page.goto('/')
  })

test('创建新任务'async ({ page }) => {
// 1. 点击"新建任务"按钮
await page.getByRole('button', { name'新建任务' }).click()

// 2. 填写任务表单
await page.getByLabel('任务标题').fill('学习 Playwright')
await page.getByRole('button', { name'保存' }).click()

// 3. 验证任务出现在列表中
await expect(page.getByText('学习 Playwright')).toBeVisible()
  })

test('登录功能'async ({ page }) => {
await page.getByRole('link', { name'登录' }).click()
await page.getByLabel('邮箱').fill('test@taskflow.com')
await page.getByLabel('密码').fill('password123')
await page.getByRole('button', { name'登录' }).click()
await expect(page.getByText('欢迎回来')).toBeVisible()
  })

})

Playwright 配置

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test'

export default defineConfig({
testDir'./tests',
fullyParalleltrue,
retries: process.env.CI ? 2 : 0,
use: {
baseURL'http://localhost:3000',
trace'on-first-retry',
screenshot'only-on-failure',
  },
projects: [
    { name'chromium'use: { ...devices['Desktop Chrome'] } },
  ],
webServer: {
command'npm run dev',
url'http://localhost:3000',
  },
})

运行测试

npx playwright test# 运行所有测试
npx playwright test --ui     # 交互式 UI
npx playwright show-report    # 查看报告

五、高级特性

自动等待

// 自动等待元素可见
await page.getByRole('button', { name'提交' }).click()

// 显式等待
await expect(page.getByText('操作成功')).toBeVisible({ timeout10000 })

// 等待网络请求
await page.waitForResponse(response =>
  response.url().includes('/api/tasks') && response.status() === 200
)

截图与录制

// 截图
await page.screenshot({ path'homepage.png'fullPagetrue })

// 录制 trace(详细调试信息)
await page.context().tracing.start({ screenshotstruesnapshotstrue })
// ... 执行操作 ...
await page.context().tracing.stop()

API 请求测试

test('API 请求测试'async ({ request }) => {
const response = await request.post('/api/tasks', {
data: { title'API 创建的任务' },
  })

expect(response.status()).toBe(201)
const task = await response.json()
expect(task.title).toBe('API 创建的任务')
})

六、🤖 AI 实践

AI 实践 1:用 AI 生成 E2E 测试

Prompt 模板

请为以下 React 组件生成 Playwright E2E 测试。

组件是一个登录表单,包含:
- 邮箱输入框
- 密码输入框
- 记住我复选框
- 登录按钮
- 点击登录后跳转到 /dashboard
- 错误提示

请生成使用 getByRole/getByLabel 的完整测试。

AI 实践 2:用 AI 设计 E2E 测试策略

请为 Next.js + Supabase 的 Todo 应用设计 E2E 测试策略。

应用功能:注册/登录、创建/编辑/删除任务、分类、截止日期、完成、筛选搜索

请给出:
1. 应该测试的关键路径(不超过 10 个)
2. 每个路径的测试用例

七、✅ QA Checklist


八、❓ 思考题

  1. E2E 测试和单元测试各有什么优缺点?为什么 E2E 测试不能替代单元测试?
  2. 什么样的测试用例应该用 E2E?什么样的应该用单元测试?
  3. E2E 测试的"Flaky"(不稳定)问题如何解决?
  4. Playwright 的"自动等待"机制是如何工作的?
  5. 如何平衡 E2E 测试的覆盖率和维护成本?

九、推荐阅读

类型
资源
说明
文章
Playwright Documentation
官方文档
文章
Playwright Selectors
选择器最佳实践
文章
Write Tests
Kent C. Dodds

下一节预告

API 测试:REST API 验证

  • REST API 基础
  • API 测试 vs E2E 测试
  • Supabase API 测试
  • API 错误处理测试
  • TaskFlow API 测试实战