--- name: req-test-gate description: 测试与质量门禁制度。覆盖需求级测试(Gates 1-5)、部署级验证(Deploy Gates)、持续回归(Regression)、Harness Engineering 工程约束方法论(Ratchet、约定建立、门禁层级)。当用户提到质量门禁、架构约束、约定检查、ratchet、harness 相关任务时自动激活。 arguments: [args] --- # 测试与质量门禁制度 (req-test-gate) v2.1 ## 概述 三层质量门禁架构,确保从需求到上线每个阶段都有结构化验证。 **三层架构**: ``` 需求级 (Gates 1-5) → /req test 触发,单需求维度 部署级 (Deploy Gates) → /req deploy 触发,批量部署维度 持续维度 (Regression) → 定时/部署后触发,系统级回归 ``` ## 需求级门禁 (Gates 1-5) **触发时机**:`/req test` 执行、`/req next` 从 testing 推进 ``` Gate 0: Scope 分级(自动,决定后续 Gate 裁剪) ↓ Gate 1: 前置条件检查(自动) ↓ Gate 2: 测试执行验证(2A→2B→2C→2D→2E→2F,按 scope 裁剪) ↓ Gate 3: 测试质量验证(子代理,按 scope 决定是否触发) ↓ Gate 4: 文档持久化(自动,按 scope 选模板) ↓ Gate 5: 回归贡献检查(按 scope 区分贡献形式) ↓ 通过 → 允许 /req next 推进到待部署池 ``` ## Gate 0: Scope 分级 + 约定检查(自动) **两件事**:① 从 `git diff` 推断变更范围;② 运行项目内所有约定检查脚本。 ### 0A: Scope 分级 ```bash git diff main...HEAD --name-only | classify_scope ``` | scope | 判断依据 | Gate 裁剪效果 | |-------|---------|--------------| | `backend` | 仅 `.go` 文件变更 | 2A(go) + 2B 必须;2C/2F 跳过 | | `frontend` | `.tsx/.ts` 变更(含业务逻辑) | 2A(tsc/build) 必须;2B 跳过 | | `style-only` | 仅 `.css/.less` 或 shared/ 变更 | 2A(build) + **2F(视觉验证)** 必须;2B/2C 跳过 | | `fullstack` | 前后端都有改动 | 2A + 2B + 2C 全部必须 | **frontend vs style-only 区分**:`.tsx/.ts` 文件中是否包含 API 调用(`import.*api`、`fetch`、`request`)。仅样式/布局改动归为 style-only。 **scope 影响全部后续 Gate**,在测试报告中必须标注。 ### 0B: 约定检查(Harness 自动执行) **自动发现并运行项目内所有 `scripts/check-*.sh` 脚本。** ```bash # 自动执行逻辑 for script in scripts/check-*.sh; do [ -x "$script" ] && bash "$script" --ci done ``` | 结果 | 处理 | |------|------| | 全部 PASS | Gate 0 通过,继续 Gate 1 | | 有 FAIL | **阻塞**,按下方「失败处理」修复后重新 `/req test` | | 无 scripts/check-*.sh | 跳过(项目未建立约定检查) | **失败处理**(区分脚本类型): | 脚本类型 | 判断方法 | 修复方式 | |---------|---------|---------| | Hard wall(纯检测) | 脚本无 baseline 文件 | 修改代码消除违规 | | Ratchet(基线对比) | 脚本有 `.*-baseline.json` | 修改代码降低违规数,**或**确认是故意增加 → `./scripts/check-{name}.sh baseline` 更新基线 + AskUserQuestion 确认 | > 更新基线是有意识的决策(如重构导致临时增加),不能静默执行。 **报告格式**: ``` ### 约定检查 (Gate 0B) | 脚本 | 结果 | 详情 | |------|------|------| | check-architecture.sh | ✅ PASS | 5 rules, all within baseline | | check-modal-safety.sh | ✅ PASS | 0 violations | ``` > 这样 Harness 建立的约定脚本会在每次 `/req test` 时自动运行,无需手动执行 `/harness report`。 --- ## Gate 1: 前置条件检查 **自动检查,不可跳过。** | 检查项 | 检查方式 | 阻塞级别 | |--------|---------|----------| | CR 已通过 | `delivery_stage >= review` 或有 completed 的 code_review 任务 | 阻塞 | | 开发任务全部完成 | 所有 `linkRole=implementation` 的任务状态为 completed | 阻塞 | | CR 文档存在(code 类型) | `has_task_document` 对 code_review 任务 | 警告 | **未通过处理**: - 阻塞项 → 直接拒绝,提示「请先完成 {缺失项}」 - 警告项 → AskUserQuestion 确认是否继续 ## Gate 2: 测试执行验证 **按需求类型执行分层测试,从静态到动态逐步验证。** ### 类型推断 从 `get_requirement_tasks` 的 linkRole 集合推断: - **code**: 有 `implementation` 任务 → 代码需求 - **skill**: 无 `implementation`,有 `prd`/`test` → Skill/文档需求 - **ops**: 仅 `deploy` 任务 → 运维需求 ### code 类型:五阶段验证 #### 2A: 静态验证(编译+类型检查) **按 scope 裁剪执行项:** | 序号 | 测试项 | 命令 | scope 触发条件 | 通过条件 | |------|--------|------|---------------|----------| | T1 | 后端编译 | `go build ./...` | backend / fullstack | exit 0 | | T2 | 后端单元测试 | `go test ./...` | backend / fullstack | 全部 PASS | | T4 | 前端类型检查 | `tsc --noEmit` | frontend / fullstack | exit 0 | | T4b | 前端构建 | `vite build` | **所有前端 scope** | 构建成功 | | T5 | 前端测试 | `npm test` 相关组件 | frontend / fullstack | PASS | | T7 | iOS 编译 | `xcodebuild build` | 有 iOS 改动时 | exit 0 | **style-only scope**:仅执行 T4b(构建验证),跳过 T1/T2/T4/T5。 #### 2B: API 端点验证(后端独立) | 序号 | 测试项 | 命令 | 必须 | 通过条件 | |------|--------|------|------|----------| | T3 | API 端点验证 | `curl localhost:8080` 调用新/改 API | 必须 | 预期状态码和数据 | | T3.1 | DB 约束验证 | `curl` 测试 FK/唯一约束 | 推荐 | 错误码正确(400/404) | | T3.2 | 错误处理验证 | 无效输入/缺失参数 | 推荐 | 错误响应格式正确 | | T3.3 | **并发/原子性** | 2 个并发请求竞争边界量(如库存恰好=N,发 2 个各 N 件的请求)| 涉及库存/积分/财务时必须 | 恰好 1 个成功,另一个返回"不足",DB 无超卖 | | T3.4 | **租户隔离** | 用 tenant B token 操作 tenant A 的资源 ID | 多租户系统必须 | 返回 403/无权,DB 未被篡改 | | T3.5 | **状态流转完整性** | 触发所有 change_type/状态流转后查流水表 | 有状态机实体时必须 | 所有预期流水类型都出现过 | > **触发判断(以下任一为真则 T3.3–T3.5 必须执行):** > - 需求涉及库存/积分/余额/限购 > - 需求有多租户资源隔离要求 > - 需求引入了新的状态机(status 枚举 ≥ 3 个) #### 2C: 前后端联调(开发环境) **触发条件**:scope 为 `fullstack`,或前端 `.tsx/.ts` 文件包含 API 调用(`import.*api`、`fetch`、`request`) **不触发**:scope 为 `backend`、`style-only`,或前端改动不涉及 API 调用 **环境要求**:本地开发环境,前端 :3000 + 后端 :8080 同时运行 > **无后端替代方案**:IT6 页面可访问性验证可用 Playwright API Mock 模式(`page.route()`)替代真实后端。详见 `dev-test` 技能的 `e2e-testing.md` §API Mock 冒烟测试。 **前置步骤**: 1. 确认本地数据库已执行相关 migration(菜单、表结构等) 2. 启动后端 `cd backend && go run main.go` 3. 启动前端 `cd frontend && npm start` 4. 获取 JWT Token(`POST /api/v1/auth/login`) | 序号 | 测试项 | 方法 | 必须 | 通过条件 | |------|--------|------|------|----------| | IT1 | 前端代理连通 | `curl localhost:3000/api/v1/health` | 必须 | 200(前端代理到后端成功) | | IT2 | 菜单可见性 | `curl localhost:3000/api/v1/menus/user-menus` | 必须 | 新菜单出现在响应中 | | IT3 | API 代理验证 | `curl localhost:3000/api/v1/<新端点>` | 必须 | 通过前端代理调用后端 API 返回预期数据 | | IT4 | 路由配置 | 检查 App.tsx 有 `` | 必须 | 路由存在且 lazy import 正确 | | IT5 | 图标映射 | 检查 Layout.tsx iconMap 有对应图标 | 条件 | 有新菜单图标时必须验证 | | IT6 | 页面可访问 | 浏览器访问 `localhost:3000/<新路径>` | 推荐 | 页面加载无白屏、无 console 报错 | **无前端改动时**:标记 `⏭️ 跳过: 无前端改动`。 **常见联调问题及排查**: | 问题 | 根因 | 解决方案 | |------|------|----------| | 菜单不显示 | 本地 DB 未执行 menu migration | 执行 migration SQL + 修复 sequence | | API 返回 404 | 前端代理路径不匹配 | 检查 `setupProxy.js` 或 `package.json` proxy 配置 | | 页面白屏 | React 组件 import 错误或 TS 类型不匹配 | 检查 console 错误,修复 import 路径 | | 登录失败 | 本地用户密码不匹配 | 重新生成 bcrypt cost 12 哈希并更新本地 DB | | Redis 缓存脏数据 | 菜单/权限缓存未清理 | `redis-cli KEYS "menu:user:*"` 后逐个 DEL | #### 2D: 冒烟测试(Staging 环境) **触发条件**:已部署到 staging | 序号 | 测试项 | 命令 | 必须 | 通过条件 | |------|--------|------|------|----------| | SM1 | API 健康检查 | `curl staging/api/v1/health` | 必须 | 200 | | SM2 | 核心流程验证 | `curl` 新功能关键 API | 必须 | 预期响应 | | SM3 | 数据一致性 | 创建→读取→验证 | 推荐 | 数据完整返回 | **未部署到 staging 时**:标记 `⏭️ 跳过: 未部署到 staging`。 #### 2E: 原型符合性测试 **触发条件**:有关联原型 HTML(`prototype-*.html`) | 序号 | 测试项 | 方法 | 必须 | 通过条件 | |------|--------|------|------|----------| | PC1 | 结构完整性 | 对比原型 Section 数 vs 实现区块 | 必须 | 所有 Section 有对应实现 | | PC2 | 数据模型对齐 | 对比原型字段 vs API 返回字段 | 必须 | 字段名/类型匹配 | | PC3 | 交互流程覆盖 | 对比原型操作 vs 实现事件绑定 | 推荐 | 所有交互有绑定 | | PC4 | 状态覆盖 | 对比原型状态标签 vs 实现枚举 | 推荐 | 状态集一致 | **无原型时**:标记 `⏭️ 跳过: 无关联原型`。 **原型冻结规则**:原型在评审通过后冻结,设计变更需创建新需求。 #### 2F: 视觉/响应式验证(v2.1 新增) **触发条件**:scope 为 `style-only` 或 `frontend`(有 CSS/LESS 变更时) **不触发**:scope 为 `backend` | 序号 | 测试项 | 方法 | 必须 | 通过条件 | |------|--------|------|------|----------| | VR1 | 断点一致性 | `grep -rn "max-width\|min-width" --include="*.css" --include="*.less"` 对比 breakpoints 定义 | 必须 | 所有新增 media query 使用标准断点值 | | VR2 | 构建无警告 | `vite build` 输出检查 | 必须 | 无 CSS 相关 warning | | VR3 | !important 审计 | `grep -c "!important"` 统计新增数量 | 推荐 | 新增 !important ≤ 3 个,或有合理理由 | | VR4 | 文件完整性 | 新增组件/样式文件全部存在 | 必须 | 所有 import 的文件可解析 | | VR5 | 移动端适配 | 检查关键页面在 ≤768px 下的 CSS 规则覆盖 | 推荐 | 有对应的移动端样式 | **无 CSS 变更时**:标记 `⏭️ 跳过: 无样式改动`。 ### skill 类型 Checklist | 序号 | 测试项 | 方法 | 必须 | |------|--------|------|------| | S1 | 关键词一致性 | `grep` 核心概念跨文件对齐 | 必须 | | S2 | 规则无歧义 | 审查每条规则触发条件和动作 | 必须 | | S3 | 边界情况 | 至少 1 个边界场景验证 | 必须 | | S4 | 交叉引用 | 文件间引用指向正确 | 推荐 | | S5 | Token 大小 | `wc -w` < 7500 词 | 推荐 | ### ops 类型 Checklist | 序号 | 测试项 | 方法 | 必须 | |------|--------|------|------| | O1 | 命令可执行 | dry-run 或 staging 执行 | 必须 | | O2 | 健康检查 | `curl` 健康端点 | 必须 | | O3 | 回滚方案 | 文档审查 | 推荐 | ### UAT 场景设计(复杂业务需求适用) 当需求涉及以下任一情况时,在 2B 之后额外执行 UAT 场景矩阵: - 完整业务流程(下单→支付→发货→退款) - 并发控制(乐观锁/悲观锁/原子 SQL) - 多角色协作(消费者 + 管理员 + 供应商) **执行方式**:参照 [uat-patterns.md](uat-patterns.md) 的 5 类场景框架逐一设计用例,用 ai-proj 创建 stage="testing" 的子任务跟踪进度。 ### 执行记录格式 ``` | T1 | 后端编译 | `go build ./...` | ✅ PASS | exit 0, 0 errors | | IT1 | 前端代理连通 | `curl localhost:3000/api/v1/health` | ✅ PASS | 200 | | IT2 | 菜单可见性 | user-menus API | ✅ PASS | 持续管理+2子菜单 | | SM1 | 健康检查 | `curl staging/health` | ✅ PASS | 200 | | PC1 | 结构完整性 | 原型 11 sections vs 实现 | ⏭️ 跳过 | 无关联原型 | ``` ## Gate 3: 测试质量验证(子代理) 派遣 test-validator 子代理审查。模板: `~/.claude/skills/req-test-gate/test-validator.md` **触发规则(按 scope 裁剪)**: - code + `backend` / `fullstack`:**总是触发** - code + `frontend`(含业务逻辑):**触发** - code + `style-only`:**不触发**(CR 已覆盖样式审查) - skill 类型:**≥5 测试项时触发** - ops 类型:**不触发** ```typescript Task({ subagent_type: "superpowers:code-reviewer", prompt: `使用 test-validator 模板审查测试质量。 模板路径: ~/.claude/skills/req-test-gate/test-validator.md 填充参数: - REQUIREMENT_TITLE: "{需求标题}" - REQUIREMENT_TYPE: "{code|skill|ops}" - TEST_RESULTS: "{Gate 2 的执行记录表格}" - CODE_CHANGES_SUMMARY: "{改动文件列表和摘要}" - CHECKLIST_USED: "{使用的 checklist 类型}" ` }) ``` | 评估结果 | 处理 | |---------|------| | "测试充分" | Gate 3 通过 | | "需补充测试"(Important) | AskUserQuestion 确认 | | "测试不足"(Critical) | 阻塞,必须补充后重新验证 | ## Gate 4: 文档持久化 **不可跳过。** `create-and-attach` 写入测试任务文档。**按 scope 选择模板。** ### 轻量模板(scope = style-only / frontend 无 API) ```markdown ## 测试报告 - {需求标题} | 字段 | 值 | |------|-----| | 需求 | REQ-XXXX | | scope | {style-only/frontend} | | 门禁版本 | test-gate v2.1 | ### 构建验证 | 项目 | 命令 | 结果 | |------|------|------| | TypeScript | tsc --noEmit | ✅/❌/⏭️ | | Vite Build | vite build | ✅/❌ | ### 视觉验证 (2F) | 序号 | 测试项 | 结果 | 备注 | |------|--------|------|------| | VR1 | 断点一致性 | ✅/❌ | ... | | VR2 | 构建无警告 | ✅/❌ | ... | | VR4 | 文件完整性 | ✅/❌ | ... | ### 总结 通过: {N}/{M} | 结论: ✅ 通过 / ❌ 未通过 ``` ### 完整模板(scope = backend / fullstack) ```markdown ## 测试报告 - {需求标题} | 字段 | 值 | |------|-----| | 需求 | REQ-XXXX | | 类型 | {code/skill/ops} | | 时间 | {YYYY-MM-DD HH:MM} | | 门禁版本 | test-gate v2 | ### 前置条件 (Gate 1) - CR 状态: ✅ 已通过 - 开发任务: ✅ 全部完成 ({N}/{N}) ### 测试执行 (Gate 2) | 序号 | 阶段 | 测试项 | 命令/方法 | 结果 | 备注 | |------|------|--------|----------|------|------| | T1 | 2A | 后端编译 | ... | ✅/❌/⏭️ | ... | | IT1 | 2C | 前端代理连通 | ... | ✅/❌/⏭️ | ... | | SM1 | 2D | 健康检查 | ... | ✅/❌/⏭️ | ... | | PC1 | 2E | 结构完整性 | ... | ✅/❌/⏭️ | ... | ### 跳过的测试 ⏭️ {测试项}: {原因} (无则写「无」) ### 质量验证 (Gate 3) {子代理结果摘要,或「未触发(ops 类型)」} ### 回归贡献 (Gate 5) {贡献的回归用例数,或「无需贡献」或「⏭️ 跳过: 过渡期」} ### 总结 通过: {N}/{M} | 跳过: {K} | 结论: ✅ 通过 / ❌ 未通过 ``` ### 文档质量门禁(被 `/req next` 检查) - 含测试项表格(`|` 分隔符 ≥ 3 行) - 含通过/失败结论(`✅ 通过` 或 `❌ 未通过`) - 总字符数 ≥ 200 - 门禁版本标记(`test-gate v2` 或 `test-gate v2.1`) ## Gate 5: 回归贡献检查 **确保 code 类型需求为回归池贡献测试用例。按 scope 区分贡献形式。** **触发条件**:code 类型需求 | 检查项 | 说明 | 阻塞级别 | |--------|------|----------| | 有 regression linkRole 任务 | `get_requirement_tasks(linkRole=regression)` | 警告 | | 任务有文档附件 | `has_task_document` | 警告 | | 文档包含可执行用例 | 含 `curl` 命令或测试脚本 | 建议 | **过渡期规则(v2.1)**:警告但不阻塞,AskUserQuestion 提醒补充。 ### Scope 贡献形式 | scope | 贡献形式 | 示例 | |-------|---------|------| | `backend` | curl 脚本(API 回归) | `curl -X POST .../api` → 201 | | `frontend` | E2E 场景描述(Playwright API Mock) | 页面加载 + 核心交互验证。编写模式见 `dev-test` 技能 `e2e-testing.md` | | `style-only` | 视觉回归 checklist | 断点覆盖 + !important 审计 | | `fullstack` | curl 脚本 + E2E 场景 | 两者都需要 | ### 回归用例模板(backend / fullstack) ```markdown ## 回归用例 - REQ-XXXX {需求标题} ### 模块 {okr / task / auth / ...} ### 用例列表 | ID | 场景 | 命令 | 预期结果 | 优先级 | |----|------|------|----------|--------| | RC1 | ... | `curl ...` | 200 + ... | 高 | ``` ### 回归用例模板(frontend / style-only) ```markdown ## 回归用例 - REQ-XXXX {需求标题} ### 模块 {product / order / layout / ...} ### 视觉/交互用例 | ID | 场景 | 验证方法 | 预期结果 | 优先级 | |----|------|---------|----------|--------| | VRC1 | 移动端列表布局 | 浏览器 375px 宽度截图 | 卡片正常排列 | 高 | | VRC2 | 响应式断点切换 | 768px→769px 切换 | 布局无跳变 | 中 | ``` 详见 [regression.md](regression.md) 了解完整回归系统设计。 ## 部署级门禁 (Deploy Gates) **触发时机**:`/req deploy` 执行 详见 [deploy-gates.md](deploy-gates.md) 概要流程: ``` DG1: 迁移检查(不可跳过) → 有未执行 migration? DG2: Staging 部署 → 构建+部署到 singapore DG3: 冒烟测试 → 核心 API 可用 DG4: 影响域回归 → module-deps 决定范围 DG5: 性能基线(推荐) → 关键 API 响应时间 DG6: 生产部署(不可跳过) → 健康检查+文档 ``` ## 回归测试模块 **系统级持续活动,独立于单需求生命周期。** 详见 [regression.md](regression.md) 核心概念: - **回归池**:所有需求贡献的测试用例汇集处 - **回归判定**:上次 PASS + 本次 FAIL = 回归(高优先级,自动创建 bug 需求) - **闭环**:回归失败 → 创建 bug 需求 → 修复 → 回归池更新 - **三种执行模式**:影响域(部署触发)、关键路径(每日)、全量(每周) ## Force 跳过规则 | 门禁 | 可否 Force | 说明 | |------|-----------|------| | Gate 1 前置条件 | **不可** | 必须满足 | | Gate 2 测试执行 | 单项可跳过 | 需记录原因 | | Gate 3 质量验证 | Critical 不可,Important 可 | AskUserQuestion 后跳过 | | Gate 4 文档持久化 | **不可** | 必须生成文档 | | Gate 5 回归贡献 | 可(过渡期) | 警告级别 | | Deploy Gates | DG1/DG6 不可,其余可 | 迁移和健康检查不可跳过 | ## 与现有流程集成 ### `/req test` 增强 ``` v1: Gate 1 → Gate 2 → Gate 3 → Gate 4 v2: Gate 1 → Gate 2(2A→2B→2C→2D→2E) → Gate 3 → Gate 4 → Gate 5 v2.1: Gate 0(scope) → Gate 1 → Gate 2(2A→2B→2C→2D→2E→2F) → Gate 3 → Gate 4 → Gate 5 v3: Gate 0A(scope) + 0B(约定检查) → Gate 1 → Gate 2(按scope裁剪) → Gate 3 → Gate 4 → Gate 5 ``` ### `/req next` testing→staging 门禁 验证测试文档:Gate 1-5 全部通过的完整报告 + 门禁版本 `test-gate v2` ### `/req deploy` 部署门禁 在 req-deploy 流程前增加 Deploy Gates (DG1-DG6) 检查。 --- ## Harness Engineering — 工程约束方法论 **项目级基础设施**的建立和维护方法论,与上述需求级门禁互补。 > 详见 [harness-engineering.md](harness-engineering.md) 完整文档。 ### 核心理念 **建立自动化护栏防止新违规,同时允许渐进式清理遗留问题。** 三大支柱: 1. **Ratchet** — 遗留违规数只能减不能增 → [ratchet-pattern.md](ratchet-pattern.md) 2. **约定建立** — 每个 bug 修复后立即建立约定和检测 → [convention-flow.md](convention-flow.md) 3. **门禁层级** — 按项目成熟度逐级引入 → [project-bootstrap.md](project-bootstrap.md) ### `/harness` 命令集(手动可用 + 自动嵌入) | 命令 | 手动 | 自动触发 | |------|------|---------| | `/harness assess` | 随时 | 首次 `/req dev` | | `/harness init [level]` | 随时 | — | | `/harness convention [name]` | 随时 | `/req cr` + bug 类型需求 | | `/harness report` | 随时 | `/req test` Gate 0B | ### 模板 `templates/` 目录提供可复用的脚本模板: - [ratchet-script.md](templates/ratchet-script.md) — Ratchet 脚本模板(check/baseline/report 三命令) - [convention-script.md](templates/convention-script.md) — 约定检测脚本模板(grep 模式匹配) - [gates-doc.md](templates/gates-doc.md) — GATES.md 文档模板 - [pre-commit-config.md](templates/pre-commit-config.md) — husky + lint-staged 配置(Node.js/Go/Monorepo) ### 与需求级门禁的关系 ``` Harness(项目级护栏) req-test-gate(需求级门禁) ├── .husky/ pre-commit ├── Gate 0A: scope 分级 ├── CI lint workflow ├── Gate 0B: 运行 harness 的 check-*.sh ←─ 连接点 ├── scripts/check-*.sh ├── Gate 1: 前置条件 ├── CLAUDE.md 约定 ├── Gate 2: 测试执行 │ ├── Gate 3: 质量验证 │ ├── Gate 4: 文档持久化 │ └── Gate 5: 回归贡献 ``` > Harness 不使用 Gate 编号。它的产出物(check-*.sh 脚本)通过 Gate 0B 接入 req-test-gate 流程。