VS2015中GTest框架下new/delete代码行无法全覆盖问题求助
Google Test 动态分配代码覆盖率问题排查与解决
嘿,这个问题我太熟了!我之前在做Google Test单元测试的时候,也碰到过明明执行了new/delete,覆盖率工具却不认的情况,其实大多是编译器优化或者覆盖率统计的小细节没处理好。先结合你给出的DummyClass示例,咱们一步步来解决。
首先,先把你提到的类和可能出现问题的函数补全(我猜你的测试函数大概是这样的):
class DummyClass // fully covered { public: int x; DummyClass() { x = 5; }; // fully covered ~DummyClass() { }; // fully covered }; // 假设这是你测试的目标函数 void createAndDeleteDummy() { DummyClass* ptr = new DummyClass(); // 显示未覆盖? delete ptr; // 显示未覆盖? }
为什么会出现这种情况?
最常见的两个原因:
- 编译器优化:如果你的
DummyClass构造/析构逻辑太简单,且创建的对象没有被实际使用,编译器会认为这些new/delete操作没有副作用,直接把它们从编译后的代码中删掉——代码都被优化没了,覆盖率工具自然看不到执行痕迹。 - 覆盖率工具配置遗漏:比如用gcov/lcov时,不小心把包含
new/delete的源文件排除在了统计范围外。
具体解决方案
1. 强制关闭编译器优化
编译测试代码时,必须关闭所有优化(用-O0参数),这是最关键的一步。
- 如果用CMake管理项目,在CMakeLists.txt里添加:
# 关闭优化,保留调试信息,确保覆盖率统计准确 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
- 如果直接用g++编译:
g++ -O0 -g your_test.cpp -o your_test -lgtest -lgtest_main -pthread
2. 给动态对象添加实际使用逻辑
如果编译器觉得new出来的对象完全没被用到,还是会优化掉相关代码。可以简单使用一下对象的成员变量,让编译器认为这个对象是有意义的:
void createAndDeleteDummy() { DummyClass* ptr = new DummyClass(); // 新增一行,实际使用对象的成员,避免被优化 [[maybe_unused]] int temp = ptr->x; delete ptr; }
这里用[[maybe_unused]]是为了避免编译器报“变量未使用”的警告,同时保留使用逻辑。
3. 检查覆盖率工具的配置
如果你用lcov生成报告,确保没有误删自己的源文件统计数据:
# 捕获覆盖率数据 lcov --capture --directory . --output-file coverage.info # 只排除系统头文件,不要删除自己的代码 lcov --remove coverage.info '/usr/*' --output-file coverage_cleaned.info # 生成HTML报告 genhtml coverage_cleaned.info --output-directory coverage_report
执行完这些步骤后,打开coverage_report/index.html,应该就能看到new和delete的行被标记为已覆盖了。
内容的提问来源于stack exchange,提问作者Bardak
相关产品推荐
相关产品推荐

