
从零构建 C 语言命令行项目的测试与覆盖率流水线cover-agent c_cli 模板测试样例实战【免费下载链接】cover-agentQodo-Cover: An AI-Powered Tool for Automated Test Generation and Code Coverage Enhancement! 项目地址: https://gitcode.com/GitHub_Trending/co/cover-agent本文基于 cover-agent 仓库中的 C 语言模板测试样例templated_tests/c_cli完整讲解一个命令行计算器项目的依赖准备、编译运行、Unity 单元测试编写、gcov/lcov 覆盖率采集全流程。读完后你可以复现该样例的编译 → 测试 → lcov 报告闭环并理解 cover-agent 如何以该项目为试验场自动提升代码覆盖率。样例定位cover-agent 的多语言模板测试之一cover-agent 为验证其在不同语言和环境下的测试生成能力内置了一系列模板测试项目。templated_tests/README.md 中的表格列出了全部 11 个样例其中c_cli对应 C 语言即本文主角。该样例同时被集成测试直接消费。tests_integration/scenarios.py 中定义了它的运行参数# C Calculator Example { docker_image: embeddeddevops/c_cli:latest, source_file_path: calc.c, test_file_path: test_calc.c, code_coverage_report_path: coverage_filtered.info, test_command: rsh build_and_test_with_coverage.sh, coverage_type: CoverageType.LCOV.value, max_iterations: 4, desired_coverage: 50, },从这份配置可以看出cover-agent 针对 C 场景使用 lcov 格式的覆盖率报告coverage_type为LCOV取值定义在 cover_agent/settings/config_schema.py一轮运行最多迭代 4 次目标覆盖率为 50%测试命令直接调用样例内的build_and_test_with_coverage.sh脚本。此外stored_responses/c_cli_responses_a8d19a85a2bf.yml 保存了该场景下 AI 调用的录制回放数据可用于离线复现生成过程。项目结构templated_tests/c_cli/ ├── Dockerfile # 一键构建含 Unity 的运行环境 ├── README.md # 本样例操作指南本文蓝本 ├── build_and_test_with_coverage.sh # 一键脚本生成 runner、编译、测试、出覆盖率 ├── calc.h # 核心函数声明 ├── calc.c # 核心计算实现 ├── main.c # 命令行入口 └── test_calc.c # 基于 Unity 的单元测试前置依赖根据 templated_tests/c_cli/README.md环境需要四类组件组件用途安装方式GCC编译计算器与测试程序并支持 gcov 插桩sudo apt-get install gccRuby运行 Unity 的测试 runner 生成脚本sudo apt-get install rubylcov采集并汇总覆盖率数据sudo apt-get install lcovlcov_cobertura将 lcov 报告转换为 Cobertura XML在 lcov 被原生支持之前作为中间格式pip install lcov_coberturaUnityC 语言单元测试框架ThrowTheSwitch/Unity从 Unity 官方仓库获取源码sudo apt-get update sudo apt-get install gcc ruby lcov pip install lcov_cobertura # 再获取 Unity 测试框架源码需包含 Unity/auto 与 Unity/src 目录仓库中的 Dockerfile 给出了完整的容器化做法基于python:3基础镜像安装curl unzip ruby lcov通过pip安装lcov_cobertura然后下载 Unity 的 master 压缩包并解压重命名为Unity目录最后把项目文件拷贝进容器。这就是embeddeddevops/c_cli:latest镜像的构建方式——如果你本地不装依赖直接用该镜像运行同样可行。计算器实现解析在跑测试之前先理解被测代码。核心逻辑只有一个函数声明在 calc.hdouble calculate(double op1, double op2, const char* operation, int* status); void print_usage();calc.c 中calculate()用strcmp依次匹配 6 种操作并通过status出参传递状态码操作行为状态码--add加法0成功--subtract减法0--multiply乘法0--divide除法op2 0时报除零错误1除零--modulus取模按整数运算除数为 0 时报错1除零--power幂运算调用pow()0其他未知操作2这个设计值得注意成功与两类失败都通过返回值区分正是这种多分支结构让覆盖率成为有意义的度量——每个else if分支和每个错误分支都需要对应的测试来覆盖。入口 main.c 负责命令行解析参数必须恰好 4 个否则打印用法并返回 1用atof()把操作数转为double结果打印时若为整数则用%d、否则用%f状态码 1/2 分别输出 Division by zero 和 Invalid operation 到 stderr 并以非零码退出。编译与运行编译被测程序README 中的命令gcc -o calculator main.c calc.c -lm-lm链接数学库因为calc.c调用了pow()。运行./calculator # 参数不足时输出 usage ./calculator --add 5 3 # 将 --add 5 3 替换为所需操作与操作数注意 usage 提示里的二进制名是calcprint_usage()打印的示例但编译产物名为calculator二者不影响实际运行以./calculator为准。用 Unity 编写单元测试test_calc.c 是 Unity 风格的测试目前只包含一个测试函数作为起始模板#include unity.h #include calc.h void test_Addition(void) { int status; double result calculate(5, 3, --add, status); TEST_ASSERT_EQUAL_INT(8, result); TEST_ASSERT_EQUAL_INT(0, status); }Unity 的约定是测试源文件中的每个test_前缀函数都会被 runner 调用。runner 不需要手写——Unity 自带 Ruby 脚本从测试文件中自动解析出测试列表并生成 main 函数ruby Unity/auto/generate_test_runner.rb test_calc.c test_calc_Runner.c这条命令读取test_calc.c生成test_calc_Runner.c其中包含测试注册、setUp/tearDown钩子调用与统计输出。这也解释了前置依赖中必须安装 Ruby 的原因。带覆盖率插桩的编译gcc -o calc_tests test_calc.c test_calc_Runner.c Unity/src/unity.c calc.c -lm -IUnity/src -fprofile-arcs -ftest-coverage各部分职责test_calc.ctest_calc_Runner.c测试用例与自动生成的 runnerUnity/src/unity.cUnity 框架实现与测试同进程编译calc.c被测源码必须一起编译否则 gcov 无法统计它的分支-IUnity/src让#include unity.h可被找到-fprofile-arcs -ftest-coverageGCC 的 gcov 插桩开关编译时插入执行计数运行时在当前目录生成.gcda计数数据文件-lm数学库。运行测试./calc_testslcov 覆盖率报告测试跑完后.gcda文件已就绪README 给出三步 lcov 流程# 1. 采集读取 .gcda/.gcno汇总成 coverage.info lcov --capture --directory . --output-file coverage.info # 2. 过滤剔除 Unity 框架代码与测试文件自身只保留被测代码 lcov --remove coverage.info */Unity/* */test_* --output-file coverage_filtered.info # 3. 查看按文件列出行/分支覆盖率 lcov --list coverage_filtered.info第 2 步的过滤是覆盖率数字不失真的关键——如果保留unity.c和test_calc.c的计数报告会被框架代码稀释。过滤产物coverage_filtered.info正是 tests_integration/scenarios.py 中code_coverage_report_path指向的文件即 cover-agent 读取的 lcov 报告。一键脚本build_and_test_with_coverage.shbuild_and_test_with_coverage.sh 把上述全部步骤串成一条流水线并额外完成 Cobertura 转换#!/bin/bash set -e # 任一步骤失败即终止 # 检查 ruby 与 gcc 是否存在 command -v ruby /dev/null 21 || { echo 2 Ruby is required...; exit 1; } command -v gcc /dev/null 21 || { echo 2 GCC is required...; exit 1; } ruby Unity/auto/generate_test_runner.rb test_calc.c test_calc_Runner.c gcc -o test_calc test_calc.c test_calc_Runner.c Unity/src/unity.c calc.c -lm -IUnity/src -fprofile-arcs -ftest-coverage ./test_calc lcov --capture --directory . --output-file coverage.info lcov --remove coverage.info */Unity/* */test_* --output-file coverage_filtered.info lcov --list coverage_filtered.info # 最后一步lcov → Cobertura XML lcov_cobertura coverage_filtered.info两个脚本与 README 命令的细节差异值得注意脚本编译的二进制名为test_calcREADME 中为calc_tests且脚本多执行了lcov_cobertura coverage_filtered.info产出 Cobertura 格式的coverage.xml作为 lcov 被 cover-agent 原生支持之前的过渡格式。脚本开头set -e加命令存在性检查保证任何一步失败都会以非零码退出——这正是 cover-agent 判断测试运行失败的信号随后它会分析失败原因并修正下一轮生成的测试。在 cover-agent 中的完整闭环把各部分串起来该样例在 cover-agent 工作流中的角色是容器内执行sh build_and_test_with_coverage.shscenarios.py 的test_command产出coverage_filtered.infocover-agent 以LCOV类型解析calc.c的未覆盖行与分支交给 AI 生成新测试追加到test_calc.c下一轮重新执行同一脚本验证新测试达到desired_coverage50% 或迭代满max_iterations4 轮后停止。现有test_calc.c只覆盖了--add一条路径calc.c的其余 5 个操作分支与 3 类错误分支都是天然的待补白——这正是该模板对 cover-agent 的价值起点低、分支清晰、反馈确定适合作为自动测试生成的基准场景。【免费下载链接】cover-agentQodo-Cover: An AI-Powered Tool for Automated Test Generation and Code Coverage Enhancement! 项目地址: https://gitcode.com/GitHub_Trending/co/cover-agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考