# Epic 2 Retrospective: 在现有 E2E 测试中验证 Select 工具 **会议日期:** 2026-01-10 **Epic 状态:** ✅ Done **参与人员:** Root (Project Lead), Bob (Scrum Master), Alice (Product Owner), Charlie (Senior Dev), Dana (QA Engineer), Elena (Junior Dev) ## 会议概览 **Epic 2 目标:** 在 `web/tests/e2e/` 的现有残疾人管理测试中使用 Select 工具,验证工具在真实场景中的可用性和稳定性。 **交付成果:** - 完成故事: 5/5 (100%) - Story 2.6 稳定性验证已跳过 - Select 工具验证: ✅ 通过(静态 + 异步场景) - 关键 Bug 修复: ✅ listbox → option DOM 结构问题 **会议目的:** 1. 学习 Epic 2 的执行经验 2. 评估 Epic 1 回顾行动项的跟进情况 3. 为 Epic 3(扩展工具集)做准备 ## 成功经验 ✅ ### 1. "先验证再扩展" 策略得到验证 Epic 1 回顾中的关键决策在 Epic 2 中得到了验证: **原 Epic 规划顺序:** - Epic 1: Select 工具(已完成) - ~~Epic 2: 扩展工具集~~ - Epic 3: 验证 **修正后的顺序:** - Epic 1: Select 工具(已完成) - **Epic 2: 验证 Select 工具** ← 当前 Epic - Epic 3: 扩展工具集 - Epic 4: 全面验证 **Alice (Product Owner):** "这个决策非常正确。如果我们先扩展更多工具,Select 工具的问题会在 Epic 3/4 中才暴露,那时修复成本会高得多。" **验证结果:** | Story | 验证内容 | 结果 | 发现问题 | |-------|---------|------|---------| | 2.1 | 工具包安装和类型安全 | ✅ 通过 | 无 | | 2.2 | 静态 Select 迁移(5 处) | ✅ 通过 | 无 | | 2.3 | 异步 Select 迁移(省份/城市) | ✅ 通过 | 移除了 waitForTimeout hack | | 2.4 | 运行测试并收集问题 | ⚠️ 发现 | DOM 结构假设错误 | | 2.5 | 验证修复效果 | ✅ 通过 | 无 | ### 2. 发现并修复关键 DOM 结构 Bug **问题详情 (Story 2.4):** ```typescript // ❌ 原代码 - 等待 listbox 元素 await page.waitForSelector('[role="listbox"]', { timeout: DEFAULT_TIMEOUTS.static, state: 'visible' }); // ✅ 修复 - 直接等待 option 元素 // findTrigger 和 findAndClickOption 中使用 getByRole("option") ``` **Charlie (Senior Dev):** "这个 bug 很关键。Epic 1 的单元测试没有发现这个问题,因为单元测试模拟了完整的 DOM 结构。真实环境中的 Radix UI Select v2.2.5 结构与假设不同。" **修复内容:** 1. `selectRadixOption`: 改用 `getByRole("option")` 代替 `waitForSelector("[role=listbox]")` 2. `selectRadixOptionAsync`: 应用相同修复 3. 添加下拉框关闭等待逻辑(200ms + hidden 状态) 4. 缩短选择器超时(5000ms → 2000ms) **验证结果 (Story 2.5):** ``` ✅ 姓名: 完整测试_1768004957534 ✅ 性别: 男 ✅ 身份证号: 420101199001011234 ✅ 残疾证号: 51100119900104 ✅ 残疾类型: 视力残疾 ✅ 残疾等级: 一级 ✅ 联系电话: 13800138004 ✅ 身份证地址: 湖北省武汉市测试街道1号 ✅ 省份: 湖北省 ✅ 城市: 武汉市 ``` ### 3. 代码审查流程持续有效 Epic 2 每个故事都经过了代码审查,问题全部修复: | Story | 审查问题数 | 状态 | |-------|-----------|------| | 2.1 | 3 个(文档相关) | ✅ 全部修复 | | 2.2 | 多个(行号更新、实现调整) | ✅ 全部修复 | | 2.3 | 9 个(MEDIUM、LOW) | ✅ 全部修复 | | 2.4 | 初始发现问题 | ✅ 已修复 | | 2.5 | 1 个(.bak 文件) | ✅ 已修复 | **Dana (QA Engineer):** "代码审查继续发挥价值。Story 2.5 中发现的 .bak 文件问题虽然小,但这种细节关注保持了代码库的整洁。" ### 4. 真实 E2E 测试的价值 **单元测试 vs E2E 测试:** | 测试类型 | 覆盖场景 | 发现的问题 | |---------|---------|-----------| | 单元测试 (Epic 1) | 模拟 DOM 结构 | 无 | | E2E 测试 (Epic 2) | 真实 Radix UI 组件 | listbox DOM 问题 | **Elena (Junior Dev):** "Epic 1 的单元测试覆盖率达到了 93.65%,但仍然没有发现这个 DOM 结构问题。真实 E2E 测试是不可替代的。" --- **[第一部分完 - 会议概览和成功经验]** ## 挑战和问题分析 ⚠️ ### 1. DOM 结构假设与实际不符 **问题描述:** 工具假设 Select 组件的 DOM 结构包含 `[role="listbox"]` 元素,但 Radix UI Select v2.2.5 的实际结构是: ``` [role="combobox"] └── [role="option"] ← 选项直接在 combobox 内部 ``` **影响:** - 导致 `waitForSelector('[role="listbox"]')` 超时 - 测试在第一个 Select 操作时失败 - 阻塞了整个 Epic 2 的验证 **根本原因分析:** **Bob (Scrum Master):** "为什么单元测试没有发现这个问题?" **Charlie (Senior Dev):** "因为单元测试中的 mock DOM 结构是我们假设的完美结构。我们没有使用真实的 Radix UI 组件进行测试。" **教训:** - 单元测试不能完全替代集成/E2E 测试 - 需要在真实组件上验证工具 - DOM 结构假设应该基于实际实现而非理想模型 ### 2. Epic 1 回顾行动项未完全跟进 **Epic 1 HIGH 优先级行动项跟进情况:** | 行动项 | 状态 | 影响 | |--------|------|------| | HIGH #1: 配置 ESLint 规则 | ❌ 未完成 | Epic 2 中仍有重复的代码风格问题 | | HIGH #2: 更新架构文档记录 TS+Playwright 陷阱 | ⏳ 部分完成 | 开发者需要自己摸索 | | HIGH #3: 创建新的 Epic 2 | ✅ 完成 | Epic 2 成功执行 | | HIGH #4: 更新 Epic 编号 | ✅ 完成 | sprint-status 已更新 | **Alice (Product Owner):** "HIGH #1 和 #2 没有完成。这可能是为什么我们在 Epic 2 中仍遇到一些预期内的问题。" **未完成的行动项影响:** 1. **ESLint 规则未配置** - Epic 2 中仍然出现代码风格问题 - 例如:Story 2.5 中的 .bak 文件未清理 - 代码审查时间被浪费在可自动检测的问题上 2. **架构文档未更新** - TypeScript + Playwright 陷阱没有正式记录 - 新开发者需要自己摸索 - 知识传递效率低 ### 3. 渐进式迁移策略的额外成本 **Story 2.2 → Story 2.3 的迁移策略:** | Story | 范围 | 状态 | |-------|------|------| | 2.2 | 静态 Select | ✅ 完成,但保留自定义方法 | | 2.3 | 异步 Select | ✅ 完成,移除自定义方法 | **额外成本:** - Story 2.2 需要添加 TODO 注释 - Story 2.3 需要再次修改相同文件 - 需要协调两个故事的边界 **Charlie (Senior Dev):** "渐进式迁移策略保持了测试连续性,但确实增加了协调成本。如果一次性迁移所有 Select,风险会更高。这是一个权衡。" ### 4. 测试超时问题(非工具问题) **问题描述:** - 测试在文件上传阶段超时(60秒) - 与 Select 工具无关,是测试流程问题 **当前状态:** - 标记为 LOW 优先级 - 需要在后续 Epic 中处理(Epic 4: 文件上传测试) **Dana (QA Engineer):** "测试超时不是 Select 工具的问题,但它影响了 Epic 2 的完整验证。我们无法运行完整的测试套件来验证所有字段。" --- **[第二部分完 - 挑战和问题分析]** ## Epic 1 回顾行动项跟进 📋 ### HIGH 优先级行动项 | # | 行动项 | 负责人 | 预计时间 | Epic 2 状态 | |---|--------|--------|----------|-------------| | 1 | 配置 ESLint 规则捕获常见问题 | Charlie | 2h | ❌ **未完成** | | 2 | 更新架构文档记录 TS+Playwright 陷阱 | Charlie | 1h | ⏳ **部分完成** | | 3 | 创建新的 Epic 2 | Bob | 1h | ✅ **已完成** | | 4 | 更新 Epic 编号(2→3, 3→4, 4→5)| Bob | 0.5h | ✅ **已完成** | ### 详细分析 #### 行动项 #1: ESLint 规则 - 未完成 **原计划 (Epic 1 回顾):** ```javascript // .eslintrc.js { rules: { 'no-constant-binary-expression': 'error', 'no-unused-vars': 'error', 'no-empty': ['error', { allowEmptyCatch: false }], 'prefer-const': 'error' } } ``` **Epic 2 中的影响:** - Story 2.5 发现了未清理的 .bak 文件 - 代码审查仍然需要人工检查可自动检测的问题 **建议:** 在 Epic 3 开始前完成此行动项 #### 行动项 #2: 架构文档更新 - 部分完成 **Epic 2 中的证据:** - Story 2.2 Dev Notes 引用了 Epic 1 回顾中的 TypeScript + Playwright 陷阱 - 但架构文档本身未更新 **Charlie (Senior Dev):** "我在故事中引用了这些经验,但没有正式更新到架构文档中。这是我的疏忽。" #### 行动项 #3-4: Epic 规划调整 - 已完成 ✅ **Epic 2 成功创建并执行:** - 使用现有 `web/tests/e2e/` 测试基础设施 - 验证了 Select 工具在真实场景中的可用性 - 发现并修复了关键 DOM 结构问题 **Alice (Product Owner):** "Epic 规划调整非常成功。'先验证再扩展'的策略得到了验证。" ### MEDIUM 优先级行动项 | # | 行动项 | 负责人 | Epic 2 状态 | |---|--------|--------|-------------| | 5 | 创建开发者自查清单 | Elena | ❌ 未完成 | | 6 | 更新代码审查检查清单 | Charlie | ⏳ 部分完成 | --- ## 行动项 📋 ### 优先级 HIGH #### 1. 配置 ESLint 规则(从 Epic 1 延续) **负责人:** Charlie **预计时间:** 2 小时 **截止日期:** Epic 3 开始前 **需要配置的规则:** ```javascript // .eslintrc.js { rules: { // 捕获冗余的 null 检查 'no-constant-binary-expression': 'error', // 捕获未使用的变量 'no-unused-vars': 'error', // 捕获空 catch 块 'no-empty': ['error', { allowEmptyCatch: false }], // 首选 const 'prefer-const': 'error' } } ``` **预期收益:** 自动捕获约 50% 的重复审查问题 #### 2. 更新架构文档记录 TS+Playwright 陷阱(从 Epic 1 延续) **负责人:** Charlie **预计时间:** 1 小时 **截止日期:** Epic 3 开始前 **文档位置:** `_bmad-output/planning-artifacts/architecture.md` **需要添加的内容:** - TypeScript DOM 类型问题及解决方案 - 精确文本匹配选择器规范 - DOM 结构假设必须基于真实组件验证 #### 3. 更新工具包单元测试策略 **负责人:** Dana (QA Engineer) **预计时间:** 2 小时 **截止日期:** Epic 3 开始前 **问题:** 当前单元测试使用模拟 DOM,无法发现真实 DOM 结构问题 **建议解决方案:** - 在单元测试中使用真实的 Radix UI 组件 - 或添加集成测试级别,使用真实组件 **Elena (Junior Dev):** "如果我们使用真实组件进行单元测试,Epic 2 的 DOM 问题就能在 Epic 1 中发现。" ### 优先级 MEDIUM #### 4. 创建开发者自查清单(从 Epic 1 延续) **负责人:** Elena **预计时间:** 1 小时 **清单内容:** - [ ] 所有导出函数都有完整的 JSDoc - [ ] 内部函数使用 `@internal` 标记 - [ ] 错误处理使用 `E2ETestError` 而非原生 `Error` - [ ] DOM 结构假设必须基于真实组件验证 - [ ] 文本选择器使用 `:text-is()` 而非 `:has-text()` - [ ] 配置对象继承 `BaseOptions` - [ ] 超时值使用 `DEFAULT_TIMEOUTS` 常量 #### 5. 解决测试超时问题 **负责人:** Dana (QA Engineer) **预计时间:** 1-2 小时 **问题描述:** - 测试在文件上传阶段超时(60秒) - 影响完整测试套件的执行 **可能的解决方案:** 1. 增加测试超时时间 2. 优化文件上传逻辑 3. 分离文件上传测试到独立套件 **当前计划:** 在 Epic 4(文件上传测试)中处理 ### 优先级 LOW #### 6. 更新代码审查检查清单(从 Epic 1 延续) **负责人:** Charlie **预计时间:** 0.5 小时 **添加检查点:** - 检查 DOM 结构假设是否基于真实组件验证 - 验证是否遵循"先验证再扩展"原则 --- ## 关键决策 🎯 ### 决策 1: 跳过 Story 2.6 稳定性验证 **原计划:** - Story 2.6: 稳定性验证(连续 10 次,100% 通过) **实际情况:** - Story 2.5 已确认 Select 工具工作正常 - 所有字段都成功填写 - 测试超时与 Select 工具无关 **决策:** 跳过 Story 2.6,Epic 2 标记为完成 **理由:** 1. Select 工具已充分验证(静态 + 异步场景) 2. 10 次稳定性测试的边际收益递减 3. 测试超时问题阻塞了完整验证 4. Epic 3(扩展工具集)更有价值 **Alice (Product Owner):** "我同意跳过 Story 2.6。Select 工具已经验证充分,继续扩展工具集的价值更高。" ### 决策 2: 单元测试策略调整 **问题:** 单元测试使用模拟 DOM,无法发现真实 DOM 结构问题 **可选方案:** | 方案 | 优点 | 缺点 | |------|------|------| | A. 继续使用模拟 DOM | 快速、独立 | 无法发现 DOM 问题 | | B. 使用真实组件 | 发现真实问题 | 依赖外部组件 | | C. 添加集成测试 | 两全其美 | 增加测试层级 | **决策:** 采用方案 C - 添加集成测试级别 **Charlie (Senior Dev):** "单元测试应该保持快速和独立。我们添加一个集成测试级别,使用真实组件验证工具。" ### 决策 3: Epic 3 前完成 HIGH 优先级行动项 **未完成的 HIGH 行动项:** 1. 配置 ESLint 规则 2. 更新架构文档 3. 调整单元测试策略 **决策:** Epic 3 暂缓,先完成这些行动项 **理由:** 1. 这些改进将降低 Epic 3 的代码审查成本 2. 文档更新将提高 Epic 3 的开发效率 3. 测试策略调整将避免类似 DOM 问题再次发生 **Bob (Scrum Master):** "我们花 2-3 小时完成这些改进,Epic 3 会更顺利。这是值得的前期投入。" --- ## 总结 📝 **Epic 2 状态:** ✅ **Done** **关键成果:** - ✅ Select 工具在真实 E2E 测试中验证通过 - ✅ 发现并修复关键 DOM 结构问题 - ✅ "先验证再扩展"策略得到验证 - ✅ 代码审查流程持续有效 **关键经验:** 1. **真实 E2E 测试不可替代** - 单元测试无法发现 DOM 结构问题 2. **DOM 结构假设必须验证** - 不能基于理想模型开发工具 3. **渐进式迁移有价值** - 但需要额外的协调成本 4. **行动项跟进很重要** - Epic 1 的未完成行动项影响了 Epic 2 **下一步:** 1. ✅ Epic 2 完成并归档 2. 🆕 完成技术改进(ESLint、文档、测试策略) 3. ⏸️ Epic 3 暂缓,等待改进完成 4. 📋 创建 Epic 3 准备检查清单 **Bob (Scrum Master):** "Epic 2 是一个成功的验证 Epic。我们发现并修复了关键问题,验证了架构决策的正确性。更重要的是,我们学到了真实 E2E 测试的价值,这将指导后续的开发。" --- **[文档完]**