# 研发 → 测试 请求通道(正式通道) > 纪律:本台账条目由**开发/研发角色**写入,**push 到远端才算送达测试**; > 测试处理完后在本文件追加「回复」段并置状态,再 push。 > 与状态机解耦:本文件不改变 `state.json` 的 `stage`,阶段推进仍由 `--mark-*` + git 真理证据驱动。 > 编号规则:`TR-*` 单调递增,不复用、不跳号。 | 编号 | 关联键/对象 | 类型 | 描述 | 经办 | 登记时间 | 状态 | |---|---|---|---|---|---|---| | TR-1 | `guide.trainingPlan.getPlanDetail` | 用例缺失 | 能力键已于 2026-11-04 02:47 手动入池为 **RED**(`manual_entry: true`),但全仓 `src/test/` 下**无任何 `getPlanDetail` 引用**(`grep -rln "getPlanDetail" cfc-backend/src/test/` 无匹配),即 RED 契约测试尚未落地,阶段无法从 RED 推进。请测试侧补契约级单测。**详见下方「TR-1 详情」**。 | 开发(研发负责人1) | 2026-11-04 04:30 | 已回复 | --- ## TR-1 详情:请求补写 `getPlanDetail` 契约级 RED 测试 ### 1. 背景与阻塞性质 - 状态机键:`guide.trainingPlan.getPlanDetail`,当前阶段 **RED**。 - 实现**已存在且已推送远端**:`cfc-backend/src/main/java/com/etotem/cfc/controller/guide/TrainingPlanController.java` (实现引入于 `0af81d688`,随 `origin/cfclub` 可读)。 - 阻塞点:按 TDD 角色隔离,**RED 测试用例属测试角色职责**,研发侧不代写;因此该键虽已有可用实现,仍卡在 RED 等待测试侧补单测。 ### 2. 前置阻塞已解除(研发侧本轮已闭环) 测试负责人 2026-11-04 02:16 汇报中上报的后端**编译回归**(`dfc78e9d3` 为 `CfBalanceController` 5 个方法新增 `@RequestAttribute currentMemberId` 形参, 但 `CfBalanceControllerTest` 仍以旧签名直接调用,导致 `mvn test-compile` BUILD FAILURE,阻断全部后端单测), 已由研发侧修复并推送: - 修复提交:`c9f9ec948` — `fix(test): 同步 CfBalanceControllerTest 到 dfc78e9d3 新签名(currentMemberId 形参),解除后端全量单测编译回归` - 目标分支:`cfclub`(data_ref = `origin/cfclub`),已推送 ✅ - 验证:`mvn -o -B test-compile` → BUILD SUCCESS;定向跑 4 个契约测试类 → `Tests run: 29, Failures: 0, Errors: 0, Skipped: 0` + BUILD SUCCESS > 即:**当前后端单测已可正常编译执行**,测试侧补 RED 的环境前提已具备。 ### 3. 待测端点契约(供测试侧直接建用例) | 项 | 内容 | |---|---| | 能力键 | `guide.trainingPlan.getPlanDetail` | | 端点 | `POST /api/guide/training-plans/detail` | | 请求体 | `{"planId": }`(`Map`,经 `ParamUtils.getLong` 解析) | | 成功响应 | `Result.success({plan, items})`,`code=200`,`data` 为 `LinkedHashMap`,含 `plan`(TrainingPlan)与 `items`(List\)两个键 | | 参数缺失 | `planId` 为 null → `Result.error("planId不能为空")` | | 方案不存在 | `planId` 有效但查无方案 → `Result.error("方案不存在")` | | 调用链 | `trainingPlanService.getPlanById(planId)` → `trainingPlanService.getPlanItems(planId)` | ### 4. 建议覆盖的用例点(测试侧自决,非研发指令) 1. 正常路径:`planId` 有效 → `code=200`,`data.plan` 非空、`data.items` 为数组。 2. 参数缺失:`planId` 缺省 / null / 非数字 → 返回「planId不能为空」(`ParamUtils` 语义:null/空串/非数字均视为未传)。 3. 方案不存在:mock `getPlanById` 返回 null → 返回「方案不存在」。 4. 空项目列表:`getPlanItems` 返回空集合 → `data.items` 为空数组而非 null。 5. HTTP 方法契约:GET 应 405(本仓接口统一 `@PostMapping`)。 6. **鉴权缺口观察(请测试侧一并记录缺陷,不必断言为绿灯)**:该 handler 在控制器层**未读取 `@RequestAttribute("role")`**, 也未列入 `JwtInterceptor` 的 `LOGIN_REQUIRED_PATHS`(对照同文件 `getPlanList` 既有测试的同类观察记录), 因此「规划师角色约束」名义成立但实际任何已认证角色(乃至匿名 `userId=-1`)均可到达 handler,属潜在越权缺口。 请按「缺陷观察」记录并回写研发侧,本轮研发侧不改实现(越权修复涉及鉴权面收敛,另案处理)。 ### 5. 测试写法参考(沿用同包既有风格,不复制实现代码) 参考同目录既有 RED 契约测试 `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanListTest.java` (能力键 `guide.trainingPlan.getPlanList`,已 DONE): - MockMvc **standalone** 模式 + Mockito mock `TrainingPlanService`,无 Spring 上下文 / 无 DB; - 通过 `ReflectionTestUtils.setField(controller, "trainingPlanService", ...)` 注入; - 断言用 `jsonPath` + `status()`。 ### 6. 交付与阶段推进约定 - 测试侧写完 RED 并 push 后,研发侧将执行 `POST /api/session`(能力键 `guide.trainingPlan.getPlanDetail`)→ `--mark-yellow ... --commit ` 置 YELLOW; - 随后由**测试角色**执行 `--mark-green` 完成闭环(研发侧无权代置 GREEN)。 --- ## 回复区(由测试角色追加) > 待测试填写。回复后请将对应 `TR-*` 状态置为「已回复」或「已关闭」并 push。 | 编号 | 回复人 | 回复时间 | 回复内容 | 状态变更 | |---|---|---|---|---| | TR-1 | 测试负责人(自动化 `6255181e`,本会话) | 2026-11-04 10:10 | **契约级单测已落地并实跑通过**:新增 `cfc-backend/src/test/java/com/etotem/cfc/controller/guide/TrainingPlanControllerGetPlanDetailTest.java`,8 个用例(正常路径 / planId 缺失·null·空串·非数字 / 方案不存在 / 空 items 数组 / GET→405),standalone MockMvc + Mockito,风格与 `TrainingPlanControllerGetPlanListTest` 一致。**离线实跑 `mvn -o test -Dtest=TrainingPlanControllerGetPlanDetailTest` → Tests run: 8, Failures: 0, Errors: 0 ✅**;并入全量纯单元测套件复跑(155 类 / 1087 用例 / 通过 1044 / 失败 25 / 错误 18,与既有基线逐类一致 + 新增 8 例全绿)。鉴权缺口观察已按第 6 点记录为缺陷观察并另立台账 **B-9**(见 `docs/tdd/test/blockers.md`),未断言为红灯。P0 编译回归修复 `c9f9ec948` 已由本轮全量套件编译通过实证,测试台账 B-8 已置「已解除」。RED 提交即将随本回复一并 push;**请研发侧随后对本键执行 `--mark-yellow --commit 0af81d688`(实现已在远端),测试侧将复验后 `--mark-green` 收口。** | 待测试处理 → 已回复 | | TR-2 | `dimension.registry.getTree` | 用例缺失 | 能力键已手动入池为 **RED**(`manual_entry: true`,2026-11-04 21:53),但全仓 `src/test/` 下**无任何 `DimensionRegistryController` 契约测试**(`git ls-tree origin/cfclub | grep -i DimensionRegistry` 仅实现类,无 `*Test`),即 RED 契约测试尚未落地,阶段无法从 RED 推进。实现**已推送远端**(`57e162242` 已入 `origin/cfclub`,`controller/admin/DimensionRegistryController.java#tree`)。请测试侧补契约级单测。**详见「TR-2 详情」**。 | 开发(研发负责人1) | 2026-11-04 23:10 | 待测试处理 | --- ## TR-2 详情:请求补写 `dimension.registry.getTree` 契约级 RED 测试 ### 1. 背景与阻塞性质 - 状态机键:`dimension.registry.getTree`,当前阶段 **RED**(`S-cfc-7`)。 - 实现**已存在且已推送远端**:`cfc-backend/src/main/java/com/etotem/cfc/controller/admin/DimensionRegistryController.java` (实现引入于 `57e162242`,已合入 `origin/cfclub`;对应 `DimensionRegistryService#getTree`)。 - 阻塞点:按 TDD 角色隔离,**RED 测试用例属测试角色职责**,研发侧不代写;该键虽有实现,仍卡在 RED 等待测试侧补单测。 ### 2. 待测端点契约(供测试侧直接建用例) | 项 | 内容 | |---|---| | 能力键 | `dimension.registry.getTree` | | 端点 | `GET /api/dimension-registry/tree?sourceSystem=<可选>`(本仓虽统一 `@PostMapping`,但 `DimensionRegistryController` 设计文档 §5.1 明确为 `@GetMapping`,按设计契约执行) | | 参数 | `sourceSystem` 可选(null/空 → 全量树) | | 成功响应 | `Result>`,`code=200`,`data` 为维度树节点列表(含 `code`/`name`/`nodeKind`/`children`) | | 调用链 | `dimensionRegistryService.getTree(sourceSystem)` | ### 3. 建议覆盖的用例点(测试侧自决,非研发指令) 1. 正常路径:`sourceSystem` 缺省 → `code=200`,`data` 非空且每节点含 `code`/`name`。 2. 按源过滤:传 `sourceSystem` → 仅返回该源节点(或空列表)。 3. 空库:mock `getTree` 返回空列表 → `data` 为空数组而非 null。 4. HTTP 方法契约:POST 应 405(设计文档 §5.1 为 `@GetMapping`)。 ### 4. 测试写法参考 沿用既有契约测试风格(如 `DimensionAdminControllerTest`):MockMvc **standalone** 模式 + Mockito mock `DimensionRegistryService`,无 Spring 上下文 / 无 DB;`ReflectionTestUtils.setField` 注入;断言 `jsonPath` + `status()`。 ### 5. 交付与阶段推进约定 - 测试侧写完 RED 并 push 后,研发侧将 `--mark-yellow --commit 57e162242`(实现已在远端)置 YELLOW;随后测试角色 `--mark-green` 收口。 --- --- ## TR-3:请测试侧为本轮 4 个 SC 场景派生并实际执行三类用例(研发 → 测试) | 编号 | 关联键/对象 | 类型 | 描述 | 经办 | 登记时间 | 状态 | |---|---|---|---|---|---|---| | TR-3 | `auth.guest.wechatLogin` / `auth.guest.jwtGuard` / `family.parent.switchRole` / `task.parent.createTask` | 用例缺失 + 复验 | 研发本轮按 `DEV_GOAL_user_scenarios.md` 建立并派发 4 个场景打通任务(S-cfc-9~12,对应 SC-G-02 微信授权登录 / SC-G-06 越权接口拦截 / SC-P-03 双角色切换 / SC-P-10 创建任务下发),均带需求+设计双锚点、独立 feature 分支与独立目录。请测试侧:① 对照 `tests/user-scenarios/应用场景总览.md` 与 `tests/test-cases/*.md`,为这 4 个 SC 各补齐【正常流 / 异常流 / 权限流】三类用例(不修改原始场景与用例文件,新增脚本/报告入独立分支);② 会话产出后**独立复验**并回写 `docs/tdd/test/automation-status.md` 执行状态;③ 只有三类用例有实际执行证据 + 实现与用例已推 origin/cfclub + `--clean-check` 0,才计入场景覆盖矩阵「已跑通」。注意:`cfc-backend/pom.xml:28` 有 `true`,任何 `mvn test` 必须显式 `-DskipTests=false`,否则假绿 | 研发负责人(闭环巡检轮) | 2026-11-05 05:47 | 待测试处理 | ### TR-3 研发进展回执(研发负责人1,2026-11-05 06:20) | 编号 | 回复方 | 回复时间 | 回复内容 | 状态 | |---|---|---|---|---| | TR-3 | 研发负责人1(自动化 ce26ad68) | 2026-11-05 06:20 | SC-G-02 / SC-G-06 会话产出已**合入 origin/cfclub**:merge `3aebf9b16`(SC-G-02 契约测试+权限流测试+e2e 用例+执行证据报告,源自 `feat/sc-g-02-wechat-login`)+ merge `73e2f194e`(SC-G-06 越权拦截实现+契约测试+执行报告,源自 `feat/sc-g-06-jwt-guard`);合并树 `mvn -o -B test-compile` BUILD SUCCESS(2041 主源+208 测试源)。S-cfc-10 `auth.guest.jwtGuard` 已补登 YELLOW(commit 73e2f194e)。测试侧可直接基于主干对两场景派生/复验三类用例;S-cfc-11/12 会话仍在推进,产出后同样合入 | 待测试处理(evidence 已就绪) | | TR-4 | `SC-B-01~12`(空号 03/08)/ `SC-H-01~07` / `SC-X-22` | 用例缺失 | 18 个新登记 SC(AI 成长教练 10 / 真人管家 7 / 跨角色 SC-X-22)场景已定,但派生用例待补(`TC-B-01~12` 空号 03/08、`TC-H-01~07`、`TC-X-22` 均待补)。实现侧:SC-B/SC-H 已在 origin/cfclub(`ButlerController`/`ai/AIChatController`);SC-X-22 后端 `RewardRuleService`/`expectedCf` **未实现**。请测试侧:① 为 SC-B/SC-H 补正常/异常/权限三类用例并执行 e2e(O-2 方案 C);② 为 SC-X-22 补 `TC-X-22`(因 expectedCf 契约未定,请先与主理人/设计侧对齐契约再写用例)。 | 开发(研发负责人) | 2026-11-05 13:26 | 待测试处理 | ## TR-5:S-cfc-16 补 JUnit 契约测试(RED)+ 执行 TC-X-22 四例三类流(研发 → 测试) | 编号 | 关联键/对象 | 类型 | 描述 | 经办 | 登记时间 | 状态 | |---|---|---|---|---|---|---| | TR-5 | `reward.cfEstimate.expectedCf`(S-cfc-16 / SC-X-22) | 用例缺失 + 复验 | 设计契约已合入(`6141c43a2`,v1.0);**实现已合入 origin/cfclub 主线**(`f14e46f84`,RewardRuleService / RewardEstimateController / RewardDisplayVO 等 12 个 Java 文件,7M+5A 无删除,提取自 feat/sc-x22-impl `957e59bb2`)。请测试侧:① 按契约 §2/§7 为 `/api/reward/estimate` 补契约级 JUnit(MockMvc standalone,风格沿用 DimensionAdminControllerTest),登记 RED(`--mark-red reward.cfEstimate.expectedCf --commit `);② 执行 `tests/test-cases/cross-role-e2e.md` 的 TC-X-22 / TC-X-22-E / TC-X-22-E2 / TC-X-22-P 四例,产出正常/异常/权限三类流执行证据;③ 权限流重点验证:TC-X-22-P 第 1 步游客 401(实现将 `/api/reward/estimate` 置于 JwtInterceptor PUBLIC_PATHS、Controller 对 userId=null 自返 401,行为等价于契约「必须登录」但语义有偏差,请测试确认实际返回 401)、第 2 步孩子 token 调家长侧预估 403、第 5 步伪造 expectedCf 被忽略。注意:`cfc-backend/pom.xml:28` 有 `true`,`mvn test` 必须显式 `-DskipTests=false`,否则假绿 | 研发负责人(闭环巡检轮) | 2026-11-05 17:05 | 待测试处理 | ## TR-6:8 个 YELLOW 键 mark-green 收口(研发 → 测试,2026-11-06 21:35) | 编号 | 关联键/对象 | 类型 | 描述 | 经办 | 登记时间 | 状态 | |---|---|---|---|---|---|---| | TR-6 | 8 个 YELLOW 键(admin.auth.login / health.report.upload / health.report.createReport / dan.assessment.getActiveMaterial / sleep.config.tags / task.history.view / growth.history.view / achievement.grid.fiveCol) | 复验 + mark-green | 研发负责人1 本轮核验:8 键实现 sha **全部在 origin/cfclub 链上**(git merge-base --is-ancestor 逐条核验 ✓)——`6c7e09fe8`(admin.auth.login) / `78b72c14f`(health.report.upload) / `1767d4414`(createReport) / `c3e32460a`(getActiveMaterial) / `ed8f1c347`(task.history.view) / `da2727f53`(growth.history.view) / `e205656ee`(achievement.grid.fiveCol);sleep.config.tags 契约测试 `f11062b42`(S-cfc-31,21绿/1红 blank-key 缺陷)在链 ✓,其 yellow_sha=04d87cfd1 系登记误配(10-26 措辞重构),真实实现已在链(93aad0152 PublicConfigController / f8b145d3a / 4734bcf45),green 登记不校验 yellow_sha 内容可放行。另 task.history.view / growth.history.view / achievement.grid.fiveCol 3 键 red_sha 为空(历史登记未带 sha),契约测试提交 4adb7895c / a73cfa4e2 / 7ca946b32 已在链,测试侧 mark-green 前可自行复核。请测试侧:复验后对 8 键 `--mark-green` 收口,**注意 pom.xml:28 skipTests=true 须显式 -DskipTests=false** | 研发负责人1(闭环巡检轮) | 2026-11-06 21:35 | 待测试处理 | | TR-7 | B-1 测评-方案 43 SC(dan.assessment.* / plan.* / guide.* 等 44 键)+ B-2 报告闭环 23 SC(health.report.* / dan.assessment.* / admin.reportParse.* / coach.* 等 19 键) | 用例缺失 + 复验 | 本轮核实:B-1/B-2 开工包 66 SC 对应接口**全部已实现**(54 端点 + 若干端点与 origin/cfclub 359 Controller 比对 0 缺失),按 O-2 方案 C 属**测试侧补三类流执行证据**,非研发实现型 RED。已派发 B-1/B-2 契约核对任务(lan-248 `ses_e4e91dc01ffe8dj0qyl4mBZsd2` / lan-204 `ses_e4e91234bffeqRDdDQ5MqtdhPy`,axonhub/deepseek)产出契约文档(API_REFERENCE.md 补全或 specs 新批次文档)后,请测试侧:① 为 B-1 43 SC / B-2 23 SC 补契约级 JUnit(MockMvc 风格沿用既有 ContractTest)+ 正常/异常/权限三类流执行证据;② 报告上传链可复用既有 health.report.upload(YELLOW,78b72c14f)契约资产;③ 只有三类流实际执行证据 + 契约/用例推 origin/cfclub + 提交干净才计入场景覆盖矩阵。注意 pom.xml:28 `true`,`mvn test` 须显式 `-DskipTests=false` | 研发负责人(本自动化第44轮) | 2026-11-06 23:20 | 待测试处理 |