|
|
@@ -0,0 +1,338 @@
|
|
|
+# 测试负责人工作汇报 R218(2026-11-15 15:20 GMT+8 · 自动化闭环)
|
|
|
+
|
|
|
+> 测试负责人:陆谨(软件测试专家团 · 测试架构师)|执行档:**review(离线白名单)+ 内网浏览器 E2E(实跑)+ 远程节点派发(251 langgraph / 189 admin)**|静默无人值守
|
|
|
+> 基线:`origin/cfclub` **`a917efe1d`**(隔离 worktree `test-lead-R218`)→ 全量跑测期间远端续推 4 提交 → rebase 至 **`4dbf17808`** 做**定向复验**
|
|
|
+> **本轮头条:① 后端全量首次在本轮**干净环境实跑(53:44 / 503 类 / 4393 例 / 89.96%),非契约确定性红 **16 例零漂移(第 34 次)**;② **新增 P0:`CoachRecommendService` @Resource 撞名**(S-cfc-351 新代码,守卫实测 1 处,R203 同类阻断复发);③ **新增 P1 计费:支付开关配置缺失仍成功下单**(131400 分订单实测生成);④ **线上后端瞬时 502 窗口**致 3 例假红,复跑全绿;⑤ **Playwright 双版本冲突**使 `npx playwright test` 报「No tests found」(工具坑,已定位正确入口);⑥ 浏览器 E2E 实测 **33 过 + 2 跳**(本机 28 + 189 admin 5),langgraph@251 **40/43**(3 红全 429 配额);⑦ 窗口 4 提交定向复验 → `S-cfc-372` **8 例红转绿**
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 0. 历史审查记录(对照,非本次结论依据)
|
|
|
+
|
|
|
+| 项 | 内容 |
|
|
|
+|---|---|
|
|
|
+| 上次审查 | **R217(2026-11-15 13:40)**,结论「不通过(有条件)」;该轮因本沙箱无 Chromium / 9000 CLOSED / 无 DB **大量承采 R216**,后端未实跑 |
|
|
|
+| 本次 | **第 218 轮,非首次审查** |
|
|
|
+| 历史遗留 → 本次状态 | **B-217-1 后端须全量重跑** → ✅ **本轮已实跑闭环**(503 类 / 4393 例,53:44)<br>**B-216-1 cfc-web S1-1 10 红** → 承袭(逐例零漂移,`Families.vue` 仍未精简)<br>**B-216-3 langgraph 上游 429** → 承袭(3 红,红集缩小:5→3)<br>**B-208-1 189 DNS→公网** → **改善**(189 实测 admin=302 / api=200 → admin E2E 5/5 绿,观察 2/2)<br>**B-213-3 CI 清单失真** → 恶化(漏拦 67→**70**,陈旧 26 不变)<br>**B-203-1/2 @Resource 撞名** → 原 2 处已修,但**新增 1 处**(B-218-1)<br>**B-36 本机 9082 未起** → 第 95 轮<br>**B-DX-1 dx 2 跳(404)** → 第 52 轮 |
|
|
|
+| 本次新增 | **B-218-1(P0 Bean 撞名)· B-218-2(P1 支付开关)· B-218-3(P1 线上瞬时 502)· B-218-4(P2 Playwright 双版本)· B-218-5(P3 jest shim)· B-218-6(P1 窗口并发推进)· B-218-7(P2 度量口径)· B-218-8(P2 后端耗时)· B-218-9(P1 leaderboard 契约)· B-218-10(P2 lg 不退出)** |
|
|
|
+
|
|
|
+> 历史记忆只作对照:本轮**全部套件为重新取证**(后端全量 / 浏览器 E2E / langgraph / web+fe Jest / 根级 / 台账 / 覆盖率扫描),无承采项。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 执行总览
|
|
|
+
|
|
|
+| 套件 | R218(本轮实跑) | R217(上轮) | 漂移 |
|
|
|
+|---|---|---|---|
|
|
|
+| 基线 | `a917efe1d`(worktree)→ 收尾 `4dbf17808` | 本机 `0472da119` | 窗口 +4 提交(1 src) |
|
|
|
+| 后端 · 全量 | **503 类 / 4393 例 / 3952 过 / 427F+10E=437 红 / 4 跳 = 89.96%**(剔 skip **90.05%**);**53:44** | 承采 R216(501/4342/89.86%) | **首次干净实跑** |
|
|
|
+| 后端 · 定向复验(`4dbf17808`) | **24 例 / 16 过 / 8 红**(`AssessmentResultView` 6/6 绿、`History` 6/6 绿、`DanAssessmentResultRecord` 3/3 绿、`GrowthLeaderboardView` 7/8 红、`BeanCollisionGuard` 1/1 红) | — | **S-cfc-372 8 例转绿** |
|
|
|
+| 浏览器 E2E · admin(本机) | **5/5**(2.3m) | 承采 | 实跑 |
|
|
|
+| 浏览器 E2E · admin(189 节点) | **5/5**(1.2m,HEAD 同线) | 承采 | **实跑**(B-208-1 改善) |
|
|
|
+| 浏览器 E2E · frontend(本机) | **6/6**(1.3m) | 承采 | 实跑 |
|
|
|
+| 浏览器 E2E · shop-api | **4/4**(9.1s;首跑 2 红=**瞬时 502**,复跑全绿) | 承采 4/4 | 实跑(B-218-3) |
|
|
|
+| 浏览器 E2E · health | **13/13**(10.5s,匿名全 401/403) | 承采 13/13 | 实跑 |
|
|
|
+| 浏览器 E2E · dx-bridge | **2 跳**(两端点 404) | 承采 2 跳 | 第 52 轮 |
|
|
|
+| langgraph@251 | **43 例 / 40 过 / 3 红 / 206.09s**(`EXIT=124` 进程不退出) | 承采 38/5 | **改善 5→3 红** |
|
|
|
+| cfc-web Jest | **124 过 / 10 红 / 134**(21 套) | 124/10/134 | **逐例零漂移** |
|
|
|
+| cfc-frontend Jest | **644 过 / 4 红 / 12 跳 / 660**(46 套) | 644/4/12/660 | **逐例零漂移** |
|
|
|
+| 根级黑盒 Jest | **7 过 / 16 红 / 23**(全 ECONNREFUSED 9082) | 承采 7/16 | B-36 第 95 轮 |
|
|
|
+
|
|
|
+**覆盖台账(本轮 discover + inventory 实跑刷新)**
|
|
|
+- 控制器 **373**|handler 方法 **2026(覆盖 557 = 27.5%)**|测试文件 **510(@Test 4377,部分 4)**
|
|
|
+- 结构化用例 **947** + Playwright **571** + Python **48** + Java@Test **4377** + 场景文件 **11** = **5943**
|
|
|
+- TC 台账:唯一 TC id **383** / 表行 **958**;SC id(API_REFERENCE 去重)**139**,user-scenarios 引用 **139/139 = 100%**,test-cases 显式引用 **81/139 = 58.3%**
|
|
|
+
|
|
|
+**全站合计(本轮实测口径)**:后端 4393 + web 134 + fe 660 + 根级 23 + 浏览器 37 + langgraph 43 = **5290 例 / 4811 过 / 447 红 / 20 跳**(剔 skip 91.34%;**剔 420 契约前瞻 + 4 fe + 10 web 预期红 = 99.15%**)
|
|
|
+
|
|
|
+**测试结果有变化(R217 → R218)**
|
|
|
+- 🟢 **S-cfc-372 契约转绿**:`AssessmentResultViewContractTest` 4F→0、`AssessmentResultViewHistoryContractTest` 4F→0(合计 8 例),实现随 `6b38cc4e2` 落地。
|
|
|
+- 🔴 **新增 P0**:`CoachRecommendService.dimensionScoreService` @Resource 撞名(守卫 1/1 红,运行期 `BeanNotOfRequiredTypeException` 风险)。
|
|
|
+- 🔴 **新增 P1**:`MembershipPaySwitchTest` 支付开关配置缺失仍创建真实订单(131400 分)。
|
|
|
+- ⚪ 其余逐例零漂移(后端确定性 16 例、web 10 例、fe 4 例、根级 16 例、lg 红集为 429 环境型)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 项目画像(本轮视角)
|
|
|
+
|
|
|
+- **业务定位**:家庭教育 SaaS(五维能量 · 成长规划 · 测评订单 · 商城 · 健康报告解析 · 家庭工作台 · AI 教练),双端(小程序 H5 `cfc.iwintrue.com/frontend` + Web 管理端 `cfc.iwintrue.com/admin`)。
|
|
|
+- **技术栈**:Spring Boot 2.7.18 / Java 8 / MyBatis-Plus(9082)· uni-app Vue2(H5)· Vue2+Element(8082)· FastAPI+LangGraph(9000/生产 `ai.etotem.com.cn`)· JDK1.8.0_25 + Maven 3.9.9。
|
|
|
+- **节点探活(15:15)**:本机 hosts → **251**(admin 302 / api 200);**189** ✅ 4090=200(站点 302 / api 200);**251** ✅ 4096=200(opencode)/ **9000 CLOSED**(B-55 延续,lg 走 pytest 不依赖 HTTP);**204** 4091=200(OpenCode UI,非 H5,B-213-2)。
|
|
|
+- **通道**:fetch=SSH 失效 → 全程 HTTP `http://git.iwintrue.com/liaoxg/cfc.git`(承 B-203-3)。
|
|
|
+- **风险点**:① 69 个契约类前瞻(420 例);② Bean 撞名类运行时阻断(P0);③ 支付开关语义缺陷(P1 资金相关);④ 线上后端瞬时 502(抽测窗口内 2 分钟不可用);⑤ CI 排除清单与实测严重脱节(漏拦 70)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 20 类测试覆盖矩阵
|
|
|
+
|
|
|
+| # | 测试类型 | 层次 | 状态 | 证据(本轮实测) |
|
|
|
+|---|---|---|---|---|
|
|
|
+| 1 | 单元测试 | 功能层次 | **已发现** | 后端 **503 类 / 4393 例全量实跑**(510 测试源,@Test 4377)+ cfc-web 21 套 134 例 + fe 46 套 660 例 |
|
|
|
+| 2 | 组件测试 | 功能层次 | **已发现** | `cfc-web/src/__tests__/components/*`、`cfc-web/src/views/admin/review/__tests__/`、fe `__tests__/components/*` |
|
|
|
+| 3 | 集成测试 | 功能层次 | **已发现** | `integration/**` 全量参与;`EnergySystemFlowTest` 6F、`GuideModuleIntegrationTest` 1E 实跑红(确定性存量) |
|
|
|
+| 4 | 契约测试 | 功能层次 | **已发现(红集主体)** | **69 个 `*Contract*` 类 / 420 例**红(契约前瞻);窗口 `S-cfc-372` 8 例转绿、`S-be-2/S-be-6`(review.detail/my)仍红;cfc-web S1-1 3 spec / 10 例 TDD-RED |
|
|
|
+| 5 | 接口 API 测试 | 功能层次 | **已发现** | 线上 `POST /api/product/list` 排序契约 4/4(asc 2,2,2,9900… / desc 59900,50000…);health 13/13 全 401/403;匿名探针实测 |
|
|
|
+| 6 | 系统/端到端 | 功能保障 | **已发现(实跑)** | **33 过 + 2 跳**:本机 admin 5/5(2.3m)、fe 6/6(1.3m)、shop 4/4、health 13/13、dx 2 跳;**189 admin 5/5(1.2m)** |
|
|
|
+| 7 | 验收 UAT | 功能保障 | **部分已发现** | 场景文件 11 份有资产,仍无人工 UAT 签署记录 |
|
|
|
+| 8 | BDD 规格 | 功能保障 | **未发现** | 仓库无 `.feature` / cucumber → 缺口 |
|
|
|
+| 9 | 冒烟测试 | 功能保障 | **已发现** | `tests/e2e-live/*.spec.js` 5+6 例可作端到端冒烟;`tests/playwright.config.smoke.js` 存在 |
|
|
|
+| 10 | 回归测试 | 功能保障 | **已发现** | 后端全量 4393 例基线 + web/fe Jest 逐例比对(10+4 预期红零漂移)+ 确定性 16 例第 34 次零漂移 |
|
|
|
+| 11 | 探索性测试 | 功能保障 | **未发现** | 无人值守窗口不做 chartered 探索(受「不提问」约束) |
|
|
|
+| 12 | 性能测试 | 非功能 | **未发现(未实测)** | 无 k6/JMeter;execute 档未授权 → 不写通过 |
|
|
|
+| 13 | 可靠性测试 | 非功能 | **部分已发现** | 实测捕获**线上瞬时 502 窗口**(B-218-3)+ lg 429 降级(3 红);无故障注入 |
|
|
|
+| 14 | 安全测试 | 非功能 | **部分已发现** | 匿名端点 health 13/13 全 401/403、shop 非法排序列被白名单拦截(TC-S-U04 96ms 不 5xx);无 SAST/依赖扫描(离线档) |
|
|
|
+| 15 | 兼容性测试 | 非功能 | **部分已发现** | Chromium 双视口(1440×900 / 375×812 isMobile);无多浏览器矩阵 |
|
|
|
+| 16 | 可用性测试 | 非功能 | **未发现** | 无 SUS / 任务完成率记录 |
|
|
|
+| 17 | 无障碍测试 | 非功能 | **未发现** | 无 axe / WCAG 扫描 |
|
|
|
+| 18 | 覆盖率(行/分支) | 度量与流程 | **部分已发现** | JaCoCo 未开;替代口径 handler 覆盖 **557/2026 = 27.5%** |
|
|
|
+| 19 | 变异测试 | 度量与流程 | **未发现** | 无 PIT / Stryker |
|
|
|
+| 20 | 全项目代码审查 | 度量与流程 | **已发现** | 本轮定位 **2 处运行期/语义缺陷**(Bean 撞名、支付开关)+ 3 处工具链缺陷(Playwright 双版本、jest shim、lg 不退出);`@GetMapping` 计数 8 处遗留 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. 测试方案(本轮实际执行)
|
|
|
+
|
|
|
+- **目标**:① 后端**全量实跑**拿权威分母(替代 R217 承采);② 浏览器 E2E 在**本机 + 189**双节点实跑(每节点单任务、串行);③ langgraph pytest **派发 251**;④ web/fe/根级 Jest 实跑比对漂移;⑤ 窗口 4 提交**定向复验**;⑥ 覆盖台账与覆盖率扫描刷新;⑦ 感知 SRS/场景变更(G12)。
|
|
|
+- **范围**:全 20 类。**排除**:性能压测(execute 档未授权)、多浏览器矩阵、探索性测试、变异测试(无资产)。
|
|
|
+- **执行档**:**review(离线白名单)**;联网仅用于站点/节点探活与既有 E2E/pytest(内网)。
|
|
|
+- **验收标准**:G1 ≥95%(剔 skip)、G2 实红 0(剔预期红契约)、G4 编译 0 错、G5 逐类 XML、G6 浏览器全绿、G13 存量零漂移。
|
|
|
+- **隔离**:后端全量在 `git worktree .worktrees/test-lead-R218`(绕开主工作区 24 个未提交文件污染),`-Dmaven.repo.local` 未另设(单批次独占)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 执行档与授权
|
|
|
+
|
|
|
+| 项 | 内容 |
|
|
|
+|---|---|
|
|
|
+| 执行档 | **review(离线白名单)** |
|
|
|
+| 联网范围 | 内网站点探活与既有 E2E(cfc.iwintrue.com → 251)、节点派发(189:4090 / 251:4096) |
|
|
|
+| 授权 | 自动化无人值守按既定范围执行;**未授权**公网压测、依赖漏洞扫描、渗透测试、生产写数据 |
|
|
|
+| 未实测项 | 性能/可靠性(故障注入)、DAST/依赖漏洞扫描、多浏览器矩阵、无障碍、可用性、变异测试、UAT 签署 → **均降级为测试设计/缺口诊断,不写成通过** |
|
|
|
+| 降级说明 | 上述 6 类在报告中统一标注「未实测」,不计入通过率分子/分母 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 覆盖缺口清单
|
|
|
+
|
|
|
+| 缺口类型 | 现状 | 风险 | 建议测试设计 | 优先级 | 闭环方式 |
|
|
|
+|---|---|---|---|---|---|
|
|
|
+| **Bean 撞名阻断(B-218-1)** | `CoachRecommendService` 1 处 `@Resource` 撞名,守卫 1/1 红 | 运行期 `BeanNotOfRequiredTypeException` 阻断上下文;若该 Bean 在启动链则整站不可用 | 字段改名/显式 `@Resource(name=...)`;守卫纳入 CI blocking | **P0** | 修后守卫 + 全量定向复跑绿 → 销号 |
|
|
|
+| **支付开关失效(B-218-2)** | 配置缺失仍创建真实订单(131400 分,`ORD17947262779410059F5D`) | 资金/订单脏数据;开关策略形同虚设 | Mockito 注入空配置 → 断言 `null` 且**无订单落库**;补 `PaymentService` 路由分支用例 | **P1** | 修后 `MembershipPaySwitchTest` 6/6 绿 → 销号 |
|
|
|
+| **线上瞬时 502(B-218-3)** | 15:26~15:27 约 2 分钟 `/api/**`=502、251:9082 refused;造成 shop U01/U02、dx U02 超时假红 | 抽测期假红污染结论;用户侧可用性事件 | E2E 前置探活(`/api/product/list` 200 才跑)+ 失败自动重试 1 次 + 采集 nginx/后端日志 | **P1** | 加探活/重试 + 运维给出 502 根因 → 销号 |
|
|
|
+| **Playwright 双版本(B-218-4)** | root `@playwright/test@1.63.0` vs `tests/node_modules@1.61.1` → `npx playwright test` 报 `test.describe() called here` + `No tests found`(0 例) | 极易被误读为「用例丢失/全绿」 | 统一版本或用 `node tests/node_modules/@playwright/test/cli.js`;加 `--list` 例数守卫 | P2 | 版本对齐 + 例数守卫上线 → 销号 |
|
|
|
+| **jest shim(B-218-5)** | `cfc-frontend/node_modules/.bin/jest` 为 POSIX shim,`node .bin/jest` 报 `SyntaxError: missing )` | 前端套件启动失败被误判「无测试」 | 统一用 `node node_modules/jest/bin/jest.js`;文档固化 | P3 | 入口固定 → 销号 |
|
|
|
+| **窗口并发推进(B-218-6)** | 全量跑测期间远端续推 4 提交(含 `6b38cc4e2` src) | 全量数字落后于 HEAD | 提交前 + 推送前**双 fetch**,并对 `src/**` 命中类定向复跑(本轮已做,8 例转绿) | P1 | 形成惯例并写入报告附录 → 持续 |
|
|
|
+| **leaderboard 契约仍红(B-218-9)** | `GrowthLeaderboardViewContractTest` 8 例 / 7 红;研发 `2c66c9302` 只改断言未落地实现 | 榜单能力不可用 | 实现 `growth.leaderboard.view`(排序/分页/越权)后复跑 | P1 | 定向复跑 8/8 绿 → 销号 |
|
|
|
+| **langgraph 429(B-216-3)** | 3 红(auto_tag 2 / intent 1)根因 `AgnesAI free rate limit` | 上游配额限制,红集不可判定 | 运维换 key/升配额;测试侧 stub 脱环境留 1 条 live smoke | P1 | 连续 2 轮全绿 → 销号 |
|
|
|
+| **lg 进程不退出(B-218-10)** | `EXIT=124`(900s timeout 杀),日志 206.09s 已有完整 summary | 无法以退出码判定结果,易漏读 | pytest 加 `-p no:cacheprovider` + `os._exit`;或改 `--timeout` + 结果文件判据 | P2 | 退出码稳定为 0/1 → 销号 |
|
|
|
+| **度量口径漂移(B-218-7)** | G14 分母 152(承袭)vs 本轮 API_REFERENCE 去重 139 | 跨轮数字不可比,易误判改善/恶化 | 固化口径脚本(含分母来源)随报告落库 | P2 | 脚本入库 → 销号 |
|
|
|
+| **后端耗时(B-218-8)** | 全量 53:44;`ActivityControllerTest` 410.9s / `HealthDimensionControllerTest` 289.6s / `GuidePackageServiceTest` 135.0s = 15.8 分钟(**29%**) | 反馈环过长,改一行等一小时 | 拆分/精简慢类(去 Spring 上下文重试)、并行 fork=2 | P2 | 全量降到 <35 分钟 → 销号 |
|
|
|
+| **CI 清单失真(B-213-3)** | 漏拦 **70** / 陈旧 **26** | 硬门禁必红 → 被无视(等同无门禁) | 由 surefire 红类自动生成 `BACKEND_OBSERVED_CLASSES` | P1 | 清单与实测对齐 → 销号 |
|
|
|
+| **S1-1 契约 10 例(B-216-1)** | cfc-web 3 spec 10 红,`Families.vue` 未精简 | 场景变更契约未落地 | 研发删死代码(`openPlanGen`/`proxyReportUpload`/plans·reports 弹窗) | P1 | cfc-web 复跑 134/134 → 销号 |
|
|
|
+| 契约前瞻 420 例 | 69 个契约类领先实现 | 契约增速 > 实现速度 | 契约批次 TDD(RED→GREEN)逐批闭环 | P1 | 定向复跑转绿 → 逐批销号 |
|
|
|
+| 覆盖率/变异/BDD/无障碍/可用性 | JaCoCo 未开、无 PIT、无 `.feature`、无 axe | 度量与行为规格缺自动保障 | 开 JaCoCo + PIT 抽样 + cucumber 冒烟 + axe | P3 | 测试侧排期立项 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 域结论表
|
|
|
+
|
|
|
+| 审查维度 | 负责专家 | 结论 | 关键证据 |
|
|
|
+|---|---|---|---|
|
|
|
+| 单元·组件级 | 苏雅 | ⚠️ 有条件通过 | 后端 503 类 / 4393 例 / 89.96%(剔 skip 90.05%);剔 420 契约红 = **99.54%**;web 124/134(10 S1-1 红);fe 644/660(4 预期红+12 跳) |
|
|
|
+| 集成·接口级 | 柯砚 | ✅ 通过(含 1 项 P1 缺口) | shop 排序 4/4(asc/desc 实测有序)、health 13/13 全 401/403、dx 2 跳;集成类 `EnergySystemFlow` 6F / `GuideModuleIntegration` 1E 存量红 |
|
|
|
+| 系统·验收级 | 白樾 | ✅ 通过 | 本机 admin 5/5 + fe 6/6 + 189 admin 5/5 = **33 过 + 2 跳**(双节点);UAT 无签署记录(缺口) |
|
|
|
+| 测试保障级 | 闻朔 | ⚠️ 有条件通过 | 全量 503/503 XML 无沉默;确定性 16 例第 34 次零漂移;窗口 4 提交定向复验 8 例转绿 |
|
|
|
+| 性能·可靠性 | 骆骋 | ⛔ 未实测(降级) | 无性能资产(execute 档未授权);可靠性侧写:实测 502 窗口 + 429 降级 |
|
|
|
+| 安全 | 关屿 | ⚠️ 有条件通过 | 匿名 13/13 = 401/403;非法排序列白名单拦截;无 SAST/依赖扫描 |
|
|
|
+| 兼容·体验 | 阮清 | ⚠️ 有条件通过 | 仅 Chromium 双视口;无 axe/多浏览器 |
|
|
|
+| 流程·度量·代码 | 何序 | ⛔ 不通过 | CI 漏拦 70 / 陈旧 26;Bean 撞名守卫红;度量口径未固化;3 处工具链缺陷 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 五要素问题清单
|
|
|
+
|
|
|
+1. **B-218-1 · P0 · `CoachRecommendService` @Resource 字段名撞名(R203 同类阻断复发)**
|
|
|
+ ① 问题描述:`CoachRecommendService.java:71-72` 声明 `@Resource private FamilyMemberDimensionBaseScoreService dimensionScoreService;`,字段名 `dimensionScoreService` 命中另一类型 `DimensionScoreService` 的默认 Bean 名;Spring `@Resource` **先按名解析**,命中且类型不可赋值 → 运行期 `BeanNotOfRequiredTypeException`,阻断所在上下文启动。守卫实测违规 **1 处**(原 B-203-1/2 两处已修)。
|
|
|
+ ② 测试 bug 点:`cfc-backend/src/test/java/com/etotem/cfc/unit/ResourceBeanNameCollisionGuardTest.java`(1/1 红,`resourceFieldNameMustNotCollideWithIncompatibleBeanName`);被测文件 `cfc-backend/src/main/java/com/etotem/cfc/service/CoachRecommendService.java:71`。
|
|
|
+ ③ 最优修改方案:字段改名为 `familyMemberDimensionBaseScoreService`,或显式 `@Resource(name = "familyMemberDimensionBaseScoreService")`;并把该守卫类纳入 CI blocking。
|
|
|
+ ④ 修改目的:消除运行期上下文启动阻断(AI 教练推荐链 + 任何加载该 Bean 的 `@SpringBootTest`)。
|
|
|
+ ⑤ 闭环:守卫 1/1 绿 + `mvn -o test -Dtest=CoachRecommendContractTest,ResourceBeanNameCollisionGuardTest` 全绿,并做一次启动冒烟(`/api/coach/recommend` 返回 200/业务码)→ 销号。
|
|
|
+
|
|
|
+2. **B-218-2 · P1 · 支付开关配置缺失仍创建真实订单**
|
|
|
+ ① 问题描述:`MembershipPaySwitchTest.createOrderWithPayType_virtualEnabled_configMissing_returnsNull` 实测 `expected: <null> but was: <{levelCode=FAMILY, amount=131400, orderNo=ORD17947262779410059F5D, payType=wechat, ... status=pending}>` —— 虚拟支付已开但**微信支付配置缺失**时,预期「不创建订单」,实际落了一笔 1314.00 元待支付订单。
|
|
|
+ ② 测试 bug 点:`cfc-backend/src/test/java/com/etotem/cfc/service/MembershipPaySwitchTest.java`(1F/6);同域 `PaymentServiceORDRoutingTest`(1F/3)同源。
|
|
|
+ ③ 最优修改方案:`MembershipOrderService.createOrderWithPayType` 在 `payType=wechat` 且 `wechatPayParams` 为空/配置缺失时**前置返回 null(不落库)**;对 `payType=virtual` 走独立分支;补「配置缺失→无订单落库」断言(校验 mapper 零写入)。
|
|
|
+ ④ 修改目的:资金路径安全(避免脏订单与对账失败),开关语义与实现一致。
|
|
|
+ ⑤ 闭环:`MembershipPaySwitchTest` 6/6 绿 + `PaymentServiceORDRoutingTest` 3/3 绿 + 定向复跑 → 销号。
|
|
|
+
|
|
|
+3. **B-218-3 · P1 · 线上后端瞬时不可用(502 / 9082 refused)导致假红**
|
|
|
+ ① 问题描述:15:26:30 起 `http://cfc.iwintrue.com/api/product/list` 连续返回 **502**,`192.168.16.251:9082` 连接被拒(`code=000`);约 2 分钟后自行恢复(15:28 起 200)。该窗口内 shop-api TC-S-U01/U02 各 30s 超时、dx TC-DX-U02 20s 超时 → **3 例假红**;15:30 复跑 **4/4 全绿**(266ms/118ms)。
|
|
|
+ ② 测试 bug 点:`tests/e2e-live/shop-sort-api.spec.js:23`(`request.post(... timeout:30000)`)、`tests/e2e-live/dx-health-bridge-auth.spec.js:36`(timeout 20000);首跑日志 `_r218_e2e_shop.log`、`_r218_e2e_dx.log`。
|
|
|
+ ③ 最优修改方案:① E2E `globalSetup` 或每 project 前加探活(`POST /api/product/list` 需 200 且 <2s);② 网络类失败自动重试 1 次并在报告中标记 `flaky(env)`;③ 向运维索取 15:26~15:28 的 nginx/后端日志定位(OOM?重启?端口漂移?)。
|
|
|
+ ④ 修改目的:消除环境噪声导致的假红,保证结论可判定;同时把可用性事件纳入可靠性观测。
|
|
|
+ ⑤ 闭环:连续 3 轮抽测无 502 且带探活守卫 → 销号;若再现则升级为可用性事故单。
|
|
|
+
|
|
|
+4. **B-218-4 · P2 · Playwright 双版本冲突使全部 E2E 报「No tests found」**
|
|
|
+ ① 问题描述:`npx playwright test -c tests/playwright.config.live.js` 直接失败:`Playwright Test did not expect test.describe() to be called here` + `Error: No tests found`(`Total: 0 tests in 0 files`);根因 root `@playwright/test@1.63.0` 与 `tests/node_modules/@playwright/test@1.61.1` 同时存在,spec 内 `require('@playwright/test')` 解析到 tests 侧(1.61.1),runner 在 root 侧(1.63.0)。
|
|
|
+ ② 测试 bug 点:`D:\cfc\tests\e2e-live\admin-live.spec.js:116`(describe 抛错点);入口命令 `_r218_e2e_admin.log` 首跑 0 例。
|
|
|
+ ③ 最优修改方案:统一版本(删 `tests/node_modules/@playwright/test` 或 root 升/降到 1.61.1 一致);短期固定入口 `node tests/node_modules/@playwright/test/cli.js test ...`;CI 加 `--list` 例数守卫(admin=5、fe=6、shop=4、dx=2)。
|
|
|
+ ④ 修改目的:防止「0 例被当成全绿」的假绿风险(与 B-39 同类)。
|
|
|
+ ⑤ 闭环:两种入口 `--list` 例数一致且实跑通过 → 销号。
|
|
|
+
|
|
|
+5. **B-218-5 · P3 · `cfc-frontend` jest 入口为 POSIX shim**
|
|
|
+ ① 问题描述:`node node_modules/.bin/jest` 报 `SyntaxError: missing ) after argument list`(`.bin/jest` 是 shell 脚本 `basedir=$(dirname ...)`),前端 660 例套件启动失败。
|
|
|
+ ② 测试 bug 点:`cfc-frontend/node_modules/.bin/jest:2`;日志 `_r218_jest_fe.log`(首次尝试)。
|
|
|
+ ③ 最优修改方案:统一用 `node node_modules/jest/bin/jest.js`(或在 `package.json` 用 `npm test`)。
|
|
|
+ ④ 修改目的:消除 Windows 下 shim 解析差异导致的「套件无输出」误判。
|
|
|
+ ⑤ 闭环:命令固化进报告附录 A + 连续一轮复跑成功 → 销号。
|
|
|
+
|
|
|
+6. **B-218-6 · P1 · 全量跑测窗口内远端持续推入提交**
|
|
|
+ ① 问题描述:全量启动时基线 `a917efe1d`,跑测期间远端续推 **4 提交**(`6b38cc4e2` src 3 文件 / `2c66c9302` 契约断言 / `27b68796e` bump / `4dbf17808` 汇报),全量数字落后于 HEAD。
|
|
|
+ ② 测试 bug 点:无代码 bug;证据链缺口——`_r218_backend.log`(基线)与 `_r218_targeted.log`(HEAD)需并列呈现。
|
|
|
+ ③ 最优修改方案:维持「提交前 + 推送前双 fetch」;凡 `src/**` 命中即对受影响类**定向复跑**(本轮已对 5 类 24 例复验)。
|
|
|
+ ④ 修改目的:报告数字与结论锚定到可复现的 commit,避免「按过期基线判绿/判红」。
|
|
|
+ ⑤ 闭环:本轮已闭环(全量基线 + HEAD 定向复验双证据)。
|
|
|
+
|
|
|
+7. **B-218-7 · P2 · 度量口径漂移(G14 分母不可比)**
|
|
|
+ ① 问题描述:R213/R216/R217 报「SC 引用 137/152 = 90.1%」,本轮按 `API_REFERENCE.md` 去重得 **139** 个 SC id(user-scenarios 覆盖 100%、test-cases 58.3%)——分母来源与口径未固化,跨轮不可比。
|
|
|
+ ② 测试 bug 点:度量脚本未入库(各轮临时命令),证据不可复现。
|
|
|
+ ③ 最优修改方案:把 SC/TC 口径脚本固化到 `tests/tools/metrics.py`,输出「分母来源 + 去重规则 + 双口径(场景层/用例层)」。
|
|
|
+ ④ 修改目的:使 G14 变化可解释(真实改善 vs 口径变化)。
|
|
|
+ ⑤ 闭环:脚本入库 + 连续两轮口径一致 → 销号。
|
|
|
+
|
|
|
+8. **B-218-8 · P2 · 后端全量耗时 53:44,慢类占 29%**
|
|
|
+ ① 问题描述:503 类全量 **53:44**;Top3 慢类 `ActivityControllerTest` **410.9s**、`HealthDimensionControllerTest` **289.6s**、`GuidePackageServiceTest` **135.0s**,合计 13.9 分钟;另有 `UserServiceFamilyNameLinkTest` 133.9s、`GuideApplicationServiceTest` 108.1s。
|
|
|
+ ② 测试 bug 点:上述 5 类(Spring 上下文反复重建 + 用例内重试);日志 `_r218_backend.log` 每类 elapsed。
|
|
|
+ ③ 最优修改方案:慢类拆分为纯 Mockito 单测 + 少量 `@SpringBootTest` 冒烟;surefire 开 `forkCount=2`(需评估 DB 隔离);对 400s 级类做用例级定位(单例耗时排序)。
|
|
|
+ ④ 修改目的:把反馈环从 54 分钟压到 <35 分钟,提升闭环频次。
|
|
|
+ ⑤ 闭环:连续两轮全量 <35 分钟且例数不减 → 销号。
|
|
|
+
|
|
|
+9. **B-218-9 · P1 · `growth.leaderboard.view` 契约仍 7 红(研发仅改断言)**
|
|
|
+ ① 问题描述:`2c66c9302` 声称「修正 RED 契约异常流断言」,但 `GrowthLeaderboardViewContractTest` 实测 **8 例 / 7 红**(HEAD `4dbf17808`),实现侧未落地。
|
|
|
+ ② 测试 bug 点:`cfc-backend/src/test/java/com/etotem/cfc/unit/GrowthLeaderboardViewContractTest.java`;定向日志 `_r218_targeted.log`。
|
|
|
+ ③ 最优修改方案:实现 `growth.leaderboard.view`(榜单排序/分页/范围越权校验),异常流返回统一 `Result` 业务码;测试侧复核断言是否覆盖「空榜/并列名次/越权」。
|
|
|
+ ④ 修改目的:消除「改断言代替改实现」的红转绿假象。
|
|
|
+ ⑤ 闭环:定向复跑 8/8 绿且断言含行为校验(非存在性反射)→ 销号。
|
|
|
+
|
|
|
+10. **B-218-10 · P2 · langgraph pytest 不退出(EXIT=124,第 21 轮)**
|
|
|
+ ① 问题描述:251 上 `timeout 900 .venv/bin/python -m pytest ...` 的日志 206.09s 已产出完整 summary(3 failed, 40 passed),但进程持续存活至 900s 被 `timeout` 杀掉 → `EXIT=124`。
|
|
|
+ ② 测试 bug 点:测试进程残留(`app/main.py:84` on_event 注册的 client 未关闭;`JavaClient._get_client` 协程未 await 的 RuntimeWarning 亦指向同一处)。
|
|
|
+ ③ 最优修改方案:收敛 `JavaClient` 生命周期(lifespan handler + 显式 close);pytest 加 `-p no:cacheprovider` 与 `--timeout=300`;结果判定改用 `--junitxml`。
|
|
|
+ ④ 修改目的:使 CI 可用退出码判定结果,避免靠读日志。
|
|
|
+ ⑤ 闭环:连续两轮 `EXIT=0/1` 且结果与 junitxml 一致 → 销号。
|
|
|
+
|
|
|
+**历史问题(B-216-1、B-216-3、B-213-3、B-36、B-DX-1、B-213-1)**:承袭,处置方案见 R216/R217 报告 §8;本轮仅更新状态(CI 漏拦 67→70、lg 红 5→3、B-208-1 改善待销号)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 门禁结论
|
|
|
+
|
|
|
+**⛔ 不通过** —— 存在 **1 项 P0(Bean 撞名运行期阻断)** 与 **3 项 P1(支付开关失效 / 线上瞬时 502 / leaderboard 契约未落地)**;后端剔预期红后达 99.54%,但**实红 17 例未清零**,且 CI 门禁与实测严重脱节。
|
|
|
+
|
|
|
+| 门禁 | R218 结果 | 判定 |
|
|
|
+|---|---|---|
|
|
|
+| G1 全量通过率 ≥95%(剔 skip) | **90.05%**;剔 420 契约前瞻 = **99.54%** | ❌(全量)/ ✅(剔预期红) |
|
|
|
+| G2 红例 0(剔预期红契约) | 实红 **17**(存量 16 第 34 次零漂移 + **新增守卫 1**) | ❌ |
|
|
|
+| G3 前端 Jest | fe **644/660**(4 预期红 + 12 跳);web **124/134**(10 S1-1 预期红);逐例零漂移 | ⚠️ 预期 RED |
|
|
|
+| G4 编译 0 错 | ✅ 2187 主源 + **510 测试源** 编译通过(全量可执行) | ✅ |
|
|
|
+| G5 逐类有 XML | ✅ **503/503**(无沉默类) | ✅ |
|
|
|
+| G6 浏览器 E2E | ✅ **33 过 + 2 跳**(本机 admin 5/5 · fe 6/6 · shop 4/4 · health 13/13;189 admin 5/5;dx 2 跳=第 52 轮) | ✅ |
|
|
|
+| G7 langgraph 通过率 | **40/43 = 93.0%**(3 红全 429 配额) | ⚠️ 环境型 |
|
|
|
+| G8 鉴权契约 | ✅ health 13/13 全 401/403;shop 非法排序列被拦截 | ✅ |
|
|
|
+| G9 覆盖率 | handler 覆盖 **557/2026 = 27.5%**(JaCoCo 未开) | ❌ |
|
|
|
+| G10 多节点互备 | ✅ 本机(admin 5/5 + fe 6/6)+ **189(admin 5/5)** + **251(lg 40/43)** | ✅ |
|
|
|
+| G11 CI | ❌ 漏拦 **70** / 陈旧 **26**(33 类清单与实测 77 类红严重脱节) | ❌ |
|
|
|
+| G12 SRS/场景变更 → 用例 | 窗口**零 SRS/API 文档变更**(仅 src 修复 + 汇报)→ 用例无需更新(已复核 API_REFERENCE / test-cases / user-scenarios 均未变) | ✅ |
|
|
|
+| G13 存量零漂移 | ✅ 确定性 16 例逐类逐例与 R213 **一致(第 34 次)**;web 10 / fe 4 / 根级 16 逐例一致;**新增 1 例守卫红为新增回归非漂移** | ✅(+1 新增) |
|
|
|
+| G14 场景映射 | 场景层 **139/139 = 100%**;用例层 test-cases **81/139 = 58.3%**(口径见 B-218-7) | ⚠️ 用例层不足 |
|
|
|
+
|
|
|
+**核心变化(R217 → R218)**
|
|
|
+1. **后端从「承采」转为「实跑」**:53:44 拿到 503 类 / 4393 例权威分母,使 G1/G2/G5 从「不可判定」变为可判定。
|
|
|
+2. **新增 2 个真实缺陷**(P0 Bean 撞名、P1 支付开关),均由本轮全量/守卫实测发现,非文档推演。
|
|
|
+3. **环境噪声被识别并隔离**:线上瞬时 502 造成 3 例假红,复跑全绿 → 报告按「假红(env)」分类,不计入实红。
|
|
|
+4. **工具链 3 处坑固化**:Playwright 双版本、jest POSIX shim、lg 不退出 → 已写入附录 A 的可复现命令。
|
|
|
+5. **正向进展**:`S-cfc-372` 8 例红转绿(定向复验证据);189 节点恢复(admin 5/5 连续 2 轮)。
|
|
|
+
|
|
|
+**复评条件**:B-218-1 修复且守卫绿 → B-218-2 支付开关 6/6 绿 → leaderboard 8/8 绿 → 实红降为 16 存量(存量类需研发逐类立项)→ CI 清单与实测对齐。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录 A · 本轮可复现命令(Windows / Git Bash)
|
|
|
+
|
|
|
+```bash
|
|
|
+# 0) 隔离工作区(绕开主工作区 24 个未提交文件)
|
|
|
+git worktree add .worktrees/test-lead-R218 -b test-lead-R218 <baseline>
|
|
|
+
|
|
|
+# 1) 后端全量(53:44)
|
|
|
+cd .worktrees/test-lead-R218/cfc-backend && mvn -o -B clean test
|
|
|
+
|
|
|
+# 2) 后端定向复验(窗口变更类)
|
|
|
+mvn -o -B test -Dtest='AssessmentResultViewContractTest,AssessmentResultViewHistoryContractTest,DanAssessmentResultRecordContractTest,GrowthLeaderboardViewContractTest,ResourceBeanNameCollisionGuardTest' -DfailIfNoTests=false
|
|
|
+
|
|
|
+# 3) 浏览器 E2E(本机,注意必须用 tests 内 CLI,勿用 npx —— B-218-4)
|
|
|
+node tests/node_modules/@playwright/test/cli.js test -c tests/playwright.config.live.js --project=admin-desktop
|
|
|
+node tests/node_modules/@playwright/test/cli.js test -c tests/playwright.config.live.js --project=frontend-mobile
|
|
|
+node tests/node_modules/@playwright/test/cli.js test -c tests/playwright.config.live.js --project=shop-api
|
|
|
+node tests/node_modules/@playwright/test/cli.js test -c tests/playwright.config.live.js --project=dx-bridge
|
|
|
+node tests/node_modules/@playwright/test/cli.js test -c tests/playwright.config.health.js
|
|
|
+
|
|
|
+# 4) 前端 Jest(fe 必须走 jest/bin/jest.js —— B-218-5)
|
|
|
+cd cfc-web && node node_modules/.bin/jest --ci
|
|
|
+cd cfc-frontend && node node_modules/jest/bin/jest.js --ci
|
|
|
+cd .. && npx jest -c tests/jest.config.js --ci # 根级黑盒(需本地 9082,B-36)
|
|
|
+
|
|
|
+# 5) langgraph(派发 251,不经本地)
|
|
|
+opencode 251 会话执行:
|
|
|
+ cd /sc-data/cfc/cfc-langgraph && timeout 900 .venv/bin/python -m pytest tests \
|
|
|
+ --ignore=tests/qna --ignore=tests/test_chat.py -q > /tmp/r218_lg.log 2>&1
|
|
|
+
|
|
|
+# 6) 台账刷新
|
|
|
+python <skill>/scripts/discover_tests.py --project .
|
|
|
+python <skill>/scripts/test_inventory.py --project .
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录 B · 红集与 CI 双向差集
|
|
|
+
|
|
|
+**后端红类 77(可执行 503 类中)**
|
|
|
+- **契约前瞻 69 类 / 420 例**(预期红,示例):`AICoachConsultContractTest`、`CoachRecommendContractTest`、`ProductReviewDetailContractTest`、`ProductReviewMyContractTest`、`GrowthLeaderboardViewContractTest`(7)、`AssessmentAppointment*ContractTest`、`Supplier*ContractTest`(6)、`Child*ContractTest`(11)、`Energy*ContractTest`(4)、`GlobalSearch*ContractTest`(3) 等
|
|
|
+- **非契约确定性红 9 类 / 17 例**:`EnergySystemFlowTest` 6F(HTTP 500)· `UserServiceWechatLoginTest` 3E(NPE)· `WebConfigGrowthExcludeRemovedTest` 2E(`Interceptor is required`)· `GuideModuleIntegrationTest` 1E(`platform_fee INT` 溢出,`schema.sql:2882` + 迁移 5901/6115)· `OrchestrationEngineTest` 1F(`manual_fail` 为 null)· `OrchestrationIntegrationTest` 1F · `MembershipPaySwitchTest` 1F(**B-218-2 新增定位**)· `PaymentServiceORDRoutingTest` 1F · **`ResourceBeanNameCollisionGuardTest` 1F(B-218-1 新增)**
|
|
|
+
|
|
|
+**CI 清单差集(`.gitlab-ci.yml#BACKEND_OBSERVED_CLASSES`,33 类)**
|
|
|
+- **漏拦 70 类**(实测红但不在排除清单 → 若执行 blocking 必红):69 个契约类 + `UserServiceWechatLoginTest`、`WebConfigGrowthExcludeRemovedTest`、`ResourceBeanNameCollisionGuardTest`
|
|
|
+- **陈旧 26 类**(在清单但实测全绿):`StatsControllerTest`、`GuideFamilyTaskControllerTest`(20/20)、`ProductOrderControllerTest`、`PaymentControllerTest`、`AuthControllerTest`、`ArticleControllerTest` 等
|
|
|
+- 结论:清单停留在「第 69 轮」快照,与当前 77 个红类严重脱节 → **G11 ❌**
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录 C · 度量口径(本轮显式声明)
|
|
|
+
|
|
|
+| 指标 | 本轮口径 | 数值 |
|
|
|
+|---|---|---|
|
|
|
+| 后端通过率 | 过 / (总 − skip) ,surefire XML 汇总 | 3952 / 4389 = **90.05%** |
|
|
|
+| 剔预期红通过率 | 过 / (总 − skip − 契约前瞻红) | 3952 / 3969 = **99.54%** |
|
|
|
+| handler 覆盖率 | discover_tests.py:被 ≥1 测试引用的 handler / 全部 handler | 557 / 2026 = **27.5%** |
|
|
|
+| 用例总量 | 结构化 md 947 + Playwright 571 + Python 48 + Java@Test 4377 + 场景 11 | **5943** |
|
|
|
+| TC 台账 | `tests/test-cases/*.md` 表格中含 `TC-*` 的唯一 id / 表行 | **383 / 958** |
|
|
|
+| SC 场景映射 | `API_REFERENCE.md` 去重 SC id 为分母;分别统计 user-scenarios 与 test-cases 引用 | 场景层 **139/139**;用例层 **81/139 = 58.3%** |
|
|
|
+| 浏览器口径 | live 配置 4 project(admin/fe/shop/dx)+ health 独立配置 | 本机 28 过 + 2 跳;+189 → **33 过 + 2 跳** |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 附录 D · 取证清单(文件级)
|
|
|
+
|
|
|
+| 套件 | 证据文件 |
|
|
|
+|---|---|
|
|
|
+| 后端全量 | `.worktrees/test-lead-R218/_r218_backend.log`、`cfc-backend/target/surefire-reports/*.xml`(503) |
|
|
|
+| 后端定向 | `.worktrees/test-lead-R218/_r218_targeted.log`(24 例 / 8 红) |
|
|
|
+| 本机 admin E2E | `_r218_e2e_admin.log`(5 passed 2.3m) |
|
|
|
+| 本机 fe E2E | `_r218_e2e_fe.log`(6 passed 1.3m) |
|
|
|
+| shop E2E | `_r218_e2e_shop.log`(2 failed 502 窗口)→ `_r218_e2e_shop2.log`(4 passed 9.1s) |
|
|
|
+| dx E2E | `_r218_e2e_dx.log`(1 failed timeout)→ `_r218_e2e_dx2.log`(2 skipped 404) |
|
|
|
+| health E2E | `_r218_e2e_health.log`(13 passed 10.5s) |
|
|
|
+| 189 admin E2E | `_r218_e2e189.log`(5 passed 1.2m) |
|
|
|
+| 251 langgraph | `_r218_lg_dispatch.log` + 251 `/tmp/r218_lg.log`(3 failed / 40 passed / 206.09s) |
|
|
|
+| web Jest | `_r218_jest_web.log`(124/10/134) |
|
|
|
+| fe Jest | `_r218_jest_fe.log`(644/4/12/660) |
|
|
|
+| 根级 Jest | 本会话输出(7/16/23,ECONNREFUSED 9082) |
|
|
|
+| 台账 | `docs/tdd/test/discovery.md`、`inventory.md`、`automation-status.md` |
|