|
@@ -0,0 +1,327 @@
|
|
|
|
|
+# CFC 自动化测试执行台账 · 2026-11-05 01:05(第 35 轮)
|
|
|
|
|
+
|
|
|
|
|
+> 测试负责人视角 · TDD 多智能体研发测试调度 skill + 软件测试专家团
|
|
|
|
|
+> 全程只读:未改 / 未提交 / 未推送源码(本台账为过程产物);未安装依赖、未联网外网、未启业务服务、未伪造通过/失败。
|
|
|
|
|
+> 无人值守默认口径(沿用 #18–#34):执行档 = **review(离线白名单)**;`mvn test` 内含 testCompile 属运行前提,**不单独做编译验证动作**。
|
|
|
|
|
+> 本轮新增:首次对 **统一维度注册中心(commit `57e162242`,2026-11-03 P0-T1/P0-T2/P1-T4)** 做了实测取证 + 测试库只读核验。
|
|
|
|
|
+
|
|
|
|
|
+## 1. 历史审查记录
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 值 |
|
|
|
|
|
+| --- | --- |
|
|
|
|
|
+| 上次同 ID 批次 | #34(2026-11-04 21:24),结论「不通过(有条件)」 |
|
|
|
|
|
+| 期间兄弟批次 | 23:25、23:36 两次(同 automation ID 兄弟会话,测试负责人闭环轮,仅跑 3 键定向 16 例) |
|
|
|
|
|
+| 上轮遗留缺口 | ① 109 例非环境红未处置;② 30 例环境红(连接池/上下文);③ 3 RED 键伪 RED;④ 无 CI;⑤ Playwright/pytest/覆盖率零执行 |
|
|
|
|
|
+| 本次是否改善 | 通过率 **90.54% → 91.88%**;环境红 **30 → 8**;红类 **41 → 37**;非环境红 109 → **112(+3,全部来自新特性契约测试)**;编译连续第 9 轮无错 |
|
|
|
|
|
+| 记忆应用 | 沿用「`-Dtest=!` 排除串失效 → 全量不排除」「完整性按源类−报告类核验」「`mvn clean` 替代 `rm -rf`」「定向跑必带 `-DskipTests=false`」「NPE 用 `@Mock` vs `@Resource` 差集归因」五条历史教训 |
|
|
|
|
|
+| 结论复用声明 | **不沿用**历史结论,本轮全部证据重新实测(后端 48 分 50 秒真实跑测、前端实跑、根级 tests 实跑、测试库 4 条只读 SQL 核验) |
|
|
|
|
|
+
|
|
|
|
|
+## 2. 项目画像(本轮复核)
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 值 |
|
|
|
|
|
+| --- | --- |
|
|
|
|
|
+| 业务定位 | 家庭教育成长平台(五维能量、家庭关系、测评订单、健康报告、商城) |
|
|
|
|
|
+| 技术栈 | Spring Boot 2.7.18 + MyBatis-Plus(Java 8)· uni-app 小程序 · Vue2 管理端 · FastAPI/LangGraph |
|
|
|
|
|
+| HEAD | `3aa97c924`(23:43 测试负责人台账提交);**后端 `src` 相对上轮基线 `e62ef62fc` 有实质变更**:15 文件 +1028 行(统一维度体系 P0/P1:新增 `DimensionRegistryController` 4 端点、`DimensionRegistryService` 183 行、`DimensionCodeMapper` 110 行、`DimensionSyncService` 48 行、`DatabaseInitializer` 迁移 445–447、`schema.sql` 同步、2 个新测试类 392 行) |
|
|
|
|
|
+| 工作区 | 74 项未提交;**后端 2 个未提交文件**(`DimensionRegistryService` +46/−13、`DimensionCodeMapper` +13/−1,即 S-cfc-7 的启动时序/过滤时序修复),本轮实测**包含该 WIP** |
|
|
|
|
|
+| 测试资产 | 204 个 Java 测试类(`@Test` 1545)· 前端 Jest 14 套件 296 例 · 根级 tests 3 套件 23 例 · Playwright 70 spec / 410 例(未跑)· pytest 11 文件 / 47 例(未跑) |
|
|
|
|
|
+| 编目规模 | 358 控制器 / 1944 handler;handler 覆盖 365(**18.8%**)=全覆盖 24 + 部分覆盖 193 + 未覆盖 140 + 无 handler 1;用例编目合计 2731 |
|
|
|
|
|
+| 环境 | JAVA_HOME=`D:\jdk1.8.0_25`,Maven 3.6.1(`/d/maven/apache-maven-3.6.1`),`~/.m2` 离线 `-o` |
|
|
|
|
|
+| 服务状态 | 9082 DOWN / 9000 DOWN / 4090 DOWN / 8082 DOWN / 8888 DOWN / 4091 OPEN;测试库 `192.168.16.251:3306` OPEN(`max_connections=1000`,`Max_used=190`) |
|
|
|
|
|
+
|
|
|
|
|
+## 3. 测试覆盖矩阵(20 类,逐类三态)
|
|
|
|
|
+
|
|
|
|
|
+| # | 测试类型 | 状态 | 证据(本轮实测优先) |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| 1 | 单元测试 | ✅ 已发现 | 204 类 / 1528 例实跑,1404 通过(91.88%) |
|
|
|
|
|
+| 2 | 测试覆盖率 | ⚠️ 待核实 | 无 JaCoCo 配置,仍无行/分支覆盖率数字(仅 handler 命中率 18.8%) |
|
|
|
|
|
+| 3 | 变异测试 | ❌ 未发现 | 无 PIT/mutation 配置 |
|
|
|
|
|
+| 4 | 集成测试 | ⚠️ 部分 | `@SpringBootTest` 上下文测随全量实跑;根级 `tests/integration` 16 例因服务未启 fetch failed |
|
|
|
|
|
+| 5 | 契约测试 | ✅ 已发现(**新增 2 类**) | 3 个 RED 键契约 16/16 绿;**维度注册中心契约 16 例(Tree 9/9 绿、Map 7 例 3 红)** |
|
|
|
|
|
+| 6 | 接口 API 测试 | ⚠️ 部分 | MockMvc 已覆盖 `/dimension-registry/tree`、`/map`;**`/roots`、`/code/{code}` 零测试** |
|
|
|
|
|
+| 7 | 端到端 E2E | ⚠️ 部分 | Playwright 70 spec / 410 例静态存在,未执行(需 9082 + 联网授权) |
|
|
|
|
|
+| 8 | 验收 UAT | ❌ 未发现 | 无 UAT 脚本/记录资产 |
|
|
|
|
|
+| 9 | BDD 规格 | ❌ 未发现 | 无 cucumber/behave 资产 |
|
|
|
|
|
+| 10 | 冒烟测试 | ⚠️ 部分 | `playwright.config.smoke.js` 存在,未执行 |
|
|
|
|
|
+| 11 | 回归测试 | ✅ 已发现 | 全量套件即回归基线(本台账连续 35 轮);**红类集合逐类比对可作回归判据** |
|
|
|
|
|
+| 12 | 探索性测试 | ❌ 未发现 | 无 charter/记录 |
|
|
|
|
|
+| 13 | 性能测试 | ❌ 未发现 | 无 JMeter/Gatling 资产 |
|
|
|
|
|
+| 14 | 可靠性测试 | ❌ 未发现 | 无故障注入/恢复演练 |
|
|
|
|
|
+| 15 | 安全测试 | ⚠️ 待核实 | 无 SAST;依赖漏洞扫描需联网未授权;**新端点匿名可读(实测契约用例通过)** |
|
|
|
|
|
+| 16 | 兼容性测试 | ❌ 未发现 | 无浏览器/机型矩阵 |
|
|
|
|
|
+| 17 | 可用性测试 | ❌ 未发现 | — |
|
|
|
|
|
+| 18 | 无障碍测试 | ❌ 未发现 | — |
|
|
|
|
|
+| 19 | QA 流程/质量指标 | ⚠️ 部分 | 本台账即指标源;无 CI 门禁;状态机 3 键滞留 |
|
|
|
|
|
+| 20 | 全项目代码审查 | ⚠️ 部分 | 本轮深读维度注册中心全链路(Controller/Service/Mapper/Sync/迁移/schema)+ 规约扫描 |
|
|
|
|
|
+
|
|
|
|
|
+**缺口初判**:可执行层仍集中在「单元 + 契约 + 回归」;E2E / 性能 / 安全 / 兼容四类零执行或条件未授权。本轮新特性的「契约层」首次有实测,但**测试设计与实现口径出现 3 处分歧**(见 P-2)。
|
|
|
|
|
+
|
|
|
|
|
+## 4. 测试方案(本轮实际执行范围)
|
|
|
|
|
+
|
|
|
|
|
+| 维度 | 命令 | 目标 | 结果 |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| 后端全量单元/契约/集成 | `mvn -o test -DskipTests=false -Dmaven.test.failure.ignore=true` | 全仓回归 + 新特性取证 | 204 类 / 1528 例,BUILD SUCCESS,48:50 |
|
|
|
|
|
+| 前端 Jest | `node node_modules/jest/bin/jest.js --ci`(cfc-frontend) | 前端工具函数回归 | 14 套件 / 296 例 **100%**,32.3s |
|
|
|
|
|
+| 根级 tests Jest | `node ../cfc-frontend/node_modules/jest/bin/jest.js -c jest.config.js`(tests/) | 小程序游戏/计划链集成 | 3 套件 / 23 例,7 绿 / 16 红(服务未启 fetch failed) |
|
|
|
|
|
+| 编目刷新 | `discover_tests.py` + `test_inventory.py` | 覆盖矩阵与台账 | 358 ctrl / 1944 handler / 18.8%;2731 用例 |
|
|
|
|
|
+| 测试库只读核验 | 4 条 `SELECT`(维度/指标/id 冲突) | 验证「指标混排」是否真生效 | **12 维度 / 130 指标 / 指标 parent_id 全为 NULL / id 冲突 12** |
|
|
|
|
|
+
|
|
|
|
|
+**未纳入本轮(原因)**:Playwright 410 例(服务未起 + 未授权联网)、pytest 47 例(无 .venv,conftest 缺 httpx,按纪律不装)、覆盖率(无 JaCoCo)、变异(无 PIT)、压测(无工具且需联网)、依赖漏洞扫描(需联网未授权)。
|
|
|
|
|
+
|
|
|
|
|
+## 5. 执行档
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 值 |
|
|
|
|
|
+| --- | --- |
|
|
|
|
|
+| 档位 | **review(离线白名单)** |
|
|
|
|
|
+| 已执行 | Maven 离线全量测试、Node Jest(前端/根级)、只读扫描脚本、只读 SQL |
|
|
|
|
|
+| 未执行(需显式授权) | 任何联网动作(远端 push、外部 API 压测、依赖漏洞库查询)、安装依赖、启动 9082/9000/4090 |
|
|
|
|
|
+| 越界声明 | 无。未改源码 / 未提交 / 未推送 / 未改 `.tdd/state.json` |
|
|
|
|
|
+
|
|
|
|
|
+### 5.1 本轮过程事故(首次记录,需流程处置)
|
|
|
|
|
+
|
|
|
|
|
+**第一次跑测(23:52 启动)在 8 分 14 秒后被外部终止**:`mvn clean` 先报 `Failed to delete target\test-classes\...\service`(被占用),随后 `mvn test` 跑到第 5 个测试类(00:04:51)时 mvn 与 surefire fork 同时消失,日志无 BUILD 汇总、仅留 5 份报告、`EXIT=0`。同期机器上存在**另一个 JVM(其它会话的构建)**,且 `target/classes` 事后被清空(迫使本轮二次全量编译 2041 个源文件)。
|
|
|
|
|
+
|
|
|
|
|
+→ 判定:**共享仓库 + 同模块并发跑测互相破坏 target**,非代码缺陷。处置建议见 P-9(worktree 隔离 + 独立 `-Dmaven.repo.local`,即 skill 的 `test_isolation` 机制)。
|
|
|
|
|
+
|
|
|
|
|
+## 6. 相对上轮(#34)漂移对账
|
|
|
|
|
+
|
|
|
|
|
+| 指标 | #34(21:24) | #35(本轮) | 变化 | 解释 |
|
|
|
|
|
+| --- | --- | --- | --- | --- |
|
|
|
|
|
+| 后端测试类 | 202 | **204** | +2 | 新增 `DimensionRegistryTreeTest`、`DimensionRegistryMapContractTest` |
|
|
|
|
|
+| 后端用例 | 1512 | **1528** | +16 | 同上(9 + 7) |
|
|
|
|
|
+| 通过 | 1369 | **1404** | +35 | 新增 13 绿 + 5 个环境红类转绿 |
|
|
|
|
|
+| 失败 / 错误 / 跳过 | 68 / 71 / 4 | **71 / 49 / 4** | +3 / −22 / 0 | E 大幅下降=环境红显著缓解 |
|
|
|
|
|
+| 通过率 | 90.54% | **91.88%** | +1.34pp | 剔除环境红 92.41% |
|
|
|
|
|
+| 红类 | 41 | **37** | −4 | 转绿 5 类、新增红 1 类 |
|
|
|
|
|
+| 环境红用例 | 30 | **8** | −22 | `Failed to load ApplicationContext` 类由 8→3 |
|
|
|
|
|
+| 非环境红用例 | 109 | **112** | +3 | **净值全部来自新特性契约测试** |
|
|
|
|
|
+| 编译 | 203 源 0 错 | **205 源 0 错** | +2 | 编译阻断连续第 9 轮关闭 |
|
|
|
|
|
+| 完整性 | 202/202 | **204/204**,沉默 0,`.dump` 0 | — | 无 fork 中断 |
|
|
|
|
|
+
|
|
|
|
|
+**逐类红例比对**:`run34 ∩ run35` 的 36 个红类,**每类红例数一一相同(0 处漂移)**;转绿 5 类全部为上轮环境红(`DailyOverviewServiceTest`、`DimensionEnergySyncServiceTest`、`DimensionScoreServiceImplTest`、`GuideApplicationServiceTest`、`GuidePackageServiceTest`);**唯一新增红类 `DimensionRegistryMapContractTest`(3 例)**。
|
|
|
|
|
+
|
|
|
|
|
+→ 结论:**存量代码零回归**;本轮全部新增失败均在「新增测试 vs 新增实现」的口径分歧上。
|
|
|
|
|
+
|
|
|
|
|
+## 7. 三层归因(非环境红 112 例 / 33 类)
|
|
|
|
|
+
|
|
|
|
|
+**A 测试侧缺陷/漂移(65 例 / 15 类)**
|
|
|
|
|
+- `GuideOrderControllerTest` 8、`CfCommissionServiceSettleTest` 8(WantedButNotInvoked)
|
|
|
|
|
+- `ProductOrderServiceFulfillmentMultiModeTest` 6(`wechatService` 未声明 `@Mock`)、`ProductOrderControllerTest` 6(桩用 `confirm(...)`,生产已 `confirmReceive(...)` @`ProductOrderController.java:94`)
|
|
|
|
|
+- `GuideFamilyTaskControllerTest` 5、`GuideRolePermissionTest` 5、`PlannerBindInviteFlowTest` 5、`AuthControllerTest` 4(期望 500 实得 410)、`FamilyJoinRequestServiceReferrerBindTest` 4(夹具缺 3 个 `@Mock`)
|
|
|
|
|
+- **`DimensionRegistryMapContractTest` 3(本轮新增,见 §8)**、`ArticleWorkflowTest` 3、`TaskProgressUpdateTest` 3、`FortuneServiceTest` 2、`ServiceRoleApproveTest` 2、`MembershipPaySwitchTest` 1
|
|
|
|
|
+
|
|
|
|
|
+**B 疑似生产缺陷(46 例 / 18 类)**
|
|
|
|
|
+- `ArticleControllerTest` 9(4F+5E)、`EnergySystemFlowTest` 6(统一 500)、`PaymentControllerTest` 4、`DanReportParseServiceTest` 4(字段丢失)、`ProductControllerTest` 3、`GrowthRecordSyncFlowTest` 3、`ProductOrderServiceUpdateExpressFieldTest` 3、`GuideTeamControllerTest` 2、`HealthDimensionControllerTest` 2、`WishControllerTest` 2、`FamilyControllerTest` 1、`MindFortuneControllerTest` 1、`StatsControllerTest` 1、`Orchestration*` 2、`PaymentServiceORDRoutingTest` 1、`TaskPlanServiceTest` 1、`DailyCheckinStreakFlowTest` 1
|
|
|
|
|
+
|
|
|
|
|
+**C 环境/数据(9 例 / 4 类)**
|
|
|
|
|
+- `AdminFamilyOverviewControllerTest` 3、`FamilyAdminOverviewServiceTest` 3、`UserServiceFamilyNameLinkTest` 2:均为 `Failed to load ApplicationContext → auditLogAspect → sqlSessionFactory → primaryDataSource → HikariPool: Communications link failure`(`SfmsDataSourceConfig.java:48`,池上限继承 `application.yml:26` 的 50)
|
|
|
|
|
+- `GuideModuleIntegrationTest` 1(planner 认证种子缺失)
|
|
|
|
|
+
|
|
|
|
|
+## 8. 新特性专项(统一维度注册中心)实测取证
|
|
|
|
|
+
|
|
|
|
|
+**8.1 实测结果**
|
|
|
|
|
+
|
|
|
|
|
+| 测试类 | 例数 | 结果 | 说明 |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| `DimensionRegistryTreeTest` | 9 | **9/9 绿**(119.7s) | 5 根 + 7 body 子维、字段契约、sourceSystem 过滤 |
|
|
|
|
|
+| `DimensionRegistryMapContractTest` | 7 | **4 绿 / 3 红**(5.3s) | 3 红见 8.2 |
|
|
|
|
|
+
|
|
|
|
|
+**8.2 三处口径分歧(本轮最高价值发现)**
|
|
|
|
|
+
|
|
|
|
|
+| 用例 | 断言 | 实际 | 定性 |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| `map_unknownLegacy_returnsNullData` | `$.data` = null | `"unknown_legacy_xyz"` | 实现 `DimensionCodeMapper.resolveToUnified` 对未知码**原样返回**(`:74` javadoc「未知则返回原值(容错)」,实现 `:82-83`);设计文档 §4/§5.1 **未定义**未知行为 → 契约空白 |
|
|
|
|
|
+| `map_emptyLegacy_returnsNullData` | `$.data` = null | `""` | 同上(空串走 `legacy.trim()` 返回 `""`) |
|
|
|
|
|
+| `map_missingLegacy_returnsBadRequest` | HTTP 400 | HTTP 200 | `GlobalExceptionHandler:43` 的 `MissingServletRequestParameterException` 分支返回 `Result.error(400,...)` 但**未设 `@ResponseStatus`** → 项目既定口径是「HTTP 200 + body.code=400」,用例按裸 HTTP 语义断言 |
|
|
|
|
|
+
|
|
|
|
|
+**8.3 测试库只读核验(关键)**
|
|
|
|
|
+
|
|
|
|
|
+| 查询 | 结果 | 含义 |
|
|
|
|
|
+| --- | --- | --- |
|
|
|
|
|
+| `product_dimension_config` 行数 | **12** | 5 根 + 7 body 子维(迁移 447 seed 生效) |
|
|
|
|
|
+| `indicator_definitions` 总行数 | 130 | 指标资产存在 |
|
|
|
|
|
+| `indicator_definitions` 中 `parent_id IS NOT NULL` | **0** | **没有任何指标进入维度树** |
|
|
|
|
|
+| `product_dimension_config.id = indicator_definitions.id` 的碰撞数 | **12 / 12** | 两表 id 空间完全重叠 |
|
|
|
|
|
+
|
|
|
|
|
+→ 与 `DimensionRegistryService.getTree` 代码对读:`if (ind.getParentId() == null) continue;` 直接跳过全部 130 个指标;即便日后补 `parent_id`,`idToNode.putIfAbsent(...)` 也会因 id 与 12 个维度节点冲突而**静默丢弃指标节点**(或被错误挂到同 id 维度下)。
|
|
|
|
|
+
|
|
|
|
|
+→ 结论:设计文档主张的「维度节点 ∪ 指标节点**混排**」在当前实现中**未生效**,而 `DimensionRegistryTreeTest` 只断言 5 根 + 7 子维,无法暴露该缺陷(契约测试覆盖不足)。
|
|
|
|
|
+
|
|
|
|
|
+## 9. 覆盖缺口清单
|
|
|
|
|
+
|
|
|
|
|
+| # | 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
|
|
|
|
|
+| --- | --- | --- | --- | --- | --- | --- |
|
|
|
|
|
+| G-1 | 契约空白 | `map` 未知/空 legacy 行为未定义 | 前后端对 null/原值理解不一致 → 前端渲染空维度 | 设计侧补「未知码返回 null + code=200」或「返回原值」明确条款;用例同步 | P0 | 设计文档定稿 + 契约用例改断言,复跑该 3 例转绿 |
|
|
|
|
|
+| G-2 | 功能未达设计 | 指标节点 0 个入树;两表 id 空间重叠 | P1-T4「指标混排」上线即错配 | 新增「指标节点混排」契约用例(造 1 个 `parent_id` 非空指标,断言出现在树中且 id 唯一化策略生效) | P0 | 实现改复合键/前缀键 + 用例转绿 |
|
|
|
|
|
+| G-3 | 端点未覆盖 | `/roots`、`/code/{code}` 零用例 | 回归无保护 | 各补 2–3 例(正常/未知/异常码) | P1 | 用例入库并转绿 |
|
|
|
|
|
+| G-4 | 双写伪实现 | `DimensionSyncService.syncToLegacy` 仅打日志 | 开关一开即「以为双写、实际不写」→ 新旧数据分叉 | 改为抛「未实现」告警或加启动校验;补开关开启时的一致性用例 | P1 | 代码标记 + 用例 |
|
|
|
|
|
+| G-5 | 门禁缺失 | 无 CI 流水线(无 `.github/workflows`/`.gitlab-ci.yml`/`Jenkinsfile`) | 通过率无强制约束 | 接入流水线:`mvn -o test` + Jest,落 `surefire` 报告 | P1 | CI 文件入库并跑通 |
|
|
|
|
|
+| G-6 | 环境不稳 | 8 例上下文加载失败(池 50 × 45 个 `@SpringBootTest` 上下文) | 通过率在 88%–92% 间摆动,易误判回归 | 新增 `application-test.yml`:`maximum-pool-size: 4`、`minimum-idle: 1` | P1 | 连跑 3 轮环境红=0 |
|
|
|
|
|
+| G-7 | 状态机滞留 | 3 键仍 RED(≈73h),对应契约 16/16 全绿 | 伪 RED 污染进度账 | 授权后 `--mark-yellow/--mark-green` 收口 | P2 | 状态机进入 GREEN/DONE |
|
|
|
|
|
+| G-8 | 执行隔离 | 同模块并发跑测互相 clean 破坏 target | 报告缺失/假绿 | 跑测走 `.worktrees/<slug>` + `-Dmaven.repo.local` 隔离 | P2 | 两批次并发跑测互不影响 |
|
|
|
|
|
+
|
|
|
|
|
+## 10. 域结论表
|
|
|
|
|
+
|
|
|
|
|
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| 单元·组件级 | 苏雅 | ⚠️ 不达标 | 91.88%(阈 95%);非环境红 112 例跨 9 轮未减 |
|
|
|
|
|
+| 集成·接口级 | 柯砚 | ⚠️ 部分 | 新特性 16 例中 3 例口径分歧;`/roots`、`/code` 零覆盖;根级 integration 16 例因服务未启失败 |
|
|
|
|
|
+| 系统·验收级 | 白樾 | ❌ 未覆盖 | 无 E2E/UAT/BDD 执行(Playwright 410 例未跑) |
|
|
|
|
|
+| 测试保障级 | 闻朔 | ⚠️ 部分 | 回归基线可用(逐类红例 0 漂移);无 CI 门禁;无探索性记录 |
|
|
|
|
|
+| 性能·可靠性 | 骆骋 | ❌ 未覆盖 | 无性能/可靠性工具与实测 |
|
|
|
|
|
+| 安全 | 关屿 | ⚠️ 待核实 | 无 SAST;依赖漏洞扫描需联网未授权;`@GetMapping` 规约违规 **11 处 / 3 文件(本轮 +4)**;新端点匿名可读(低敏感) |
|
|
|
|
|
+| 兼容·体验 | 阮清 | ❌ 未覆盖 | 无浏览器/机型矩阵、无无障碍资产 |
|
|
|
|
|
+| 流程·度量·代码 | 何序 | ⚠️ 部分 | 迁移 445–447 与 `schema.sql` 已同步(合规);feature flag 一处未使用;并发跑测破坏 target |
|
|
|
|
|
+
|
|
|
|
|
+## 11. 五要素问题清单
|
|
|
|
|
+
|
|
|
|
|
+### P-1(P0·疑似设计目标未达成)指标混排未生效 + 两表 id 空间冲突
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`GET /api/dimension-registry/tree` 返回的树中**不含任何指标节点**;测试库 `indicator_definitions` 130 行的 `parent_id` 全部为 NULL,实现遇到 NULL 直接 `continue`。同时 `product_dimension_config` 与 `indicator_definitions` 的主键空间完全重叠(12/12),一旦指标补上 `parent_id`,`idToNode.putIfAbsent` 会静默丢弃指标节点。
|
|
|
|
|
+2. **测试 bug 点**:`DimensionRegistryService.java:71-84`(`:72` `if (ind.getParentId() == null) continue;` / `:83` `idToNode.putIfAbsent(n.getId(), n)`);`DimensionRegistryTreeTest` 仅断言 5 根 + 7 子维(`:81-215`),无「指标入树」用例。
|
|
|
|
|
+3. **最优修改方案**:① 节点键改为 `dim:<id>` / `ind:<id>` 复合键(或统一 `nodeKey`),父子引用同步改;② 补 1 条契约用例:造 `parent_id` 非空的指标,断言其出现在树中、且与同号维度节点并存不冲突;③ 若产品决定「指标暂不入树」,则同步修改设计文档 §3.2 并在 `getTree` 注释标注「P1-T4 未实现」。
|
|
|
|
|
+4. **修改目的**:保证注册中心作为「统一取数入口」名副其实,避免上线后前端拿到残缺树。
|
|
|
|
|
+5. **闭环**:新增用例由红转绿 + `tree?sourceSystem=indicator` 返回非空 + 人工比对设计文档 §3.2。
|
|
|
|
|
+
|
|
|
|
|
+### P-2(P0·契约口径分歧)`DimensionRegistryMapContractTest` 3 例失败
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`map` 端点 7 例中 3 例失败——未知 legacy 期望 `data=null` 实得原值;空串期望 `data=null` 实得 `""`;缺参期望 HTTP 400 实得 200。
|
|
|
|
|
+2. **测试 bug 点**:`DimensionRegistryMapContractTest.java:71-75`(unknown)、`:80-84`(empty)、`:89-93`(missing param);实现侧 `DimensionCodeMapper.java:74-83`(javadoc「未知则返回原值」+ 实现 `:82-83`)、`GlobalExceptionHandler.java:43-47`。
|
|
|
|
|
+3. **最优修改方案**:先由设计/研发裁决「未知码语义」(建议:`Result.success(null)`,前端显式判空);裁决后二选一落地——(a) 若采纳 null:实现改 `resolveToUnified` 未知返回 null,并加 `@ResponseStatus` 无关;用例保留;(b) 若采纳「原值容错」:改用例断言 `data == "unknown_legacy_xyz"`,并把缺参用例改为断言 `body.code==400`(符合项目「HTTP 200 + body code」约定)。
|
|
|
|
|
+4. **修改目的**:让契约成为跨端唯一事实源,消除「测试绿但语义未定」。
|
|
|
|
|
+5. **闭环**:3 例转绿 + 设计文档 §5.1 补「未知/空/缺参」三行契约表。
|
|
|
|
|
+
|
|
|
|
|
+### P-3(P1·规约漂移)新增 4 个 `@GetMapping` 违反项目强制规约
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`DimensionRegistryController` 新增 `/tree`、`/roots`、`/code/{code}`、`/map` 全部用 `@GetMapping`;全仓 `@GetMapping` 计 11 处 / 3 文件(`CfBalanceController` 6、`AdminSystemPromptController` 1、本轮新增 4)。
|
|
|
|
|
+2. **测试 bug 点**:`DimensionRegistryController.java:27,32,37,46`;规约出处 `AGENTS.md`「统一 `@PostMapping`,禁止 `@GetMapping`」。
|
|
|
|
|
+3. **最优修改方案**:改为 `@PostMapping`,前端 `DimensionProvider` 调用同步改 POST;或先在 `AGENTS.md` 明确「只读查询类允许 GET」并统一整改历史 7 处。
|
|
|
|
|
+4. **修改目的**:消除规约二义性(当前既有 7 处违例,新增代码继续复制坏范式)。
|
|
|
|
|
+5. **闭环**:`grep -rn "@GetMapping" controller/ | wc -l` 归零或规约条款更新 + 代码一致。
|
|
|
|
|
+
|
|
|
|
|
+### P-4(P1·静默失效)特性开关一处未使用、双写为伪实现
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`dimension.registry.enabled=false` 仅被 `isRegistryEnabled()` 读取,全仓无调用方 → 开关不产生任何行为差异;`dimension.registry.dualWrite=true` 时 `syncToLegacy` 只打 debug 日志,不写旧表。
|
|
|
|
|
+2. **测试 bug 点**:`DimensionRegistryService.java:41-46,152-176`;`DimensionSyncService.java:27-48`。
|
|
|
|
|
+3. **最优修改方案**:① `enabled=false` 时让控制器返回明确「未启用」或注册 Bean 条件装配;② `dualWrite` 未实现则启动时 `log.warn` + 拒绝为 true(fail-fast),避免运维误开。
|
|
|
|
|
+4. **修改目的**:防止「以为关了/以为在双写」造成的数据口径事故。
|
|
|
|
|
+5. **闭环**:补 2 条配置驱动用例(enabled=false 行为、dualWrite=true 抛错/告警)+ 启动日志核对。
|
|
|
|
|
+
|
|
|
|
|
+### P-5(P1·状态机)3 个 RED 键伪 RED 第 8 轮
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`health.report.createReport`(5 例)、`guide.trainingPlan.getPlanDetail`(8 例)、`dan.assessment.getActiveMaterial`(3 例)对应契约测试 **16/16 全绿**,但状态机仍全为 RED,滞留 ≈73h。
|
|
|
|
|
+2. **测试 bug 点**:`.tdd/state.json` 3 键 `stage=RED`;台账侧 `docs/tdd/test/automation-status.md` 与实测不一致。
|
|
|
|
|
+3. **最优修改方案**:由研发负责人对本轮实测结论 `--mark-yellow`(若实现已合入)→ 测试负责人 `--mark-green`;`O-1` 连续 8 轮缺研发动作,建议升级为流程阻塞项。
|
|
|
|
|
+4. **修改目的**:状态机可信,否则「红绿灯」失去调度意义。
|
|
|
|
|
+5. **闭环**:`--status` 显示 3 键 GREEN/DONE + 台账同步刷新。
|
|
|
|
|
+
|
|
|
|
|
+### P-6(P1·门禁)无 CI 流水线
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:仓库无任何 CI 配置,1528 例测试无强制门禁,回归依赖人工/定时任务。
|
|
|
|
|
+2. **测试 bug 点**:仓库根无 `.github/workflows`、`.gitlab-ci.yml`、`Jenkinsfile`。
|
|
|
|
|
+3. **最优修改方案**:最小流水线 = `mvn -o test`(后端)+ `jest --ci`(前端)+ 归档 surefire 报告 + 通过率阈值(先设 90%,逐步升 95%)。
|
|
|
|
|
+4. **修改目的**:把「连续 35 轮人工跑测」变成自动化守门。
|
|
|
|
|
+5. **闭环**:流水线在 PR 上跑通并阻断低于阈值合并。
|
|
|
|
|
+
|
|
|
|
|
+### P-7(P2·环境)3 类 8 例上下文加载失败(连接池/网络)
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`AdminFamilyOverviewControllerTest`、`FamilyAdminOverviewServiceTest`、`UserServiceFamilyNameLinkTest` 全部 `Failed to load ApplicationContext`,根因链到 `primaryDataSource`(`application.yml:26` 池 50、`SfmsDataSourceConfig.java:48`)`Communications link failure`。
|
|
|
|
|
+2. **测试 bug 点**:`application.yml:23-30`(`maximum-pool-size: 50`、`minimum-idle: 10` 被测试继承,**45 个 `@SpringBootTest` 类**各自建池)。
|
|
|
|
|
+3. **最优修改方案**:新增 `src/test/resources/application-test.yml`,池收敛为 `maximum-pool-size: 4` / `minimum-idle: 1` / `connection-timeout: 5000`,测试 profile 激活。
|
|
|
|
|
+4. **修改目的**:消除随机环境红,让通过率成为可比指标。
|
|
|
|
|
+5. **闭环**:连跑 3 轮环境红 = 0。
|
|
|
|
|
+
|
|
|
|
|
+### P-8(P2·流程)共享仓库并发跑测互相破坏 target
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:本轮第一次跑测被外部 `clean` 中断(8 分 14 秒,仅 5 份报告,无 BUILD 汇总);同时 `target/classes` 被清空,迫使二次全量编译。
|
|
|
|
|
+2. **测试 bug 点**:无隔离的 `cfc-backend/target` 被多会话共用;skill `test_isolation` 机制未启用。
|
|
|
|
|
+3. **最优修改方案**:跑测统一走 `.worktrees/<branch-slug>`(目录与分支 1:1)+ `-Dmaven.repo.local=<worktree>/.m2`;或在 CI/本地脚本加「target 独占锁」。
|
|
|
|
|
+4. **修改目的**:保证「一次跑测一组证据」,避免假绿/假红。
|
|
|
|
|
+5. **闭环**:两批次并发跑测互不影响、报告数与源类数一致。
|
|
|
|
|
+
|
|
|
|
|
+### P-9(P2·文档一致性)`AGENTS.md` 公开路径数量与实际不符
|
|
|
|
|
+
|
|
|
|
|
+1. **问题描述**:`AGENTS.md` 记「`JwtInterceptor` 拦截 `/api/**`(8 个公开路径除外)」,实际 `WebConfig.java:97-136` 排除 **40** 条;`dimension-registry` 未在排除列表却被匿名访问(实测 200),说明鉴权口径另有分支。
|
|
|
|
|
+2. **测试 bug 点**:`AGENTS.md` 认证段;`WebConfig.java:96-137`;`JwtInterceptor.java:86-97,250-256`。
|
|
|
|
|
+3. **最优修改方案**:文档改为「按 `JwtInterceptor` 内 `loginRequired` 白名单 + WebConfig 40 条排除」双口径描述,并列出「匿名可读」接口清单。
|
|
|
|
|
+4. **修改目的**:避免新人按文档误判鉴权、把敏感接口当公开。
|
|
|
|
|
+5. **闭环**:文档与实际排除清单脚本化比对(`grep` 计数一致)。
|
|
|
|
|
+
|
|
|
|
|
+## 12. 门禁结论
|
|
|
|
|
+
|
|
|
|
|
+| 门禁项 | 阈值 | 实测 | 判定 |
|
|
|
|
|
+| --- | --- | --- | --- |
|
|
|
|
|
+| G1 后端单测通过率 | ≥ 95% | **91.88%**(剔环境红 92.41%) | ❌ |
|
|
|
|
|
+| G2 非环境红 | = 0 | **112 例 / 33 类** | ❌ |
|
|
|
|
|
+| G3 前端 Jest | 100% | **296/296 = 100%** | ✅ |
|
|
|
|
|
+| G4 可编译性 | 0 错误 | **205 测试源 0 错**(连续第 9 轮) | ✅ |
|
|
|
|
|
+| G5 执行完整性 | 报告类 = 源类 | **204/204,沉默 0,`.dump` 0** | ✅ |
|
|
|
|
|
+| G6 CI 门禁 | 已接入 | 无流水线 | ❌ |
|
|
|
|
|
+| G7 状态机一致 | 无伪 RED | **3 键伪 RED(第 8 轮,≈73h)** | ❌ |
|
|
|
|
|
+| G8 新特性契约一致 | 新增用例全绿 | **7 例 3 红** | ❌ |
|
|
|
|
|
+
|
|
|
|
|
+### 结论:**不通过(有条件)**
|
|
|
|
|
+
|
|
|
|
|
+- 存量代码**零回归**(36 个存量红类逐类红例数 0 漂移),编译与完整性双绿,前端 100%。
|
|
|
|
|
+- 阻断项集中在:① 新特性契约口径未定(P-1/P-2,3 例红 + 混排未生效);② 112 例存量非环境红;③ 无 CI;④ 状态机 3 键伪 RED。
|
|
|
|
|
+
|
|
|
|
|
+**使绿优先序**:P-1/P-2(新特性,1 天内可闭环)→ P-3/P-4(规约与开关,半天)→ P-7(test profile 收池)→ P-6(CI)→ P-5(状态机收口)→ P-8(跑测隔离)。
|
|
|
|
|
+
|
|
|
|
|
+## 13. 未实测项(如实声明)
|
|
|
|
|
+
|
|
|
|
|
+| 项 | 原因 | 本轮处置 |
|
|
|
|
|
+| --- | --- | --- |
|
|
|
|
|
+| Playwright 410 例 / 70 spec | 9082 未启 + 需联网授权 | 未执行,不计入结论 |
|
|
|
|
|
+| pytest 47 例(11 文件) | 无 `.venv`,conftest 缺 `httpx`(按纪律不装) | 未执行 |
|
|
|
|
|
+| cfc-web Jest | `node_modules` 无 jest 依赖 | 未执行 |
|
|
|
|
|
+| 覆盖率(JaCoCo)/ 变异(PIT) | 无工具配置 | 未产出数字 |
|
|
|
|
|
+| 性能 / 可靠性 / 依赖漏洞 / DAST | 无工具 + 需联网 | 未执行 |
|
|
|
|
|
+| CI 实测 | 无流水线 | 仅诊断 |
|
|
|
|
|
+| 状态机写入(mark-*) | 写操作未授权 | 仅只读取证 |
|
|
|
|
|
+| 提交与推送 | 未授权 | 全部本地 |
|
|
|
|
|
+
|
|
|
|
|
+## 14. 方法论继承与新增
|
|
|
|
|
+
|
|
|
|
|
+**沿用(5 条)**:全量不排除优于 `-Dtest=!`;完整性按「源类 − 报告类」核验;`mvn clean` 替代 `rm -rf`;定向跑必带 `-DskipTests=false`;NPE 用 `@Mock` vs `@Resource` 差集归因。
|
|
|
|
|
+
|
|
|
|
|
+**本轮新增(3 条,后续务必继承)**:
|
|
|
|
|
+1. **跑测前先探活并发构建**:`Get-Process java` + `target` 目录 mtime;同模块有他人构建时,本轮第一次跑测被 `clean` 打断(8 分 14 秒、5/205 类)。判据:日志无 `BUILD` 汇总 + 报告数远小于源类数 = 被外部杀,不是测试失败。
|
|
|
|
|
+2. **「设计与实现是否一致」可用测试库只读 SQL 快速取证**:`SHOW VARIABLES`/`SELECT COUNT(*)`/自连接查 id 冲突,比读代码更硬(本轮 4 条 SQL 定形 P-1)。
|
|
|
|
|
+3. **契约测试转红先判「是测试错还是实现错」**:把断言与 `AGENTS.md`/`GlobalExceptionHandler` 既有约定比对(本轮 HTTP 400 vs 200 即项目约定「HTTP 200 + body code」,属测试侧错)。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 15. 01:05 复跑更正(当前 main HEAD = `db095214a`,2026-11-05 00:39)
|
|
|
|
|
+
|
|
|
|
|
+> 本章节为 01:05 本轮(测试负责人)对**当前 main 仓库 HEAD** 的复跑结论,覆盖并修正 §1–§12 中「编译连续第 9 轮无错 / 后端 BUILD SUCCESS」的口径。
|
|
|
|
|
+> **重要**:§1–§12 描述的是 01:04 轮基于 **HEAD `3aa97c924`(2026-11-04 23:43,回归提交 `44b2f0d42` 之前)** 的运行;本轮 01:05 复跑基于**当前 main HEAD `db095214a`(含 `44b2f0d42` 的回归)**,后端已**无法编译**。
|
|
|
|
|
+
|
|
|
|
|
+### 15.1 复跑环境与结果
|
|
|
|
|
+- 工具链:`/d/tools/apache-maven-3.9.9` + `/d/jdk1.8.0_25`;MySQL `192.168.16.251:3306` OPEN;前端 `node_modules` 存在。
|
|
|
|
|
+- `cfc-frontend` jest:**296/296 通过,14/14 suites,exit 0(~21s)**——与 §4 完全一致,无回归。
|
|
|
|
|
+- `cfc-backend` `mvn -o -DskipTests=false -Dtest='!TestRoles' test`:**MVN_EXIT=1,testCompile FAILURE,0/1474 @Test 执行(3m44s)**。
|
|
|
|
|
+ - 7 处编译错误全部位于 `CfBalanceControllerTest.java`:行 95/113/121/140(调 `balance`)、169/189/202(调 `logs`)。
|
|
|
|
|
+ - javac:`balance` 需要 `Long`(1 参)但找到 `long, <nulltype>`(2 参);`logs` 需要 `Long,Integer,Integer`(3 参)但找到 `long,<nulltype>,int,int`(4 参)。
|
|
|
|
|
+
|
|
|
|
|
+### 15.2 根因(git 真理核验)
|
|
|
|
|
+- 引入回归的提交:**`44b2f0d42` chore(sync): 工作区遗留未提交 WIP 收尾同步(2026-11-05 00:31:53)**。
|
|
|
|
|
+- 该提交**重写** `CfBalanceController`:`balance`/`logs` 由 `dfc78e9d3` 的 `balance(userId, currentMemberId)` / `logs(userId, currentMemberId, page, size)` **改回 `userId`-only**(并删除 `stats(...)` / `familySummary(...)` 方法、`resolveMemberId(userId, currentMemberId)` → `resolveMemberId(userId)`)。控制器内 `currentMemberId` 计数现为 **0**。
|
|
|
|
|
+- 但测试 `CfBalanceControllerTest.java` 仍停在 **`c9f9ec948`**(上轮 P0 修复——给测试**加上** `currentMemberId` 实参):调用 `balance(7L, null)` / `logs(7L, null, 1, 20)` → 实参个数不符 → testCompile 失败。
|
|
|
|
|
+- 日志实证:`/d/cfc/.tdd/backend-run-20261105-0105.log`。
|
|
|
|
|
+- **结论**:`44b2f0d42` 在「WIP 收尾同步」时把控制器签名回退/改写,却未同步配套单测,导致整模块 1474 @Test 零执行。这是 **B-8(P0 编译回归)的再次触发**(方向相反:上轮控制器加参/测试未加;本次控制器去参/测试仍带参)。
|
|
|
|
|
+
|
|
|
|
|
+### 15.3 门禁结论(当前 main 状态)
|
|
|
|
|
+> **不通过(Blocked / 编译回归)**
|
|
|
|
|
+- ✅ 前端 296/296 全绿(稳定,无回归)。
|
|
|
|
|
+- ⛔ 后端 **新 P0 编译回归**(`44b2f0d42`)→ 0/1474 执行,较 §6 基线(实跑 1528/1404 通过)严重倒退。
|
|
|
|
|
+- ⛔ cfc-web / cfc-langgraph / Playwright:严格标「未实测」(缺依赖 + 未授权联网)。
|
|
|
|
|
+- 历史结构性缺口仍在:覆盖率 ~10.6%、CI 未接入、执行回写空洞。
|
|
|
|
|
+
|
|
|
|
|
+### 15.4 阻塞处置与下一步
|
|
|
|
|
+- 已登记 **B-10(新 P0 研发类)** 于 `docs/tdd/test/blockers.md`,并将 B-8 状态由「已解除」更正为「`44b2f0d42` 重新引入(见 B-10)」。
|
|
|
|
|
+- 修复方案(交研发,二选一):① 改 `CfBalanceControllerTest` 7 处调用去掉 `currentMemberId` 实参(改为 `balance(7L)` / `logs(7L,1,20)`),匹配当前 `userId`-only 签名,并复核 `resolveMemberId(userId)` 语义;② 回退 `44b2f0d42` 对控制器的改写。修复须 `commit` + `push origin/cfclub` 方算送达(推送纪律)。
|
|
|
|
|
+- 后端编译恢复后,本自动化下一轮重跑 `mvn -o -DskipTests=false -Dtest='!TestRoles' test` 复验真实执行 + 真实缺陷 triage(ASSERT/NPE/分润缺口等历史 ~109 例信号)。
|
|
|
|
|
+
|
|
|
|
|
+**产出**:本台账(`docs/tdd/test/automation-run-2026-11-05-0105.md`,未提交未推送);本地日志与聚合 `_run35b_backend.log`、`_run35_agg.json`、`_run35_aggregate.py`、`_run35_backend.log`(首跑被中断的现场);上轮报告备份 `_surefire_backup_r34/`;本轮后端日志 `/d/cfc/.tdd/backend-run-20261105-0105.log`。
|