7.3 KiB
7.3 KiB
分层测试优化指南
概述
本文档介绍如何使用分层测试系统来优化测试执行效率,缩短测试时间,提高测试质量。
测试层级
快速层 (Fast Tier)
特点:
- 执行时间:30秒内
- 测试类型:冒烟测试、API测试、基础功能验证
- 并行度:高(75% workers)
- 失败策略:快速失败(failFast: true)
- 重试次数:1次
适用场景:
- 每次代码提交后的快速验证
- 持续集成(CI)中的第一道防线
- 关键路径的功能验证
示例:
test.describe('API快速测试 @smoke @critical', () => {
test('应该能够获取内容列表', async ({ request }) => {
const response = await request.get('/api/admin/content');
expect(response.status()).toBe(200);
});
});
标准层 (Standard Tier)
特点:
- 执行时间:60秒内
- 测试类型:功能测试、响应式测试、移动端核心功能
- 并行度:中(50% workers)
- 失败策略:继续执行(failFast: false)
- 重试次数:2次
适用场景:
- 功能分支合并前的验证
- 回归测试的主要部分
- 跨浏览器/设备测试
示例:
test.describe('管理后台功能测试 @admin @regression', () => {
test('应该能够创建和编辑新闻', async ({ page }) => {
await page.goto('/admin/news');
await page.click('[data-testid="create-news-btn"]');
// ... 测试逻辑
});
});
深度层 (Deep Tier)
特点:
- 执行时间:120秒内
- 测试类型:视觉回归、性能测试、完整回归测试
- 并行度:低(25% workers)
- 失败策略:继续执行(failFast: false)
- 重试次数:3次
适用场景:
- 发布前的完整验证
- 夜间/周末的全面回归
- 性能和视觉质量检查
示例:
test.describe('首页视觉回归测试 @visual @regression', () => {
test('首页应该与基准截图一致', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png');
});
});
使用方法
本地开发
运行快速层测试
npm run test:tier:fast
运行标准层测试
npm run test:tier:standard
运行深度层测试
npm run test:tier:deep
运行所有层级测试
npm run test:tier:all
CI/CD集成
Woodpecker CI配置
项目已配置Woodpecker CI工作流,支持分层测试自动化执行:
-
完整工作流 (
.woodpecker/test-tiered.yml)- 依次执行快速层、标准层、深度层
- 前一层失败则停止后续执行
- 生成测试报告并上传
- 发送通知
-
简化工作流 (
.woodpecker/test-tiered-simple.yml)- 根据分支类型执行不同层级
- main分支:执行所有层级
- develop分支:执行快速层和标准层
- 其他分支:仅执行快速层
测试标记
使用测试标记来分类和管理测试:
test.describe('测试套件 @smoke @critical', () => {
test('测试用例 @api @regression', async ({ page }) => {
// 测试逻辑
});
});
可用标记:
@smoke- 冒烟测试@critical- 关键测试@regression- 回归测试@visual- 视觉测试@performance- 性能测试@api- API测试@mobile- 移动端测试@responsive- 响应式测试@admin- 管理后台测试@a11y- 可访问性测试@security- 安全测试
性能优化
识别慢速测试
使用性能优化工具分析测试执行时间:
cd e2e && node test-optimizer-simple-test.js
工具会生成优化报告,包含:
- 慢速测试列表
- 优化建议
- 潜在时间节省
优化建议
1. 减少等待时间
// 不推荐
await page.waitForTimeout(5000);
// 推荐
await page.waitForSelector('[data-testid="result"]', { timeout: 5000 });
2. 优化选择器
// 不推荐
await page.click('div > div > button');
// 推荐
await page.click('[data-testid="submit-btn"]');
3. 并行测试
// playwright.config.tiered.ts
{
fullyParallel: true, // 启用并行执行
workers: '75%', // 使用75%的CPU核心
}
4. 测试拆分
// 不推荐:单个大测试
test('完整的用户注册流程', async ({ page }) => {
await page.goto('/register');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password123');
await page.fill('[name="confirm"]', 'password123');
await page.click('[type="submit"]');
await page.waitForURL('/dashboard');
await page.click('[data-testid="profile"]');
// ... 更多步骤
});
// 推荐:拆分为多个小测试
test.describe('用户注册流程', () => {
test('应该能够填写注册表单', async ({ page }) => {
await page.goto('/register');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password123');
await page.fill('[name="confirm"]', 'password123');
});
test('应该能够提交注册', async ({ page }) => {
await page.goto('/register');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password123');
await page.fill('[name="confirm"]', 'password123');
await page.click('[type="submit"]');
});
});
监控和告警
测试执行历史
系统会自动记录每次测试执行的历史数据,包括:
- 执行时间
- 成功/失败状态
- 测试标记
历史数据存储在 e2e/test-history.json。
告警规则
系统会根据以下规则触发告警:
- 测试通过率低于80% (Critical)
- 测试通过率低于90% (High)
- 测试执行时间超过30分钟 (Medium)
- 失败测试数量超过10个 (High)
- 深度层测试存在失败 (Critical)
查看告警
告警信息会输出到控制台,并保存在 test-results/alerts.json。
最佳实践
1. 测试分层原则
- 快速层:只包含最关键的测试,确保在5分钟内完成
- 标准层:包含大部分功能测试,确保在30分钟内完成
- 深度层:包含完整的回归测试,可以接受较长的执行时间
2. 测试标记使用
- 为每个测试套件添加合适的标记
- 优先使用
@smoke和@critical标记关键测试 - 使用
@regression标记需要定期运行的测试
3. 持续优化
- 定期运行性能优化工具
- 关注慢速测试的优化
- 根据历史数据调整测试分层
4. CI/CD集成
- 在每次提交时运行快速层测试
- 在合并PR时运行标准层测试
- 在发布前运行深度层测试
故障排查
测试超时
问题: 测试执行超时
解决方案:
- 检查是否有不必要的等待
- 增加测试超时时间
- 检查网络请求是否正常
测试不稳定
问题: 测试时好时坏
解决方案:
- 增加重试次数
- 使用更稳定的等待策略
- 检查是否有竞态条件
执行时间过长
问题: 测试执行时间超过预期
解决方案:
- 运行性能优化工具
- 检查是否有慢速测试
- 考虑调整测试分层