一键导入
unit-test-cplusplus-generate-run
单测生成流水线的生成-运行阶段:基于 `test_cases.json` 基线,为 C++ 源文件分批派发 `cpp-test-gen-agent` 子 agent 并行生成测试、编译、采集覆盖率,最后汇总结果回写基线。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
单测生成流水线的生成-运行阶段:基于 `test_cases.json` 基线,为 C++ 源文件分批派发 `cpp-test-gen-agent` 子 agent 并行生成测试、编译、采集覆盖率,最后汇总结果回写基线。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | unit-test-cplusplus-generate-run |
| description | 单测生成流水线的生成-运行阶段:基于 `test_cases.json` 基线,为 C++ 源文件分批派发 `cpp-test-gen-agent` 子 agent 并行生成测试、编译、采集覆盖率,最后汇总结果回写基线。 |
基于 unit-test-gen-init 产出的 test_cases.json 基线,把仓库里的 C++ 待测文件按函数数贪心打包成批次,派发 cpp-test-gen-agent 子 agent 并行生成测试代码、编译、运行、采集覆盖率,最后把结果回写到 test_cases.json,并产出全局汇总。
本 skill 只处理 C++。Python 测试生成走独立的 skill。
本 skill 走"脚本化"路线:所有机械数据处理由 scripts/ 下的 Python 脚本完成,Claude 主要负责:
Claude 本身不构造大段 JSON、不解析 test_cases.json、不做 LPT 打包算法、不做 atomic write。这些都在脚本里。脚本接口契约见 scripts/README.md。
unit-test-gen-init 已成功跑过,test/generated_unit/test_cases.json 存在且 languages 里含 "cpp".claude/agents/cpp-test-gen-agent.md 必须存在python3 scripts/check_env.py --auto-install-gcovr
拿 stdout 的 JSON。如果 all_ok: true,进入下一步。
如果 all_ok: false,读 missing 数组和 install_hints,向用户展示缺失工具和安装命令。
然后终止。保留 stdout 拿到的 tools 字段,后续步骤 7 要用它做 tool_status。
用 bash 检查 <repo_root>/CMakeLists.txt:
test -f <repo_root>/CMakeLists.txt && echo exists || echo missing
存在:跳到步骤 3。
不存在:用 AskUserQuestion 询问:
"仓库根没有 CMakeLists.txt。本 skill 需要它来探测 include 路径和 C++ 标准。请选择:"["让 skill 自动生成一个最小化 CMakeLists.txt", "终止,我去手动准备 CMakeLists.txt 后再跑"]"缺少 CMakeLists"让 skill 自动生成一个最小化 CMakeLists.txt: 则由你(claude)生成一个CMakeLists.txt. 选"终止":打印"请准备好 CMakeLists.txt 后重新执行本 skill",退出。
检查是否已存在且新鲜(mtime 在 24h 内):
find <repo_root>/build/compile_commands.json -mtime -1 2>/dev/null
有输出(存在且新鲜):跳到步骤 4。
无输出:跑 cmake configure:
cmake -S <repo_root> -B <repo_root>/build \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_BUILD_TYPE=Debug
只 configure,不 cmake --build。失败时展示 cmake 输出末 30 行,提示用户"仓库 CMake 配置自身有问题,请先让 cmake -S . -B build 在仓库里跑通",终止。
最后(无论新生成还是复用已有):将 compile_commands.json 拷贝到 .test/ 作为调试记录:
cp <repo_root>/build/compile_commands.json .test/compile_commands.json
python3 scripts/build_build_context.py \
--repo-root <repo_root> \
--compile-commands build/compile_commands.json \
--output .test/build_context.json
退出码 0:进入步骤 5。
退出码 3(抽不到 cxx_standard):直接默认使用 17 作为 C++ 标准版本,带参数重跑脚本:
python3 scripts/build_build_context.py \
--repo-root <repo_root> \
--compile-commands build/compile_commands.json \
--output .test/build_context.json \
--cxx-standard 17
其他退出码:展示 stderr,终止。
一个脚本完成,自动从基线读取 coverage_config.exclude_dirs:
python3 scripts/pack_batches.py \
--baseline test/generated_unit/test_cases.json \
--output .test/batches.json
退出码 0:读 stdout 的 agent_count 和 batch_count,告诉用户:"将生成 <agent_count> 个 sub-agent,分 <batch_count> 批并发运行,每批 3 个"。
退出码 3:告知"过滤后没有可处理的 C++ 文件",结束。
读 .test/batches.json 的 batch_count 后,循环处理每个 batch(batch_id 从 0 到 batch_count - 1)。
对每个 batch:
6a. 为本批每个 agent 生成 input JSON
for agent_id in 0 1 2; do
python3 scripts/build_agent_input.py \
--baseline test/generated_unit/test_cases.json \
--batches .test/batches.json \
--batch-id <batch_id> \
--agent-id $agent_id \
--repo-root <repo_root_abs> \
--build-context-path .test/build_context.json \
--scripts-dir <scripts_dir_abs> \
--output-dir .test/ 2>/dev/null || true
done
收集 stdout 打印的 input JSON 绝对路径(每次成功调用打印一个路径)。最后一批可能不足 3 个,脚本遇到越界 agent_id 退出码 2 即跳过。
6b. 并发派发 sub-agent
对本批收集到的每个 input JSON 路径,在同一条回复里并列用 Agent 工具启动 sub-agent,subagent_type 为 cpp-test-gen-agent,提示词模板:
读取
<input JSON 绝对路径>,按其 JSON 内容中定义的任务执行。
等待本批所有 sub-agent 全部完成后再进行下一步。
6c. 汇报本批进度
ls .test/*/run_result.json 2>/dev/null | wc -l
打印给用户:"批次 <batch_id + 1>/<batch_count> 完成,累计 run_result: <count> 个"。
硬性约束:
7a. 收集所有 run_result
python3 scripts/collect_results.py \
--batches .test/batches.json \
--output .test/all_results.json
读 stdout 的统计。如果有缺失 run_result,记下供后续报告提到。
7b. 把步骤 1 的 tool_status 落盘
Claude 用 bash heredoc 把步骤 1 保存的 tools 字段写入文件:
cat > .test/tool_status.json <<'EOF'
<粘贴步骤 1 拿到的 tools JSON>
EOF
7c. 回写 test_cases.json
python3 scripts/writeback_baseline.py \
--baseline test/generated_unit/test_cases.json \
--results .test/all_results.json \
--tool-status .test/tool_status.json
读 stdout 拿"更新了 N 个文件、M 个函数、写入 K 个 cases"。
7d. 生成 summary.json 和 summary.md
这步 Claude 亲自做(无专用脚本):
.test/all_results.json,统计各 status 计数、算平均覆盖率.test/summary.json(机器可读):
{
"generated_at": "<ISO 时间>",
"total_files": N,
"status_counts": {"success": ..., "coverage_not_met": ..., "source_bug": ..., ...},
"coverage_summary": {"line_avg": ..., "branch_avg": ..., "function_avg": ...},
"per_file": [ {"source_path": "...", "status": "...", "coverage": {...}, "run_result_path": "..."} ],
"skipped_dirs": [...],
"dead_code_found": N
}
.test/summary.md(人类可读),章节:
coverage_not_met 文件列表 + unmet_reasons)source_bug 文件列表 + error 描述)test_gen_failed 文件列表)dead_code_locations)summary.md 到 test/generated_unit/ 目录:cp .test/summary.md test/generated_unit/summary.md
向用户输出:
"C++ 单测生成完成".test/summary.md 的"概览"章节前 20 行贴出来(head -20)test/generated_unit/test_cases.json.test/summary.json.test/summary.mdstatus_counts 里 coverage_not_met / source_bug / test_gen_failed 任一 > 0,明确提示读 summary.md 相应章节.test/
├── build_context.json 步骤 4 产物
├── batches.json 步骤 5 产物
├── tool_status.json 步骤 7b 产物
├── all_results.json 步骤 7a 产物
├── summary.json 步骤 7d 产物
├── summary.md 步骤 7d 产物
├── cpp_gen_batch_0_agent_0/ 每个 sub-agent 一个工作目录
│ └── agent_input.json
├── core_parser_cpp/ 每个源文件一个工作目录
│ ├── input.json sub-agent 保存的 input 片段
│ ├── process.log sub-agent 过程日志
│ ├── run_result.json sub-agent 最终结果
│ └── build/ 编译产物
│ ├── CMakeLists.txt
│ ├── cmake_configure.log
│ ├── cmake_build.log
│ ├── test_run.log
│ ├── gcovr.log
│ ├── test_core_parser_cpp
│ ├── coverage.json
│ └── *.gcda / *.gcno
└── ...
所有辅助脚本的详细接口契约见 scripts/README.md。本 skill 用到的脚本一览:
| 步骤 | 脚本 | 作用 |
|---|---|---|
| 1 | check_env.py | 环境总检测,输出 tool_status |
| 2 | (bash 一行) | 仓库缺 CMakeLists 时生成最小化版本 |
| 3 | cmake 命令 | 生成 compile_commands.json |
| 4 | build_build_context.py | 生成 build_context.json(含 cxx_standard 抽取) |
| 5 | pack_batches.py | 筛选 + LPT 贪心打包 |
| 6 | build_agent_input.py | 为指定 batch/agent 生成 input JSON + 并发派发 |
| 7a | collect_results.py | 聚合所有 run_result |
| 7c | writeback_baseline.py | 回写 test_cases.json + tool_status |
| 7d | (Claude 亲自) | 生成 summary.json / summary.md |
查任一 run_result.json 的 error 字段(通常指向具体缺失组件)。补装后重跑 —— 步骤 1 的 check_env.py 会再次检测。
可能原因:
source_bug / test_gen_failed / coverage_not_met —— 查 summary.mdskipped_functions 里 —— 查该文件的 run_result.jsoncoverage_config.exclude_dirs 排除)步骤 3 的 cmake configure 失败通常源于仓库自身 CMake 有问题。本 skill 不修复 —— 请先让 cmake -S . -B build 在仓库里手动跑通再重跑。
长时间不返回(> 10 分钟无新输出)可能是某函数让 LLM 陷入生成死循环。临时方案:重新运行 unit-test-gen-init 将该文件所在目录加入 exclude_dirs;根本方案:检查该文件是否异常(超大模板、宏爆炸)。
| 项 | 默认值 | 备注 |
|---|---|---|
| 每批并发 sub-agent 数 | 3 | 不暴露参数 |
| 单 sub-agent 最大文件数 | 10 | 硬上限 |
| 打包算法 | LPT 贪心(按函数数) | 不按文件夹 |
| 覆盖率迭代上限 | 2(由 sub-agent 实施) | 见 SUBAGENT.md |
| 处理范围 | 基线中所有 C++ 文件 - exclude_dirs | 全量重跑 |
| 基线回写字段 | files[*].functions[*].cases + tool_status | 其余不动 |
| compile_commands.json 缓存 | mtime < 24h 视为新鲜 | 过期重生成 |