gtest测试用例必须用test宏定义,格式为test(测试套名, 用例名),二者均为合法c++标识符;断言根据是否需继续执行选expect_或assert_;测私有成员应抽离逻辑或用friend_test;链接需正确使用gtest_main或手动调initgoogletest。

gtest 测试用例必须写在 TEST 宏里,不是函数就能跑
直接写个普通函数,哪怕返回 void、参数为空,gtest 也完全看不到它。测试用例得用 TEST(或 TEST_F)宏包裹,否则编译通过但运行时零用例执行。
-
TEST后面跟两个标识符:测试套名(TestSuiteName)和用例名(TestCaseName),都必须是合法 C++ 标识符,不能含空格、斜杠、点号 - 名字不支持变量或宏拼接,比如
TEST(MySuite, "test-1")会编译失败——引号里的字符串不算标识符 - 同一个测试套名下可以有多个
TEST,它们彼此隔离,不会共享变量或状态
TEST(MathUtils, AddPositiveNumbers) {
EXPECT_EQ(5, add(2, 3));
}
<p>TEST(MathUtils, AddNegativeNumbers) {
EXPECT_EQ(-1, add(2, -3)); // 这是另一个独立用例
}</p>
断言用 EXPECT_* 还是 ASSERT_*?看是否允许后续逻辑继续执行
EXPECT_EQ 失败只记日志、标记该用例为失败,但测试函数还会往下走;ASSERT_EQ 一失败就直接 return,跳过后面所有语句。选错会导致误判或崩溃。
- 验证前置条件(如指针非空、文件已打开)用
ASSERT_*,避免后续空解引用 - 检查多个独立结果(比如循环中每个元素)必须用
EXPECT_*,否则第一个失败就停了,看不到其余问题 -
ASSERT_TRUE(ptr)比EXPECT_TRUE(ptr != nullptr)更简洁安全,且能触发早期退出
测试私有成员或未导出函数?别硬测,改接口或加 FRIEND_TEST
gtest 本身不提供反射或友元注入机制,试图在测试文件里 #include "class.h" 然后调 obj.private_method() 会编译失败——除非你主动开放。
- 最稳妥做法:把要测的逻辑抽成 public 或 protected 的小函数,测试其行为而非访问权限
- 若必须测私有方法,可在原类定义中加
FRIEND_TEST(TestSuiteName, TestCaseName);,注意名字必须和TEST宏里的一致 - 不要用
#define private public这类 hack:破坏封装、可能因编译器优化失效、CI 上行为不一致
链接 gtest 时提示 undefined reference 到 main 或 InitGoogleTest
常见于自己写了 main 函数却没调 InitGoogleTest,或者链接了 gtest 库但没链接 gtest_main。
- 如果没写自己的
main,直接链接gtest_main库(不是gtest),它自带标准入口 - 如果写了自定义
main,必须在int main(int argc, char** argv)开头调::testing::InitGoogleTest(&argc, argv); - CMake 中别漏掉
target_link_libraries(your_test gtest gtest_main),顺序不能反;用find_package(GTest REQUIRED)而非硬写路径 - 静态链接 gtest 时,确保编译选项(如
-std=c++17)与 gtest 编译时一致,否则 ABI 不兼容导致符号找不到
C++ 单元测试真正卡住人的地方,往往不是语法,而是测试边界没对齐——比如被测函数改了签名,测试里忘了同步更新 EXPECT_CALL 参数;或者 mock 对象生命周期比测试短,导致析构时访问野指针。这些细节不报编译错,只在运行时崩,得靠反复跑 + 日志定位。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











