Files
gym-manage/docs/superpowers/specs/2026-04-04-e2e-test-optimization-design.md
T

536 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# E2E测试优化设计方案
**文档版本**: 1.0
**创建日期**: 2026-04-04
**作者**: 张翔
**目标**: 将E2E测试通过率从17.3%提升至100%,并优化测试执行时间
---
## 1. 背景与目标
### 1.1 当前状态
- **总测试数**: 52个测试用例
- **通过**: 9个测试用例 (17.3%)
- **失败**: 43个测试用例 (82.7%)
- **执行时间**: 17.2分钟
### 1.2 主要问题
1. **页面导航问题**: 大部分测试用例无法正确导航到目标页面
2. **选择器问题**: 测试用例使用的选择器无法找到对应的页面元素
3. **测试执行时间**: 当前执行时间较长,需要优化
### 1.3 目标
- **测试通过率**: 100% (所有52个测试用例通过)
- **执行时间**: 减少30%以上 (从17.2分钟降至12分钟以内)
- **测试稳定性**: 所有测试用例稳定可重复执行
---
## 2. 实施策略
采用**分阶段实施**策略,按照问题的影响范围,从基础到高级逐步修复。
### 2.1 为什么选择分阶段实施?
- **风险可控**: 每个阶段都可以验证效果,及时调整方案
- **效率最高**: 先解决基础问题,再解决复杂问题,避免重复工作
- **符合测试金字塔**: 从基础功能到高级功能,逐步提高测试覆盖率
- **易于管理**: 每个阶段都有明确的目标和验收标准
---
## 3. 第一阶段:基础导航修复
**预计时间**: 2-3天
**目标**: 测试通过率提升至50%以上(至少26个测试用例通过)
### 3.1 问题分析
43个失败的测试用例中,大部分都是因为无法正确导航到目标页面。主要原因包括:
1. **页面不存在**: 某些管理页面可能还未实现
2. **路由配置问题**: 路由路径与测试用例中的路径不一致
3. **页面加载超时**: 页面加载时间过长,导致测试超时
4. **权限问题**: 某些页面需要特定权限才能访问
### 3.2 修复策略
#### 3.2.1 页面存在性验证
首先验证所有测试用例涉及的页面是否都已经实现:
-`/users` - 用户管理页面
-`/roles` - 角色管理页面
-`/menus` - 菜单管理页面
-`/sys/config` - 系统配置页面
-`/dict` - 字典管理页面
-`/files` - 文件管理页面
-`/loginlog` - 登录日志页面
-`/oplog` - 操作日志页面
-`/exceptionlog` - 异常日志页面
#### 3.2.2 Page Object类优化
为每个Page Object类添加更健壮的导航逻辑:
```typescript
async goto() {
await this.page.goto('/users');
// 等待页面加载完成
await this.page.waitForLoadState('networkidle');
// 等待关键元素出现
await this.page.waitForSelector('.el-table', { timeout: 10000 });
// 验证页面标题或URL
await expect(this.page).toHaveURL(/.*users/);
}
```
#### 3.2.3 错误处理机制
添加完善的错误处理机制:
```typescript
async goto() {
try {
await this.page.goto('/users');
await this.page.waitForLoadState('networkidle');
await this.page.waitForSelector('.el-table', { timeout: 10000 });
} catch (error) {
// 截图保存错误状态
await this.page.screenshot({ path: `test-results/error-${Date.now()}.png` });
// 记录错误信息
console.error('页面导航失败:', error);
// 抛出更详细的错误信息
throw new Error(`导航到用户管理页面失败: ${error.message}`);
}
}
```
### 3.3 任务清单
1. **验证页面存在性**0.5天)
- 检查所有测试用例涉及的页面是否已实现
- 确认路由配置是否正确
- 验证页面权限设置
2. **优化Page Object类**1天)
- 为每个Page Object类添加健壮的导航方法
- 添加错误处理机制
- 添加页面加载验证逻辑
3. **运行测试验证**0.5天)
- 运行完整测试套件
- 收集通过率数据
- 分析剩余失败原因
### 3.4 验收标准
- ✅ 测试通过率提升至50%以上(至少26个测试用例通过)
- ✅ 所有页面都能正确导航
- ✅ 页面加载错误有清晰的错误信息
---
## 4. 第二阶段:选择器精准化
**预计时间**: 2-3天
**目标**: 测试通过率提升至90%以上(至少47个测试用例通过)
### 4.1 问题分析
测试用例中使用的选择器无法找到对应的页面元素,主要原因包括:
1. **选择器过时**: 前端代码修改后,选择器未同步更新
2. **选择器不够健壮**: 使用class选择器,容易受CSS变化影响
3. **动态元素**: 某些元素是动态生成的,需要更灵活的定位方式
4. **异步加载**: 元素加载有延迟,需要添加等待逻辑
### 4.2 修复策略
#### 4.2.1 选择器诊断工具
使用Playwright的trace功能,捕获实际页面元素:
```typescript
// 在测试配置中启用trace
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
}
```
#### 4.2.2 选择器优化原则
优先使用以下选择器(按优先级排序):
1. **data-testid属性**(最推荐)
```typescript
page.getByTestId('submit-button')
```
2. **角色和文本组合**
```typescript
page.getByRole('button', { name: '确定' })
page.getByText('用户管理')
```
3. **CSS选择器**(最后选择)
```typescript
page.locator('.el-button--primary')
```
#### 4.2.3 Page Object类选择器更新
为每个Page Object类更新选择器:
```typescript
export class UserManagementPage {
readonly page: Page;
readonly table: Locator;
readonly createUserButton: Locator;
readonly searchInput: Locator;
readonly searchButton: Locator;
constructor(page: Page) {
this.page = page;
// 使用更健壮的选择器
this.table = page.locator('.el-table').first();
this.createUserButton = page.getByRole('button', { name: '新增用户' });
this.searchInput = page.getByPlaceholder('搜索用户名或邮箱');
this.searchButton = page.getByRole('button', { name: '搜索' });
}
}
```
#### 4.2.4 等待策略优化
添加智能等待逻辑:
```typescript
async waitForTableReady() {
// 等待表格出现
await this.table.waitFor({ state: 'visible', timeout: 10000 });
// 等待表格数据加载完成
await this.page.waitForFunction(
() => document.querySelectorAll('.el-table__body tr').length > 0,
{ timeout: 5000 }
);
}
```
#### 4.2.5 动态元素处理
处理动态生成的元素:
```typescript
async clickDynamicButton(buttonText: string) {
// 使用文本内容定位动态按钮
await this.page.getByRole('button', { name: buttonText }).click();
// 或者使用正则表达式匹配
await this.page.getByRole('button', { name: /确定|确认/ }).click();
}
```
### 4.3 任务清单
1. **选择器诊断**0.5天)
- 使用Playwright trace捕获实际页面元素
- 分析所有失败测试的选择器问题
- 生成选择器诊断报告
2. **批量更新选择器**(1.5天)
- 更新所有Page Object类的选择器
- 添加智能等待逻辑
- 处理动态元素
3. **运行测试验证**0.5天)
- 运行完整测试套件
- 收集通过率数据
- 分析剩余失败原因
### 4.4 验收标准
- ✅ 测试通过率提升至90%以上(至少47个测试用例通过)
- ✅ 所有选择器都能正确找到元素
- ✅ 动态元素有稳定的处理逻辑
---
## 5. 第三阶段:性能优化
**预计时间**: 1-2天
**目标**: 测试通过率达到100%,执行时间减少30%以上
### 5.1 问题分析
当前测试套件执行时间为17.2分钟,主要耗时在:
1. **全局setup/teardown**: 启动后端服务、数据库初始化等
2. **页面加载等待**: 每个测试用例都等待页面加载完成
3. **固定等待时间**: 使用`waitForTimeout`固定等待,不够智能
4. **串行执行**: 测试用例逐个执行,无法并行
### 5.2 优化策略
#### 5.2.1 全局setup优化
优化后端服务启动时间:
```typescript
// global-setup.ts
export default async function globalSetup() {
console.log('🚀 开始全局测试环境设置...');
// 使用JAR文件启动(比Maven快50%
const jarFile = path.join(backendDir, 'target/manage-app-1.0.0.jar');
// 减少健康检查间隔(从1秒改为0.5秒)
const healthCheckInterval = 500;
// 减少最大等待时间(从60秒改为30秒)
const maxWaitTime = 30;
// 并行启动多个服务(如果需要)
await Promise.all([
startBackendService(),
startFrontendService(),
]);
}
```
#### 5.2.2 页面加载等待优化
使用更智能的等待策略:
```typescript
// 优化前
await page.waitForTimeout(2000);
// 优化后:等待特定条件
await page.waitForLoadState('domcontentloaded'); // 只等待DOM加载
await page.waitForSelector('.el-table', { state: 'visible' }); // 等待关键元素
```
#### 5.2.3 测试用例并行执行
在确保测试独立性的前提下,启用并行执行:
```typescript
// playwright.config.ts
export default defineConfig({
// 项目级并行(不同项目并行执行)
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
],
// 文件级并行(同一项目内,不同文件并行执行)
workers: process.env.CI ? 1 : 4, // CI环境串行,本地并行
// 完全并行(需要确保测试完全独立)
fullyParallel: false, // 暂不启用,避免localStorage冲突
});
```
#### 5.2.4 测试数据缓存
缓存测试数据,避免重复创建:
```typescript
// 使用全局状态存储测试数据
let testUserId: string | null = null;
test.beforeAll(async ({ request }) => {
if (!testUserId) {
// 只创建一次测试用户
const response = await request.post('/api/users', {
data: { username: 'testuser', password: 'Test@123' }
});
testUserId = (await response.json()).id;
}
});
test.afterAll(async ({ request }) => {
if (testUserId) {
// 清理测试数据
await request.delete(`/api/users/${testUserId}`);
testUserId = null;
}
});
```
#### 5.2.5 智能重试机制
为不稳定的测试用例添加智能重试:
```typescript
// playwright.config.ts
export default defineConfig({
// 失败后重试2次
retries: process.env.CI ? 2 : 1,
// 只重试失败的测试用例
retryOnlyFailed: true,
});
```
#### 5.2.6 测试报告优化
生成更详细的测试报告:
```typescript
// 自定义报告器
export default class CustomReporter {
onTestEnd(test: TestCase, result: TestResult) {
const duration = result.duration;
const status = result.status;
// 记录慢测试
if (duration > 10000) {
console.log(`⚠️ 慢测试: ${test.title} (${duration}ms)`);
}
// 记录失败测试的详细信息
if (status === 'failed') {
console.log(`❌ 失败: ${test.title}`);
console.log(` 错误: ${result.error?.message}`);
}
}
}
```
### 5.3 任务清单
1. **优化全局setup/teardown**0.5天)
- 使用JAR文件启动后端服务
- 减少健康检查等待时间
- 并行启动多个服务
2. **优化页面加载等待**0.5天)
- 移除固定等待时间
- 使用智能等待策略
- 优化关键元素等待逻辑
3. **生成最终报告**0.5天)
- 运行完整测试套件
- 生成详细的测试报告
- 分析性能指标
### 5.4 验收标准
- ✅ 测试通过率达到100%(所有52个测试用例通过)
- ✅ 测试执行时间减少30%以上(从17.2分钟降至12分钟以内)
- ✅ 生成完整的测试报告和性能分析
---
## 6. 总体验收标准
### 6.1 功能验收
- ✅ 所有52个测试用例100%通过
- ✅ 测试覆盖所有核心业务流程
- ✅ 测试报告清晰展示测试结果
### 6.2 性能验收
- ✅ 测试执行时间在12分钟以内
- ✅ 全局setup时间在30秒以内
- ✅ 单个测试用例平均执行时间在20秒以内
### 6.3 质量验收
- ✅ 所有Page Object类有完善的错误处理
- ✅ 所有选择器使用最佳实践
- ✅ 测试代码有清晰的注释和文档
---
## 7. 风险与应对
### 7.1 页面未实现风险
**风险**: 某些测试页面可能还未实现
**应对**:
- 优先检查页面存在性
- 如果页面未实现,暂时跳过相关测试用例
- 记录未实现页面的测试用例,后续补充
### 7.2 选择器不稳定风险
**风险**: 某些选择器可能不稳定,导致测试时好时坏
**应对**:
- 使用多个备选选择器
- 添加重试机制
- 使用更健壮的等待策略
### 7.3 测试数据冲突风险
**风险**: 多个测试用例共享测试数据,可能导致冲突
**应对**:
- 每个测试用例使用唯一的测试数据(如时间戳)
- 测试完成后清理测试数据
- 使用独立的测试数据库
### 7.4 执行时间过长风险
**风险**: 即使优化后,执行时间可能仍然较长
**应对**:
- 进一步优化等待策略
- 考虑并行执行更多测试用例
- 减少不必要的测试步骤
---
## 8. 后续优化建议
### 8.1 短期优化(1-2周)
1. **添加更多测试用例**: 覆盖更多边界场景
2. **优化测试数据管理**: 使用测试数据工厂模式
3. **集成到CI/CD**: 配置Woodpecker CI自动运行E2E测试
### 8.2 中期优化(2-4周)
1. **添加可视化测试**: 使用Percy或Applitools进行视觉回归测试
2. **性能监控**: 集成Lighthouse进行性能监控
3. **测试报告优化**: 生成更详细的HTML报告
### 8.3 长期优化(1-2个月)
1. **测试框架升级**: 考虑使用更先进的测试框架
2. **AI辅助测试**: 使用AI工具自动生成测试用例
3. **持续优化**: 定期审查测试用例,优化测试执行速度
---
## 9. 参考资料
- [Playwright官方文档](https://playwright.dev/)
- [Playwright最佳实践](https://playwright.dev/docs/best-practices)
- [Vue 3测试指南](https://vuejs.org/guide/scaling-up/testing.html)
- [E2E测试最佳实践](https://testingjavascript.com/)
---
**文档结束**