docs(测试说明): 按用途分六个子目录并同步全库引用

分层:流程与规范/ 单元测试/ 板级测试/ 专项验证/ 测试工具/ 测试数据/,
顶层只留新增的目录导航 README.md(归层判据 + 硬约束 + 本次处置记录)。

- 搬迁 28 个路径:测试数据三个目录 58 个文件为纯改名(R100,内容逐字节不变)
- 全库引用同步 124 个文件:AGENTS / docs 索引 / skills / 门禁注释 / scripts
- 门禁面:scripts/check_test_traceability.py 的 glob 改 rglob
  (分层后不递归扫描=追溯门禁直接瞎掉)
- scripts/rename_ref.py:收尾的 ℹ 提示在 GBK 代码页抛 UnicodeEncodeError,
  让进程以退出码 1 收场而改写其实已落盘(RC 与真实结果相反);改为把
  stdout/stderr reconfigure 成 UTF-8,与 check_doc_links.py 等同法
- docs/文档规范.md §1.1 补「子目录文件过多时再分一层」;§3.6 补 rename_ref
  搬整目录的两个实测坑:① 会改写目录内部文件的内容 ② 内部文件的 ../ 出链
  不补层级(本次 23 个被误改的证据文件已按 HEAD 原始字节逐字节还原)
- docs/README.md §6 改为与六个子目录一一对应,并补登原先漏登记的
  「启动日志原子性复验流程」一行
- .cubemx_survival_baseline.json:App/util/task_watchdog.c 的注释路径也随分层更新,
  该文件是存活审计的 watchdog-module 漂移锚点,按脚本自己的提示跑 --write 重建基线
  (实测重建后仅 watchdog-module 一条哈希变化)
- 铁律 4 例外(本次在任务树里改了单写者文件):AGENTS.md 与
  .pre-commit-config.yaml 只被 rename_ref 改写路径字面量(后者全在注释行),
  任务表块与钩子声明一字未动

验证:check_doc_links.py --sections-strict 覆盖全部 88 个改动 .md 全绿;
check_test_traceability.py 输出与主树逐行一致;196 个文本文件无 BOM、无新增
CR、无 U+FFFD、无行尾空白;陈旧引用面由主树 25 处降到 6 处(无新增断链)。
This commit is contained in:
2026-10-30 07:06:38 +08:00
parent fea4cc7502
commit f754d59218
209 changed files with 644 additions and 528 deletions
+7 -7
View File
@@ -24,7 +24,7 @@ r"""
- **Windows 原生侧没有 gcc / clang / gcov / lcov / gcovr**(全盘扫 0 处)→ gcov 那条最主流的路在
Windows 侧走不通。**但 WSL2 Ubuntu 里有 gcc/gcov 15.2.0**,实测 16 套单测在 gcc 下全部编过、
gcov -b -c 还给出分支覆盖——不用它当默认是因为**换编译器=换分母**(sha256.c:gcc 105 行 vs
MSVC 114 行),详见 docs/测试说明/主机单测覆盖率口径.md §2.1 的决策记录。
MSVC 114 行),详见 docs/测试说明/单元测试/主机单测覆盖率口径.md §2.1 的决策记录。
- **MSVC 14.51(VS 2026/18)已不认 /coverage**:cl 只报 warning D9002「忽略未知选项」,
然后**照常编译成功** → 拿它做覆盖率等于静默出假数据,绝不可用(/fsanitize=coverage 同)。
- Team Tools\Dynamic Code Coverage Tools\CodeCoverage.exe(17.0)还在但已 deprecated,
@@ -34,7 +34,7 @@ r"""
MSVC 原生 exe + PDB,且**子进程退出码原样透传**(实测子进程 return 3 → collect 也返回 3)。
- 结论:编译期插桩这条路在本机是断的,走**加载期动态插桩**(mscoverage collect)。
口径(一句话版,完整版见 docs/测试说明/主机单测覆盖率口径.md):
口径(一句话版,完整版见 docs/测试说明/单元测试/主机单测覆盖率口径.md):
行覆盖 = 至少执行过一次的可执行行 / 被插桩的可执行行;
函数覆盖 = 至少有一行命中的函数 / 被插桩的函数;
统计面 = 自研生产源码(App/**、Drivers/BSP/** 的 .c/.h),**不含**测试单元自身、
@@ -73,7 +73,7 @@ r"""
- **PDB 里的源路径大小写会漂**(盘符、VS 根),比对前先按仓库实际拼写归一,否则同一文件
在基线里裂成两份。
设计依据:docs/测试说明/主机单测覆盖率口径.md
设计依据:docs/测试说明/单元测试/主机单测覆盖率口径.md
创建日期:2026-10-23
"""
@@ -440,7 +440,7 @@ def write_baseline(path, modules, files, totals, tested_sources, untested):
payload = {
"schema": BASELINE_SCHEMA,
"generated_by": "scripts/check_test_coverage.py --update-baseline",
"note": "主机单测覆盖率基线。口径与工具链限制见 docs/测试说明/主机单测覆盖率口径.md。"
"note": "主机单测覆盖率基线。口径与工具链限制见 docs/测试说明/单元测试/主机单测覆盖率口径.md。"
"门禁判据:files[].lines_covered 与 funcs_covered 只增不减,下降即拦提交。",
"totals": totals,
"modules": modules,
@@ -523,7 +523,7 @@ def diff_baseline(baseline, modules, files, totals, full_run):
# --------------------------------------------------------------------------
def print_report(modules, files, totals, untested, generated, notes, regress, verbose):
print("=== 主机单测覆盖率(口径:docs/测试说明/主机单测覆盖率口径.md)===")
print("=== 主机单测覆盖率(口径:docs/测试说明/单元测试/主机单测覆盖率口径.md)===")
print("")
print("--- 各套单测(插桩运行)---")
for name in sorted(modules):
@@ -584,7 +584,7 @@ def write_markdown(path, modules, files, totals, untested, notes, regress):
"# 主机单测覆盖率报告",
"",
"> 由 " + code("scripts/check_test_coverage.py") + " 生成;口径、工具链限制与盲区见 "
+ code("docs/测试说明/主机单测覆盖率口径.md") + "。本报告是一次性快照,重跑即覆盖。",
+ code("docs/测试说明/单元测试/主机单测覆盖率口径.md") + "。本报告是一次性快照,重跑即覆盖。",
"",
"## 总计",
"",
@@ -689,7 +689,7 @@ def run(args):
# 中间产物根:**跟着工作树走**,与主机单测同一个家(task-10)。旧写法是
# tempfile.gettempdir()/dtu_test_cov —— 全机一个名字,多棵工作树并行跑覆盖率就
# 互相覆盖 exe/PDB/cov 文件(docs/测试说明/主机单测覆盖率口径.md 里"并行期每人
# 互相覆盖 exe/PDB/cov 文件(docs/测试说明/单元测试/主机单测覆盖率口径.md 里"并行期每人
# 只跑 --module 自己模块"那条规避,就是为了绕开它;分家之后不再需要)。
# 复用 harness 的同一套判据(含 DTU_HOST_BUILD 覆盖),避免两处口径漂移。
_host_build_root = getattr(harness, "host_build_root", None)