C/C++代码中如何重置gcov累计覆盖率统计数据
googletest单用例精准gcov覆盖率统计实现
按顺序执行指定测试用例的命令行参数
- 固定执行顺序:添加启动参数
--gtest_shuffle=false,测试用例将严格按照代码内注册的先后顺序执行,该配置为googletest默认配置,无需额外添加即可生效 - 执行单个指定用例:添加启动参数
--gtest_filter=<测试套件名>.<测试用例名>,运行时将仅执行匹配到的目标测试用例 - 批量按自定义顺序执行:可逐次启动测试二进制,每次传入单个用例的filter参数,从进程层面完全隔离不同用例的覆盖率数据,是兼容性最高的统计方案
代码内重置gcov统计数据的实现方案
gcov运行时原生提供代码层面的计数重置、数据落盘接口,完全可以实现单测试用例粒度的覆盖率数据拆分,无需拆分执行进程。
具体实现步骤:
- 提前声明gcov运行时的内部接口,无需引入额外头文件:
// GCC编译场景:将当前累计的覆盖率计数写入.gcda文件 extern "C" void __gcov_flush(void); // GCC编译场景:清空内存中所有已累计的覆盖率计数,重置为初始0状态 extern "C" void __gcov_reset(void);
GCC 9及以上版本中
__gcov_flush()已更名为__gcov_dump(),接口功能完全兼容;若使用Clang + llvm-cov链路,对应接口为__llvm_profile_write_file()(落盘)、__llvm_profile_reset_counters()(重置)。
- 对接googletest全局事件监听器,实现用例级自动处理:
- 自定义类继承
testing::EmptyTestEventListener - 重写
OnTestEnd回调方法,该方法会在每一个测试用例执行完毕后被googletest框架自动调用 - 回调内首先调用落盘接口,将当前用例产生的覆盖率数据写入.gcda文件,随后将生成的.gcda文件重命名/备份为「测试套件名_测试用例名」格式的独立文件,避免后续被覆盖
- 最后调用重置接口清空内存中累计的所有覆盖率计数,保证下一个测试用例启动统计时初始状态为0
- 自定义类继承
- 编译注意事项:测试二进制编译时必须添加
-fprofile-arcs -ftest-coverage编译参数开启gcov插桩,不要添加会修改代码流、合并计数的过度优化参数,否则会导致统计结果偏差。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

