元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
入门指南
Playwright安装与配置
环境要求与验证
第一个自动化测试脚本
▶
核心概念
Browser对象详解
Page对象操作指南
Frame与上下文管理
网络请求拦截与Mock
▶
元素定位与操作
CSS选择器实战
XPath高级定位技巧
文本定位与正则匹配
动态元素等待策略
▶
高级操作指南
文件上传下载处理
多标签页与弹窗管理
浏览器上下文隔离
设备模拟与地理定位
▶
测试框架集成
Jest集成配置
Mocha测试报告生成
持续集成CI/CD配置
▶
最佳实践
测试用例组织结构
性能优化策略
跨浏览器测试方案
▶
疑难解答
常见错误代码解析
元素定位失败分析
浏览器启动问题排查
▶
录制功能指南
录制功能基础入门
录制脚本生成与编辑
高级录制配置与技巧
录制脚本调试与优化
发布时间:
2025-03-27 19:19
↑
☰
# 测试用例组织结构 本文将详细介绍如何在Playwright中组织和管理测试用例,帮助你构建可维护和可扩展的测试项目。 ## 基本结构 ### 1. 目录结构 ```bash ├── tests/ │ ├── e2e/ │ │ ├── auth/ │ │ │ ├── login.spec.ts │ │ │ └── register.spec.ts │ │ └── user/ │ │ ├── profile.spec.ts │ │ └── settings.spec.ts │ ├── integration/ │ │ ├── api.spec.ts │ │ └── services.spec.ts │ ├── fixtures/ │ │ ├── auth.fixture.ts │ │ └── data.fixture.ts │ └── utils/ │ ├── helpers.ts │ └── selectors.ts ├── playwright.config.ts └── package.json ``` ### 2. 配置文件 ```typescript // playwright.config.ts import { PlaywrightTestConfig } from '@playwright/test'; const config: PlaywrightTestConfig = { testDir: './tests', testMatch: '**/*.spec.ts', timeout: 30000, retries: 2, workers: 4, reporter: [ ['list'], ['html', { open: 'never' }] ], projects: [ { name: 'e2e', testMatch: /\/e2e\/.+\.spec\.ts/ }, { name: 'integration', testMatch: /\/integration\/.+\.spec\.ts/ } ] }; export default config; ``` ## 测试组织 ### 1. 测试套件 ```typescript // tests/e2e/auth/login.spec.ts import { test, expect } from '@playwright/test'; import { LoginPage } from '../../pages/login.page'; test.describe('登录功能', () => { let loginPage: LoginPage; test.beforeEach(async ({ page }) => { loginPage = new LoginPage(page); await loginPage.goto(); }); test('成功登录', async () => { await loginPage.login('admin', '123456'); await expect(loginPage.welcomeMessage).toBeVisible(); }); test('登录失败', async () => { await loginPage.login('wrong', 'wrong'); await expect(loginPage.errorMessage).toBeVisible(); }); }); ``` ### 2. 页面对象模式 ```typescript // tests/pages/login.page.ts import { Page, Locator } from '@playwright/test'; export class LoginPage { readonly page: Page; readonly usernameInput: Locator; readonly passwordInput: Locator; readonly loginButton: Locator; readonly errorMessage: Locator; constructor(page: Page) { this.page = page; this.usernameInput = page.getByLabel('用户名'); this.passwordInput = page.getByLabel('密码'); this.loginButton = page.getByRole('button', { name: '登录' }); this.errorMessage = page.getByText('登录失败'); } async goto() { await this.page.goto('/login'); } async login(username: string, password: string) { await this.usernameInput.fill(username); await this.passwordInput.fill(password); await this.loginButton.click(); } } ``` ## 最佳实践 ### 1. 测试数据管理 ```typescript // tests/fixtures/data.fixture.ts import { test as base } from '@playwright/test'; export const test = base.extend({ testData: async ({}, use) => { const data = { users: [ { username: 'admin', password: '123456' }, { username: 'user', password: '654321' } ], products: [ { id: 1, name: '商品1', price: 100 }, { id: 2, name: '商品2', price: 200 } ] }; await use(data); } }); export { expect } from '@playwright/test'; ``` ### 2. 共享工具函数 ```typescript // tests/utils/helpers.ts import { Page } from '@playwright/test'; export class TestHelpers { static async waitForLoading(page: Page) { await page.waitForSelector('.loading', { state: 'hidden' }); } static async mockApi(page: Page, url: string, data: any) { await page.route(url, async route => { await route.fulfill({ status: 200, body: JSON.stringify(data) }); }); } } ``` ## 高级特性 ### 1. 标签管理 ```typescript // tests/e2e/user/profile.spec.ts import { test } from '@playwright/test'; test.describe('用户资料', () => { test('查看资料 @smoke', async ({ page }) => { // 冒烟测试 }); test('编辑资料 @regression', async ({ page }) => { // 回归测试 }); test('上传头像 @slow', async ({ page }) => { // 耗时测试 }); }); // 运行特定标签的测试 // npx playwright test --grep @smoke ``` ### 2. 并行测试 ```typescript // tests/parallel.spec.ts import { test } from '@playwright/test'; // 串行测试组 test.describe.serial('需要顺序执行的测试', () => { test('步骤1', async ({ page }) => { // 第一步 }); test('步骤2', async ({ page }) => { // 第二步 }); }); // 并行测试组 test.describe('可以并行的测试', () => { test.describe.configure({ mode: 'parallel' }); test('测试1', async ({ page }) => { // 并行执行 }); test('测试2', async ({ page }) => { // 并行执行 }); }); ``` ## 调试技巧 ### 1. 测试调试 ```typescript // tests/debug.spec.ts import { test } from '@playwright/test'; test('调试测试', async ({ page }) => { // 启用调试模式 await test.step('打开页面', async () => { await page.goto('/'); await page.pause(); // 暂停执行 }); await test.step('执行操作', async () => { console.log('当前URL:', page.url()); await page.screenshot({ path: 'debug.png' }); }); }); ``` ### 2. 错误处理 ```typescript // tests/error.spec.ts import { test } from '@playwright/test'; test('错误处理', async ({ page }) => { test.fail(); // 标记预期失败 try { await page.click('.non-existent'); } catch (error) { console.error('测试失败:', error); // 自定义错误处理 } }); ``` ## 常见问题 ### 1. 测试隔离 ```typescript // tests/isolation.spec.ts import { test } from '@playwright/test'; test.describe('测试隔离', () => { test.beforeEach(async ({ context }) => { // 每个测试前清理状态 await context.clearCookies(); await context.clearLocalStorage(); }); test('独立测试1', async ({ page }) => { // 测试代码 }); test('独立测试2', async ({ page }) => { // 测试代码 }); }); ``` ### 2. 资源管理 ```typescript // tests/cleanup.spec.ts import { test } from '@playwright/test'; test.describe('资源清理', () => { const resources = []; test.afterEach(async () => { // 测试后清理资源 for (const resource of resources) { await resource.cleanup(); } resources.length = 0; }); test('资源测试', async ({ page }) => { const resource = await createTestResource(); resources.push(resource); // 使用资源 }); }); ``` ## 下一步 1. 学习[性能优化策略](/article/playwright/best-practices/performance) 2. 了解[跨浏览器测试方案](/article/playwright/best-practices/cross-browser) 3. 探索[常见错误代码解析](/article/playwright/troubleshooting/error-codes) ## 参考资料 - [Playwright测试组织](https://playwright.dev/docs/test-grouping) - [Playwright页面对象模式](https://playwright.dev/docs/pom) - [Playwright并行测试](https://playwright.dev/docs/test-parallel)