Files
gym-manage/docs/superpowers/specs/2026-04-08-user-journey-test-improvement-design.md
T

405 lines
9.6 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.
# User Journey 测试改进设计文档
**文档日期**: 2026-04-08
**负责人**: 张翔
**版本**: 1.0
**状态**: 已验证
---
## 执行摘要
通过快速验证测试,我们确认了 **Playwright 本身是有效的**,问题在于测试方式。改进后的测试方法成功发现了真实问题,证明了方案的可行性。
**核心发现**
- ✅ Playwright 工具本身有效
- ❌ 旧测试方式存在假阳性问题
- ✅ 新测试方式能真实发现问题
- ✅ 三层验证策略可行
---
## 1. 问题分析
### 1.1 当前问题
**用户报告**
- 测试通过了,但实际运行时页面没有内容
- Console 有 Mock API 日志,但页面无内容
**根本原因**
```typescript
// ❌ 错误的测试方式
const dataStats = page.locator('[data-testid="data-stats"]')
if (await dataStats.isVisible()) { // 如果不可见,跳过验证!
const statsText = await dataStats.textContent()
expect(statsText).toBeTruthy() // 这行永远不会执行
}
// 测试通过!但实际上什么都没验证
```
**问题本质**
- 软验证:元素不存在就跳过验证
- 假阳性:测试通过但实际无效
- 缺乏强制验证:没有确保元素必须存在
---
### 1.2 验证测试结果
**测试文件**: `tests/e2e/specs/validation/test-improvement-validation.spec.ts`
**测试结果**
| 测试类型 | 结果 | 说明 |
|---------|------|------|
| ❌ 旧方式:软验证 | ✅ 通过 | **假阳性!** 元素不存在但测试通过 |
| ✅ 新方式:硬验证 | ❌ 失败 | **正确!** 元素不存在,测试失败 |
| ✅ 三层验证 | ❌ 失败 | API请求超时,暴露真实问题 |
| ✅ 完整用户旅程 | ❌ 失败 | 案件列表元素不存在(count = 0) |
| ✅ 诊断测试 | ✅ 通过 | 提供详细诊断信息 |
**关键发现**
- 页面上没有 `.ant-list-item` 元素(count = 0
- API请求超时(没有调用 `/api/cases`
- 页面根本没有加载案件数据
---
## 2. 解决方案
### 2.1 核心原则转变
#### ❌ 旧方式(软验证)
```typescript
// 软验证:元素不存在就跳过
if (await element.isVisible()) {
expect(await element.textContent()).toBeTruthy()
}
```
#### ✅ 新方式(硬验证)
```typescript
// 硬验证:元素必须存在且可见
await expect(element).toBeVisible()
const text = await element.textContent()
expect(text).toBeTruthy()
expect(text.length).toBeGreaterThan(0)
```
---
### 2.2 三层验证策略
```typescript
test('真实验证用户看到的内容', async ({ page }) => {
// Layer 1: API层验证
const response = await page.waitForResponse('**/api/cases')
expect(response.status()).toBe(200)
const data = await response.json()
expect(data.length).toBeGreaterThan(0)
// Layer 2: 状态层验证
const state = await page.evaluate(() => {
return {
cases: window.__CASE_STORE__?.getState().cases,
currentCase: window.__CASE_STORE__?.getState().currentCase
}
})
expect(state.cases.length).toBeGreaterThan(0)
// Layer 3: DOM层验证
const caseItems = page.locator('.ant-list-item')
await expect(caseItems.first()).toBeVisible({ timeout: 5000 })
const count = await caseItems.count()
expect(count).toBeGreaterThan(0)
// Layer 4: 内容验证
const firstCaseText = await caseItems.first().textContent()
expect(firstCaseText).toBeTruthy()
expect(firstCaseText.length).toBeGreaterThan(10)
})
```
---
### 2.3 增强的测试工具
#### 1. 状态验证器
```typescript
// tests/e2e/utils/state-validator.ts
export async function validatePageState(page: Page, expectedState: {
hasCase?: boolean
hasData?: boolean
activePage?: string
}) {
const state = await page.evaluate(() => ({
currentCase: window.__CASE_STORE__?.getState().currentCase,
transactions: window.__DATA_STORE__?.getState().transactions,
activePage: window.__PAGE_STORE__?.getState().activePageKey
}))
if (expectedState.hasCase) {
expect(state.currentCase).toBeTruthy()
}
if (expectedState.hasData) {
expect(state.transactions.length).toBeGreaterThan(0)
}
if (expectedState.activePage) {
expect(state.activePage).toBe(expectedState.activePage)
}
}
```
#### 2. 内容验证器
```typescript
// tests/e2e/utils/content-validator.ts
export async function validateContent(
page: Page,
selector: string,
options: {
mustBeVisible?: boolean
mustHaveText?: boolean
minLength?: number
exactText?: string
} = {}
) {
const element = page.locator(selector)
// 默认必须可见
if (options.mustBeVisible !== false) {
await expect(element).toBeVisible({ timeout: 5000 })
}
if (options.mustHaveText) {
const text = await element.textContent()
expect(text).toBeTruthy()
if (options.minLength) {
expect(text.length).toBeGreaterThanOrEqual(options.minLength)
}
if (options.exactText) {
expect(text.trim()).toBe(options.exactText)
}
}
}
```
#### 3. 截图验证器
```typescript
// tests/e2e/utils/screenshot-validator.ts
export async function takeScreenshotAndValidate(
page: Page,
testName: string,
step: string
) {
const screenshot = await page.screenshot({
fullPage: true,
path: `test-results/screenshots/${testName}-${step}.png`
})
// 验证截图不为空
expect(screenshot.length).toBeGreaterThan(1000)
console.log(`📸 Screenshot saved: ${testName}-${step}.png`)
}
```
---
## 3. 实施计划
### 3.1 短期(1周内)
**目标**: 修复现有测试用例
**任务清单**:
- [ ] 将所有软验证改为硬验证
- [ ] 添加三层验证策略
- [ ] 创建测试工具函数
- [ ] 修复发现的问题
**预计工作量**: 2-3 天
---
### 3.2 中期(2-4周)
**目标**: 建立完整的测试体系
**任务清单**:
- [ ] 添加视觉验证(截图对比)
- [ ] 建立测试报告机制
- [ ] 集成到CI/CD
- [ ] 建立测试数据管理
**预计工作量**: 5-7 天
---
### 3.3 长期(1-3个月)
**目标**: 持续优化和扩展
**任务清单**:
- [ ] 评估是否需要引入Storybook
- [ ] 考虑AI辅助测试
- [ ] 建立性能测试
- [ ] 建立安全测试
**预计工作量**: 10-15 天
---
## 4. 技术选型
### 4.1 核心工具
**Playwright****已验证有效**
- 优势:
- 强大的选择器和断言
- 支持API拦截和验证
- 内置截图和视频录制
- 跨浏览器支持
- 活跃的社区和文档
- 劣势:
- 需要正确的使用方式
- 学习曲线适中
**结论**: 继续使用Playwright,改进测试方式
---
### 4.2 辅助工具
| 工具 | 用途 | 优先级 |
|------|------|--------|
| Playwright Screenshot | 视觉验证 | P0 |
| Playwright Trace | 调试支持 | P0 |
| Playwright API Mocking | 数据模拟 | P1 |
| Percy / Chromatic | 视觉回归 | P2 |
| Storybook | 组件测试 | P3 |
---
## 5. 质量保障
### 5.1 测试原则
1. **硬验证优先**: 元素必须存在,否则测试失败
2. **多层验证**: API → 状态 → DOM → 内容
3. **快速失败**: 发现问题立即失败,不继续执行
4. **清晰诊断**: 提供详细的诊断信息
---
### 5.2 测试覆盖率目标
| 层级 | 当前覆盖率 | 目标覆盖率 |
|------|-----------|-----------|
| API层 | 0% | 100% |
| 状态层 | 0% | 100% |
| DOM层 | 50% | 100% |
| 内容层 | 30% | 100% |
| **总体** | **30%** | **100%** |
---
## 6. 风险评估
### 6.1 技术风险
| 风险 | 影响 | 概率 | 缓解措施 |
|------|------|------|----------|
| 测试用例维护成本高 | 中 | 中 | 建立测试工具库,提高可维护性 |
| 测试执行时间长 | 低 | 低 | 使用并行执行,优化测试用例 |
| 误报率高 | 高 | 低 | 使用硬验证,减少假阳性 |
---
### 6.2 业务风险
| 风险 | 影响 | 概率 | 缓解措施 |
|------|------|------|----------|
| 测试不通过影响交付 | 高 | 中 | 优先修复关键问题,建立分级测试 |
| 测试数据管理复杂 | 中 | 中 | 建立测试数据工厂,使用Mock数据 |
---
## 7. 成功标准
### 7.1 短期目标(1周内)
- ✅ 所有测试用例使用硬验证
- ✅ 测试覆盖率提升到 60%
- ✅ 无假阳性问题
- ✅ 发现并修复当前问题
---
### 7.2 中期目标(2-4周)
- ✅ 测试覆盖率提升到 80%
- ✅ 建立完整的测试报告
- ✅ 集成到CI/CD
- ✅ 测试执行时间 < 10分钟
---
### 7.3 长期目标(1-3个月)
- ✅ 测试覆盖率提升到 100%
- ✅ 建立视觉回归测试
- ✅ 建立性能测试
- ✅ 测试执行时间 < 5分钟
---
## 8. 附录
### 8.1 验证测试文件
**文件**: `tests/e2e/specs/validation/test-improvement-validation.spec.ts`
**测试结果**:
- ❌ 旧方式:软验证 - ✅ 通过(假阳性)
- ✅ 新方式:硬验证 - ❌ 失败(正确)
- ✅ 三层验证 - ❌ 失败(正确)
- ✅ 完整用户旅程 - ❌ 失败(正确)
- ✅ 诊断测试 - ✅ 通过
---
### 8.2 参考资料
- [Playwright 官方文档](https://playwright.dev/)
- [Playwright 最佳实践](https://playwright.dev/docs/best-practices)
- [测试驱动开发(TDD](https://en.wikipedia.org/wiki/Test-driven_development)
---
## 9. 总结
### 9.1 核心结论
1.**Playwright 工具本身有效**
2.**问题在于测试方式(软验证 vs 硬验证)**
3.**改进后的测试能真实发现问题**
4.**三层验证策略可行**
---
### 9.2 下一步行动
1. **立即行动**: 修复现有测试用例,使用硬验证
2. **短期计划**: 建立测试工具库,提高可维护性
3. **中期计划**: 集成到CI/CD,建立完整测试体系
4. **长期计划**: 持续优化,建立视觉回归测试
---
**文档状态**: ✅ 已验证
**下一步**: 用户审查书面规格