logo
0
0
WeChat Login

PR #3:Q2-001 功能测试补齐 + B 层棘轮第 2 次上调(36/46 → 78/70)#3

Merged
created 2 weeks ago
main
feature/functional-tests
Edit
OverviewCommits
3
Files changed
14
Attachments

动机(Why)

按源仓库 anta-workshopdemo 方向 F 指令,关闭 CHECKPOINT §五 T-Q2-a 待办——功能测试补齐

本 PR 让 B 层 CI 棘轮第 2 次上调(首次 PR #2 激活 36/46;本次跃升到 78/70)——跨越 42/24 个百分点。这不是因为"写了很多代码",而是因为测试层次升级(unit-only → unit+functional)。棘轮记录的不是代码质量,是测试对代码行为的覆盖广度

同时首次将 testing-standards §3.1(禁 H2)+ §3.2 方案 A(显式 compose)落地——docker-compose.test.yml 启动真实 PostgreSQL,按 LESSONS B12 禁止 UI 推断数值,按 §1.3.1 阈值首次激活 5 步流程。

变更清单(What)

3 个 commits 分层推进

  • commit 1 test(functional) dc9d409:功能测试 + 5 个真实 bug 修正(8 文件 / +381 行)
  • commit 2 feat(ci) 2f042ab:CI 升级 14→15 stages + 棘轮阈值上调(5 文件 / +206/-26 行)
  • commit 3 docs(meta) 28ea564:CHECKPOINT §四 轮次 3 档案(1 文件 / +85/-12 行)

改动 1:功能测试基础设施(commit 1)

  • 新增 docker-compose.test.yml(项目根):PostgreSQL 15-alpine + tmpfs + 5433 端口避让 + healthcheck
  • 重写 backend/src/test/resources/application-test.yml:从"排除 DataSource"改为"连真实 PG" + Flyway enabled + 环境变量注入
  • 新增 backend/src/test/java/.../functional/AbstractFunctionalTest.java:按 functional-testing.md §3.3 方案 A 骨架
  • 新增 backend/src/test/java/.../functional/ReqQ2001ArticleCrudTest.java11 个用例覆盖 AC-1~AC-8 全部 P0 + 3 个补充边界

改动 2:修 5 个真实 bug(功能测试暴露的,单元测试架构上不可能暴露)

#Bug根因修正
1create 返回 VO 的 createdAt/updatedAt 为 nulluseGeneratedKeys 只回填主键不回填 DB DEFAULTinsert 后再 selectById 回查
2update 同样问题——返回 updatedAt 不是 DB 刷新后值同上updateById 后再 selectById
3PSQLException: Cannot convert TIMESTAMPTZ to LocalDateTimeFlyway 列类型与 Entity 不匹配迁移脚本 TIMESTAMPTZ → TIMESTAMP
4非法 JSON 返回 500 而非 400GlobalExceptionHandler 未处理 HttpMessageNotReadableException新增 @ExceptionHandler 返回 400 + 40001
5ArticleServiceImplTest 单元测试受 create/update 回查影响需补 mockServiceImpl 新增第二次 selectById 调用CreateTests/UpdateTests 补 given(selectById).willReturn(...)

改动 3:CI 流水线升级 14→15 stages(commit 2)

  • 新增 scripts/ci/backend/check-backend-functional.sh:独立 stage 跑功能测试;Docker 探测 + 幂等跳过
  • scripts/ci/backend/check-backend-test.shmvn testmvn -Dtest='...unit.**' test 只跑单元层
  • 重写 scripts/ci/backend/check-backend-coverage.sh:从 unit-only → unit+functional 合并度量;需 Docker 启动 compose
  • backend/pom.xmljacoco.line.min 0.36→0.78;jacoco.branch.min 0.46→0.70
  • .cnb.yml:push + MR 两段对称新增 biz-backend-functional stage(maven + services:[docker])+ biz-backend-coverage 加 services:[docker]

改动 4:CHECKPOINT 档案(commit 3)

  • §一 last-update + B 层指标表全面升级(B2' 新增功能测试行 + 覆盖率棘轮演进子表)
  • §三 PR 总览新增 #3
  • §四 完整"轮次 3"档案:5 bug 表格 + 5 条学到的东西 + §七 指标变化
  • §五 关闭 T-Q2-a/b/c(其中 b/c 由源仓库 PR #43 闭环)+ 新增 T-Q2-d/e

验证证据(How verified)

本地 15/15 CI stages 全绿 + 0 lint

真实测试运行

  • mvn -B test:Tests run: 26(unit 15 + functional 11), Failures: 0, Errors: 0
  • mvn -B verify:BUILD SUCCESS
  • check-backend-coverage.sh 实测:
    行覆盖: 79%  保底: 78%
    分支覆盖: 71%  保底: 70%
    [OK] 后端覆盖率棘轮达标
    

棘轮实测证据链(两次激活对比)

阶段测试范围LINEBRANCH阈值
PR #2 首次unit only36.45%46.43%36/46
PR #3 第 2 次unit + functional79.82%71.43%78/70
变化+functional+43 pct+25 pct+42/+24

遵循 testing-standards §1.3.1 阈值首次激活流程

  1. 跑真实测试 ✅
  2. 从 JaCoCo CSV 读机器可读数据:awk -F, 'NR>1 { lm+=$8; lc+=$9 } END { printf "%.4f", lc/(lm+lc) }' → 0.7982
  3. 手动交叉验证:91/114 = 0.7982 ✓
  4. 向下取整 + 1% 余量:设 78/70
  5. 守门员实测:[OK]

yml 对称verify-yml-consistency.sh push/MR 两段 81 行完全一致

影响面(Impact)

CI 流水线结构升级

  • 14 stages → 15 stages(B 层从 5 → 6)
  • biz-backend-functional 作为独立 stage 关注功能测试本身绿否
  • biz-backend-coverage 覆盖度量升级为 unit + functional 两层合并
  • 远端 CI 预估时间 +60s(新 stage 耗时 ~20s,coverage 扩展 ~40s)

测试金字塔首次在本项目完整落地

  • 单元层:15 用例(Mockito 隔离,不连 DB)
  • 功能层:11 用例(MockMvc 全链路 + 真实 PG)
  • 集成层:未建立(可作为 T-Q3 候选)
  • E2E 层:前端未建立(T-Q2-d 候选)

关闭的待办

  • ✅ T-Q2-a 功能测试补齐(本 PR)
  • ✅ T-Q2-b scaffold SKILL.md 摩擦反馈(源仓库 PR #43 闭环)
  • ✅ T-Q2-c 回写源仓库 Q2-001 经验(源仓库 PR #43 闭环)

新增候选待办

  • T-Q2-d:前端 E2E 测试(Playwright)——覆盖剩余 82% 前端代码
  • T-Q2-e:回写源仓库 5 个 bug 类型经验(Mockito 单元测试盲区),docker-compose.test.yml 模式作为 testing-standards §3.2 补强

本轮最深刻的 insight(入 CHECKPOINT 轮次 3 学到的东西):

"覆盖率 100% 的单元测试 ≠ 代码正确"

本 PR 修的 5 个 bug 中有 3 个(#1/#2/#3)是 Mockito 单元测试架构上根本不可能暴露的——因为 mock 隔离掉了数据库真实行为。这证明 testing-standards §1.1 测试金字塔分层设计的必要性不是纸面约定。单元测试是必要但远不充分

本 PR 不动的事

  • 前端功能测试 / E2E 测试:不在本 PR 范围(T-Q2-d 候选)
  • 集成测试层:不在本 PR 范围
  • 源仓库的新经验回写:不在本 PR 范围(T-Q2-e 候选)

Refs

  • 父事件:源仓库方向 F 指令——功能测试补齐关闭 T-Q2-a 待办
  • 关联:
    • docs/requirements/Q2-001.md §六 AC-1~AC-8
    • 源仓库 testing-standards.md §1.3.1(阈值首次激活)+ §3.1(禁 H2)+ §3.2 方案 A(显式 compose)
    • 源仓库 LESSONS.md §二 B12(禁 UI 推断数值)
    • 源仓库 rules/git-conventions.md §四(PR body 规范)
    • CHECKPOINT §四 轮次 3 完整档案
  • 远端 CI 验证:合并后由 CNB cnb-* 构建输出 15 stages 结果
is using the merge method to merge into8fcc707b
added 3 commits
合并来自 feature/functional-tests 的合并请求 #3
docs(meta): CHECKPOINT §四 轮次 3.1 追加——CNB dind 修复档案同步
fix(ci): 修复 CNB dind 静默跳过——functional/coverage 真实跑通
fix(ci): 根据 PR #5 诊断结果修复——回滚 image 语法 + 脚本安装 docker CLI

Successfully merged and closed

branch can be safely deleted
Reviewer
None yet
Assignee
None yet
Label
None yet
Participant