用预编译googletest 1.14.0,配置头文件与静态库路径,编写含initgoogletest和run_all_tests的main,编译加-std=c++17;assert_eq用于前置条件失败即终止,expect_eq用于多独立断言;避免hack私有成员,优先测试接口行为;注意ci中gtest_filter转义、death_test_style适配及-g调试信息。

用 GoogleTest 写第一个测试,5 分钟跑起来
别从零搭环境——GoogleTest 是 C++ 事实标准,Windows/macOS/Linux 都能直接编译,不用动系统级配置。重点不是“学框架”,而是让第一行断言通过。
- 下载预编译的
googletest-release-1.14.0(别用 main 分支,CI 不稳定) - 把
googletest/include加进编译器-I路径,libgtest.a或gtest.lib加进链接路径 - 写个
main.cpp:只包含#include <gtest></gtest>和int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } - 编译时加
-std=c++17(GoogleTest1.14 要求最低 C++14,但某些断言在 C++17 下行为更一致)
常见错误:undefined reference to testing::UnitTest::GetInstance() —— 多半是没链接 libgtest,或用了静态库却忘了加 -static-libstdc++(Windows MinGW 场景)。
ASSERT_EQ 和 EXPECT_EQ 到底该用哪个
它们不是“严格/宽松”之分,而是“是否继续执行当前测试函数”的开关。选错会导致后续逻辑被跳过,掩盖真正问题。
-
ASSERT_EQ:失败就立刻return,适合检查前置条件(比如指针非空、容器 size > 0) -
EXPECT_EQ:失败只记日志,继续往下跑,适合验证多个独立输出(比如结构体里 a/b/c 三个字段) - 别在循环里无脑用
ASSERT_EQ:一次失败就停,你根本看不到后面几轮的结果 - 错误现象:
Test case 'FooTest.Bar' did not check any assertions—— 意味着你写了ASSERT但没走到那行(比如提前return或异常抛出)
测试私有成员或未导出函数,别 hack
C++ 没有“测试专用访问权限”。强行 friend 或宏定义 #define private public 看似快,实则让测试和实现细节强耦合,重构时全崩。
立即学习“C++免费学习笔记(深入)”;
- 优先测接口行为:比如类
Parser的parse()返回值、抛出异常类型、修改了传入的std::vector<token>&</token> - 真要覆盖内部逻辑?把关键算法抽成独立
inline函数,头文件里声明,测试直接调用 - Windows DLL 场景下,如果函数没加
__declspec(dllexport),测试工程根本链接不到 —— 别试图用GetProcAddress,那是运行时黑盒,不是单元测试 - 性能影响:过度暴露内部状态会抑制内联,
GoogleTest的断言宏本身有轻微开销,但远小于错误设计带来的维护成本
CI 里跑不起来?先看 gtest_filter 和 gtest_death_test_style
本地能过、CI 报 Segmentation fault (core dumped),八成是死亡测试(ASSERT_DEATH)没配对,或者过滤规则写错了。
-
--gtest_filter=MyTest.*:星号必须转义为\*(bash)或*(Windows cmd),否则 shell 先展开成文件名 - 死亡测试默认用
fork,但 Alpine Linux(Docker 默认镜像)不支持 —— 改用--gtest_death_test_style=threadsafe - MacOS 上
ASSERT_DEATH可能卡住:因为fork后子进程继承了主线程锁状态,加--gtest_break_on_failure容易暴露死锁点 - 兼容性坑:
GoogleTest1.13+ 默认启用threadsafe,但旧项目升级后没改 CI 参数,就会莫名失败
最常被忽略的是:测试二进制文件本身没加 -g 编译,GoogleTest 的堆栈回溯为空,你只能看到 [ FAILED ] MyTest.CrashTest (0 ms) —— 连哪行崩的都不知道。










