From 77e38360a8d4413f9157beaf67189e7e45556f3d Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Wed, 4 Nov 2026 19:27:01 +0800 Subject: [PATCH] =?UTF-8?q?ci+docs:=20=E8=A6=86=E7=9B=96=E7=8E=87=E6=94=B9?= =?UTF-8?q?=E7=94=A8=20-coverpkg=3D./...=20=E2=80=94=E2=80=94=20=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E7=BB=9F=E8=AE=A1=E4=BC=9A=E6=BC=8F=E6=8E=89=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E6=B5=8B=E8=AF=95=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 缺陷(实测发现,且是**度量本身**在说谎) 加覆盖率采集之后,`internal/agent/core/child` 报告 0.0% —— 但刚给 它写了 9 条判据、覆盖 87.6%。 原因:`go test ./... -coverprofile` **只统计每个包内自测的覆盖**。 而覆盖 child 的测试在 `child/test/` —— 另一个包。主报告里只看到: internal/agent/core/child 0.0% ← 假的 internal/agent/core/child/test 87.6% ← 真的在覆盖 child ## 修法 go test ./... -coverpkg=./... -coverprofile=/tmp/cover.out 实测差异: child 0.0% → 85.7% 全局总覆盖率 56.9% → 63.0% 即**此前的数字是系统性低估的**。而低估比高估更危险 —— 它会促使人 "为凑覆盖率写空判据",那正是 engineering-lessons §1.1 记的坑。 代价:`-coverpkg=./...` 为每个测试二进制插桩全部包,跑得更慢 (实测仍在 20m 门内)。这个代价换"数字是真的",值得。 ## 文档补 §5.3.2 把这条写进 engineering-lessons,因为它是**判据分离的连带义务**: > 判据分离(§5.3)与覆盖率采集必须同时改。 > 只改前者,度量会退化成谎报。 否则下次有人把测试迁到 test/ 之后,会看到覆盖率"莫名其妙掉了", 进而怀疑分离本身,把它改回去。 ## 本提交同时包含 `internal/agent/core/child/test/registry_contract_test.go`(9 条判据) 已随上一个提交(8884cf9)入库 —— 那里和 io 的并发判据修复放在一起, 因为它们都是"判据自身的缺陷"这一主题。 --- .github/workflows/ci.yml | 15 +++++++++++++++ docs/zh/engineering-lessons.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e3ae5b2..4dda6ed8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -226,7 +226,22 @@ jobs: - name: 覆盖率(仅报告) run: | set -euo pipefail + # ★ 必须带 -coverpkg=./...(2026-11-04 实测发现漏统计)。 + # + # 不带它时,`go test ./... -coverprofile` **只统计每个包内自测的覆盖**。 + # 而本仓正在把判据迁到 `/test/` 外部包 —— 那样一来: + # + # internal/agent/core/child 显示 0.0% + # internal/agent/core/child/test 覆盖了它 87.6% + # + # 主报告里 child 是 0%,因为覆盖它的测试在**另一个包**里。 + # 实测:加 -coverpkg=./... 后 child 从 0.0% → 85.7%, + # 全局从 56.9% → 63.0%。即之前的数字是**低估**的。 + # + # 代价:-coverpkg=./... 会为每个测试二进制插桩全部包,跑得更慢 + # (实测 20m 门内仍有余量)。这个代价换"数字是真的",值得。 go test ./... -count=1 -timeout 20m \ + -coverpkg=./... \ -coverprofile=/tmp/cover.out -covermode=atomic > /tmp/cover.log 2>&1 || { echo "★ 覆盖率跑挂了(这条同时兜住了 go test 的失败)" tail -40 /tmp/cover.log diff --git a/docs/zh/engineering-lessons.md b/docs/zh/engineering-lessons.md index dbc8ff00..09ae9067 100644 --- a/docs/zh/engineering-lessons.md +++ b/docs/zh/engineering-lessons.md @@ -352,6 +352,34 @@ files, _ := filepath.Glob("*.go") // childkind_test.go 标准库符号。**正确做法是一次只迁一个,逐步看编译器报什么,手工修。** 慢,但不会留下半成品(agent/core 已因此完全回滚过一次)。 +### 5.3.2 覆盖率必须用 `-coverpkg=./...` + +把判据迁到 `/test/` 之后,**默认的覆盖率统计会把它们算丢**: + +```bash +go test ./... -coverprofile=cover.out +``` + +只统计"每个包内自测的覆盖"。而覆盖 `child` 的测试在 `child/test/` —— 另一个包。 +于是主报告里: + +```text +internal/agent/core/child 0.0% ← 假的 +internal/agent/core/child/test 87.6% ← 真的在覆盖 child +``` + +加 `-coverpkg=./...` 之后: + +```text +internal/agent/core/child 85.7% +全局 56.9% → 63.0% +``` + +**即此前的数字是系统性低估的。** 而低估比高估更危险 —— 它会促使人 +"为凑覆盖率写空判据",而那正是 §1.1 记的坑。 + +⇒ 判据分离(§5.3)与覆盖率采集必须同时改。只改前者,度量会退化成谎报。 + ### 5.4 CI 必须覆盖每个独立 module **实测缺口(2026-11-04)**:主仓有 `third_party/hologramagentsdk/`,