|
|
@@ -0,0 +1,393 @@
|
|
|
+# Story 8.9: 区域管理稳定性验证
|
|
|
+
|
|
|
+Status: ready-for-dev
|
|
|
+
|
|
|
+<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
|
|
|
+
|
|
|
+## Story
|
|
|
+
|
|
|
+作为测试开发者,
|
|
|
+我想要验证区域管理测试的稳定性,
|
|
|
+以便确保测试可以可靠地使用。
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+
|
|
|
+**Given** 所有问题已修复(包括工具扩展和测试代码修复)
|
|
|
+**When** 连续运行区域管理相关测试 10 次
|
|
|
+**Then** 所有测试 100% 通过
|
|
|
+**And** 无 flaky 失败
|
|
|
+**And** 平均执行时间符合预期
|
|
|
+
|
|
|
+**测试场景:**
|
|
|
+- 运行 `pnpm test:e2e:chromium region-*.spec.ts` 10 次
|
|
|
+- 记录每次运行的通过率
|
|
|
+- 计算稳定性指标
|
|
|
+
|
|
|
+**成功标准:**
|
|
|
+- 10/10 次通过 = 100% 稳定性 ✅ Epic B 完成
|
|
|
+- 9/10 次通过 = 90% 稳定性,需要分析失败原因 ⚠️
|
|
|
+- < 9/10 次通过 = 稳定性不足,需要修复 ❌
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+
|
|
|
+- [ ] 准备稳定性测试环境
|
|
|
+ - [ ] 确认测试数据清理策略正常工作
|
|
|
+ - [ ] 确认测试隔离性(无测试间依赖)
|
|
|
+ - [ ] 准备测试运行脚本
|
|
|
+- [ ] 执行 10 次连续测试运行
|
|
|
+ - [ ] 运行 `pnpm test:e2e:chromium region-*.spec.ts`
|
|
|
+ - [ ] 记录每次运行的通过/失败/跳过数量
|
|
|
+ - [ ] 记录每次运行的执行时间
|
|
|
+ - [ ] 收集失败测试的错误信息
|
|
|
+- [ ] 分析测试结果
|
|
|
+ - [ ] 计算总体通过率
|
|
|
+ - [ ] 识别 flaky 测试(时通过时失败)
|
|
|
+ - [ ] 分析失败模式
|
|
|
+- [ ] 处理不稳定的测试
|
|
|
+ - [ ] 如果通过率 < 100%,分析失败原因
|
|
|
+ - [ ] 修复测试代码或等待策略问题
|
|
|
+ - [ ] 重新验证修复后的稳定性
|
|
|
+- [ ] 生成稳定性报告
|
|
|
+ - [ ] 记录最终通过率
|
|
|
+ - [ ] 记录平均执行时间
|
|
|
+ - [ ] 记录修复的问题(如有)
|
|
|
+ - [ ] 更新 Epic 8 状态
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### Epic 8 背景和上下文
|
|
|
+
|
|
|
+**Epic 8: 区域管理 E2E 测试 (Epic B - 业务测试 Epic)**
|
|
|
+
|
|
|
+这是 Epic B(区域管理业务测试)的最后一个 Story。前置 Story 已完成:
|
|
|
+- Story 8.1: ✅ 已完成 - RegionManagementPage Page Object
|
|
|
+- Story 8.2: ✅ 已完成 - 区域列表查看测试 (12/13 passed)
|
|
|
+- Story 8.3: ✅ 已完成 - 添加区域测试 (15/15 passed)
|
|
|
+- Story 8.4: ✅ 已完成 - 编辑区域测试 (10 passed, 2 skipped)
|
|
|
+- Story 8.5: ✅ 已完成 - 删除区域测试 (15/15 passed)
|
|
|
+- Story 8.6: ✅ 已完成 - 级联选择测试 (10 passed, 2 skipped)
|
|
|
+- Story 8.7: ✅ 已完成 - 运行测试并收集问题(代码审查完成)
|
|
|
+- Story 8.8: ⏭️ 跳过 - 不需要扩展工具包
|
|
|
+
|
|
|
+**依赖:**
|
|
|
+- Epic 1: ✅ 已完成(Select 工具基础框架)
|
|
|
+- Epic 2: ✅ 已完成(Select 工具在真实 E2E 测试中验证)
|
|
|
+
|
|
|
+### Story 8.7 关键修复回顾
|
|
|
+
|
|
|
+**Story 8.7 发现并修复的问题:**
|
|
|
+
|
|
|
+#### HIGH-1 ✅ 已修复: 新建区域后树形 UI 不刷新
|
|
|
+- **问题**: 树形组件使用懒加载机制,新创建的节点不会自动刷新到树中
|
|
|
+- **修复**: 添加了 `refreshTree()` 方法,通过 `page.reload()` 强制刷新树数据
|
|
|
+- **影响文件**:
|
|
|
+ - `region-management.page.ts` - 添加 refreshTree() 方法
|
|
|
+ - `region-add.spec.ts` - 添加 16 处 refreshTree() 调用
|
|
|
+ - `region-edit.spec.ts`, `region-cascade.spec.ts`, `region-delete.spec.ts`
|
|
|
+
|
|
|
+#### HIGH-2 ✅ 已修复: expandNode strict mode violation
|
|
|
+- **问题**: 展开包含 100+ 子节点的市级节点时,strict mode 找到多个匹配元素
|
|
|
+- **修复**: 优化了 `expandNode()` 方法,添加元素数量检查和早期错误抛出
|
|
|
+- **同时优化**: `regionExists()` 方法使用 `waitFor({ state: 'attached' })`
|
|
|
+
|
|
|
+#### MEDIUM-1 ✅ 已修复: 测试刷新策略不统一
|
|
|
+- **问题**: 部分测试使用 `page.goto('/admin/areas')`,部分使用 `refreshTree()`
|
|
|
+- **修复**: 统一所有区域测试文件使用 `refreshTree()` 方法
|
|
|
+
|
|
|
+**不需要扩展工具包:**
|
|
|
+- Story 8.7 评估确认不需要扩展 e2e-test-utils
|
|
|
+- 所有问题都可以通过修改测试代码解决
|
|
|
+- 现有工具(selectRadixOption, selectRadixOptionAsync, uploadFileToField)已满足需求
|
|
|
+
|
|
|
+### 稳定性测试策略
|
|
|
+
|
|
|
+**测试文件清单:**
|
|
|
+
|
|
|
+| 测试文件 | 描述 | 代码审查状态 |
|
|
|
+|---------|------|-------------|
|
|
|
+| `region-list.spec.ts` | 区域列表查看测试 | ✅ 已完成 |
|
|
|
+| `region-add.spec.ts` | 添加区域测试 (15 tests) | ✅ 已修复 (refreshTree) |
|
|
|
+| `region-edit.spec.ts` | 编辑区域测试 (12 tests) | ✅ 已修复 (refreshTree) |
|
|
|
+| `region-delete.spec.ts` | 删除区域测试 (15 tests) | ✅ 已修复 (refreshTree) |
|
|
|
+| `region-cascade.spec.ts` | 级联选择测试 (12 tests) | ✅ 已修复 (refreshTree) |
|
|
|
+
|
|
|
+**预期测试总数**: 约 66 个测试
|
|
|
+
|
|
|
+### 测试运行命令
|
|
|
+
|
|
|
+**单次运行命令:**
|
|
|
+```bash
|
|
|
+cd web
|
|
|
+pnpm test:e2e:chromium region-*.spec.ts
|
|
|
+```
|
|
|
+
|
|
|
+**快速失败模式(调试用):**
|
|
|
+```bash
|
|
|
+timeout 300 pnpm test:e2e:chromium region-*.spec.ts
|
|
|
+```
|
|
|
+
|
|
|
+**稳定性测试脚本:**
|
|
|
+
|
|
|
+建议创建以下 shell 脚本自动运行 10 次:
|
|
|
+
|
|
|
+```bash
|
|
|
+#!/bin/bash
|
|
|
+# run-stability-test.sh
|
|
|
+
|
|
|
+PASSED=0
|
|
|
+FAILED=0
|
|
|
+TIMES=()
|
|
|
+
|
|
|
+echo "=== 区域管理 E2E 测试稳定性验证 ==="
|
|
|
+echo "开始时间: $(date)"
|
|
|
+echo ""
|
|
|
+
|
|
|
+for i in {1..10}; do
|
|
|
+ echo "=== 运行 #$i ==="
|
|
|
+ START=$(date +%s)
|
|
|
+
|
|
|
+ cd web && pnpm test:e2e:chromium region-*.spec.ts 2>&1 | tee "../test-results/stability-run-$i.log"
|
|
|
+ RESULT=$?
|
|
|
+
|
|
|
+ END=$(date +%s)
|
|
|
+ DURATION=$((END - START))
|
|
|
+ TIMES+=($DURATION)
|
|
|
+
|
|
|
+ if [ $RESULT -eq 0 ]; then
|
|
|
+ PASSED=$((PASSED + 1))
|
|
|
+ echo "✅ 运行 #$i 通过 (耗时: ${DURATION}s)"
|
|
|
+ else
|
|
|
+ FAILED=$((FAILED + 1))
|
|
|
+ echo "❌ 运行 #$i 失败 (耗时: ${DURATION}s)"
|
|
|
+ fi
|
|
|
+ echo ""
|
|
|
+done
|
|
|
+
|
|
|
+echo "=== 稳定性测试结果 ==="
|
|
|
+echo "通过: $PASSED/10"
|
|
|
+echo "失败: $FAILED/10"
|
|
|
+
|
|
|
+if [ $PASSED -gt 0 ]; then
|
|
|
+ AVG_TIME=$(awk '{sum+=$1} END {print sum/NR}' <<< "${TIMES[@]}")
|
|
|
+ echo "平均时间: ${AVG_TIME}s"
|
|
|
+fi
|
|
|
+
|
|
|
+if [ $PASSED -eq 10 ]; then
|
|
|
+ echo "✅ 100% 稳定性通过!Epic B 完成!"
|
|
|
+ exit 0
|
|
|
+else
|
|
|
+ echo "❌ 稳定性不足,需要分析失败原因"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+```
|
|
|
+
|
|
|
+### 稳定性评估标准
|
|
|
+
|
|
|
+**通过率计算:**
|
|
|
+- 10/10 = 100% ✅ Epic B 完成
|
|
|
+- 9/10 = 90% ⚠️ 需要分析
|
|
|
+- < 9/10 ❌ 需要修复
|
|
|
+
|
|
|
+**Flaky 测试识别:**
|
|
|
+- 如果某个测试在不同运行中时而通过时而失败,标记为 flaky
|
|
|
+- 常见原因: 竞态条件、网络延迟、时序问题、数据清理不完整
|
|
|
+
|
|
|
+**执行时间基准:**
|
|
|
+- 基于 Story 8.7 的数据:单次运行约 240 秒(4 分钟)
|
|
|
+- 稳定性测试预期总时间: 约 40 分钟
|
|
|
+- 如果单次运行超过 5 分钟,分析是否有性能退化
|
|
|
+
|
|
|
+### 已知问题和技术债务
|
|
|
+
|
|
|
+**剩余跳过的测试(region-edit.spec.ts, region-cascade.spec.ts):**
|
|
|
+
|
|
|
+1. **编辑子区域测试** (2 个 skipped)
|
|
|
+ - `应该成功编辑市级区域名称` - 需要修复 createChildRegion 功能
|
|
|
+ - `应该成功编辑区级区域状态` - 需要修复 createChildRegion 功能
|
|
|
+
|
|
|
+2. **级联选择测试** (2 个 skipped)
|
|
|
+ - `编辑区域后应保持父级关系` - 因树缓存问题跳过
|
|
|
+ - `编辑区域后子区域应跟随` - 因树缓存问题跳过
|
|
|
+
|
|
|
+**说明**: 这些测试被跳过是已知问题,不影响稳定性测试。稳定性测试关注的是:
|
|
|
+- 已实现的测试是否能稳定通过
|
|
|
+- 没有 flaky 失败
|
|
|
+- 执行时间一致
|
|
|
+
|
|
|
+### 测试数据隔离策略
|
|
|
+
|
|
|
+**当前策略:**
|
|
|
+- 每个测试使用 `generateUniqueRegionName()` 生成唯一名称
|
|
|
+- 使用时间戳 + 随机数确保唯一性
|
|
|
+- `afterEach` 钩子尝试删除创建的测试数据
|
|
|
+
|
|
|
+**潜在问题 (LOW-1 from Story 8.7):**
|
|
|
+- 测试数据清理总是显示 "成功 0, 失败 0"
|
|
|
+- 可能导致测试数据在数据库中累积
|
|
|
+
|
|
|
+**稳定性验证要点:**
|
|
|
+- 确认测试数据不累积影响后续运行
|
|
|
+- 确认测试可以独立运行(无测试间依赖)
|
|
|
+- 如果发现问题,需要在稳定性测试前修复
|
|
|
+
|
|
|
+### RegionManagementPage 关键方法
|
|
|
+
|
|
|
+**稳定性测试相关的关键方法:**
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 树形操作 - 所有测试都会使用
|
|
|
+await regionManagementPage.waitForTreeLoaded();
|
|
|
+await regionManagementPage.refreshTree(); // ⚠️ 关键修复
|
|
|
+await regionManagementPage.expandNode(name);
|
|
|
+await regionManagementPage.regionExists(name);
|
|
|
+
|
|
|
+// CRUD 操作
|
|
|
+await regionManagementPage.createProvince({ name, code, level });
|
|
|
+await regionManagementPage.createChildRegion(parent, type, { name, code, level });
|
|
|
+await regionManagementPage.editRegion(name, { newName });
|
|
|
+await regionManagementPage.deleteRegion(name);
|
|
|
+
|
|
|
+// 表单操作
|
|
|
+await regionManagementPage.openCreateProvinceDialog();
|
|
|
+await regionManagementPage.fillRegionForm({ name, code, level });
|
|
|
+await regionManagementPage.submitForm();
|
|
|
+await regionManagementPage.waitForDialogClosed();
|
|
|
+```
|
|
|
+
|
|
|
+### 失败分析检查清单
|
|
|
+
|
|
|
+当测试失败时,按以下顺序分析:
|
|
|
+
|
|
|
+1. **查看错误上下文**
|
|
|
+ ```bash
|
|
|
+ cat test-results/*/error-context.md
|
|
|
+ ```
|
|
|
+
|
|
|
+2. **检查日志输出**
|
|
|
+ - 查找 console.debug 输出
|
|
|
+ - 查找 API 响应数据
|
|
|
+
|
|
|
+3. **识别失败模式**
|
|
|
+ - 是否总是同一个测试失败?
|
|
|
+ - 是否随机失败(flaky)?
|
|
|
+ - 是否与执行顺序有关?
|
|
|
+
|
|
|
+4. **常见问题诊断**
|
|
|
+ - 树加载超时 → 增加 waitForTreeLoaded() 超时
|
|
|
+ - 选择器找不到 → 检查 DOM 结构变化
|
|
|
+ - 数据冲突 → 检查测试数据清理
|
|
|
+ - 网络问题 → 重试运行
|
|
|
+
|
|
|
+### 成功标准
|
|
|
+
|
|
|
+**Epic 8 完成条件:**
|
|
|
+- [ ] 10 次连续运行 100% 通过
|
|
|
+- [ ] 无 flaky 测试
|
|
|
+- [ ] 平均执行时间 < 5 分钟/次
|
|
|
+- [ ] 生成稳定性报告
|
|
|
+- [ ] Epic 8 状态更新为 "done"
|
|
|
+
|
|
|
+**如果稳定性测试失败:**
|
|
|
+1. 分析失败原因
|
|
|
+2. 修复测试代码或等待策略
|
|
|
+3. 重新运行稳定性测试
|
|
|
+4. 重复直到 100% 通过
|
|
|
+
|
|
|
+### 与后续 Epic 的关系
|
|
|
+
|
|
|
+**Epic 8 完成后:**
|
|
|
+- Epic B(区域管理 E2E 测试)✅ 完成
|
|
|
+- 可以进入 Epic C(订单管理 E2E 测试)
|
|
|
+- Epic C 已在进行中,可以参考 Epic 8 的经验
|
|
|
+
|
|
|
+**经验传递:**
|
|
|
+- Story 8.7 的问题修复模式可用于其他 Epic
|
|
|
+- refreshTree() 模式可能对其他树形 UI 有用
|
|
|
+- 测试数据隔离策略需要在 Epic C 中保持
|
|
|
+
|
|
|
+## Project Structure Notes
|
|
|
+
|
|
|
+### 对齐统一项目结构
|
|
|
+
|
|
|
+**测试文件位置:**
|
|
|
+```
|
|
|
+web/tests/e2e/specs/admin/
|
|
|
+├── region-list.spec.ts # Story 8.2 - 13 tests
|
|
|
+├── region-add.spec.ts # Story 8.3 - 15 tests
|
|
|
+├── region-edit.spec.ts # Story 8.4 - 12 tests
|
|
|
+├── region-delete.spec.ts # Story 8.5 - 15 tests
|
|
|
+└── region-cascade.spec.ts # Story 8.6 - 12 tests
|
|
|
+```
|
|
|
+
|
|
|
+**Page Object 位置:**
|
|
|
+```
|
|
|
+web/tests/e2e/pages/admin/
|
|
|
+└── region-management.page.ts # Story 8.1
|
|
|
+```
|
|
|
+
|
|
|
+**Story 文档位置:**
|
|
|
+```
|
|
|
+_bmad-output/implementation-artifacts/
|
|
|
+├── 8-1-region-page-object.md
|
|
|
+├── 8-2-region-list-test.md
|
|
|
+├── 8-3-add-region-test.md
|
|
|
+├── 8-4-edit-region-test.md
|
|
|
+├── 8-5-delete-region-test.md
|
|
|
+├── 8-6-cascade-select-test.md
|
|
|
+├── 8-7-run-tests-collect-issues.md
|
|
|
+└── 8-9-region-stability-test.md # 本 Story
|
|
|
+```
|
|
|
+
|
|
|
+## References
|
|
|
+
|
|
|
+**源文档和规范:**
|
|
|
+- [Source: `_bmad-output/planning-artifacts/epics.md`](Epic 8 - 区域管理 E2E 测试)
|
|
|
+- [Source: `_bmad-output/planning-artifacts/architecture.md`](测试架构和标准)
|
|
|
+- [Source: `_bmad-output/project-context.md`](项目上下文和规则)
|
|
|
+
|
|
|
+**前置 Story 参考:**
|
|
|
+- [Source: `_bmad-output/implementation-artifacts/8-1-region-page-object.md`](RegionManagementPage 实现)
|
|
|
+- [Source: `_bmad-output/implementation-artifacts/8-7-run-tests-collect-issues.md`](问题收集和修复 - 关键修复)
|
|
|
+
|
|
|
+**代码参考:**
|
|
|
+- [Source: `web/tests/e2e/pages/admin/region-management.page.ts`](Page Object 实现 - refreshTree() 方法)
|
|
|
+- [Source: `web/tests/e2e/specs/admin/region-*.spec.ts`](所有区域管理测试文件)
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+
|
|
|
+Claude Opus 4 (claude-opus-4-5-20251101)
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+
|
|
|
+无调试问题 - Story 文档创建阶段
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+
|
|
|
+1. **Story 文档结构创建完成**
|
|
|
+ - 包含完整的用户故事描述
|
|
|
+ - 包含详细的验收标准
|
|
|
+ - 包含任务和子任务分解
|
|
|
+
|
|
|
+2. **Dev Notes 章节完成**
|
|
|
+ - Epic 8 背景和上下文
|
|
|
+ - Story 8.7 关键修复回顾(HIGH-1, HIGH-2, MEDIUM-1)
|
|
|
+ - 稳定性测试策略和评估标准
|
|
|
+ - 测试运行命令和脚本模板
|
|
|
+ - 已知问题和技术债务说明
|
|
|
+ - 失败分析检查清单
|
|
|
+
|
|
|
+3. **Previous Story Intelligence 完成**
|
|
|
+ - 记录了所有前置 Story 的状态
|
|
|
+ - 记录了关键修复和经验
|
|
|
+ - 提供了与后续 Epic 的关系说明
|
|
|
+
|
|
|
+### File List
|
|
|
+
|
|
|
+**Story 文档:**
|
|
|
+- `_bmad-output/implementation-artifacts/8-9-region-stability-test.md` (本文件)
|
|
|
+
|
|
|
+**相关代码文件:**
|
|
|
+- `web/tests/e2e/pages/admin/region-management.page.ts`
|
|
|
+- `web/tests/e2e/specs/admin/region-*.spec.ts` (5 个测试文件)
|