用Google Test写C++单元测试的核心是写可测代码、用断言验证行为、自动化执行;推荐FetchContent拉取源码编译,用TEST宏定义测试用例,EXPECT_EQ等断言验证结果。

用 Google Test(gtest)为 C++ 项目写单元测试,核心是:写可测代码 + 用断言验证行为 + 自动化执行。不需要宏大的测试架构,从一个 .cpp 文件开始就能跑起来。
一、快速搭建 gtest 环境(以 CMake 项目为例)
推荐用 FetchContent 直接拉取 gtest 源码编译,避免系统级安装或版本冲突:
- 在项目的
CMakeLists.txt中加入:
include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip ) FetchContent_MakeAvailable(googletest)链接测试可执行文件
add_executable(my_tests test_main.cpp my_class_test.cpp) target_link_libraries(my_tests gtest_main gtest)
注意:不用单独编译 gtest 库,FetchContent_MakeAvailable 会自动处理构建依赖;gtest_main 提供了默认的 main(),省去自己写入口函数。
二、写第一个测试用例(TestCase + TEST 宏)
假设有如下待测类:
立即学习“C++免费学习笔记(深入)”;
// calculator.h #pragma once int add(int a, int b); int multiply(int a, int b);
对应测试文件 calculator_test.cpp:
#include "calculator.h" #includeTEST(CalculatorTest, AddPositiveNumbers) { EXPECT_EQ(add(2, 3), 5); }
TEST(CalculatorTest, MultiplyByZero) { EXPECT_EQ(multiply(7, 0), 0); EXPECT_EQ(multiply(0, -5), 0); }
-
TEST(测试套名, 测试名)是最常用宏,自动生成函数并注册到测试框架 -
EXPECT_EQ是非致命断言:失败时打印信息但继续执行本测试函数 - ASSERT_EQ
三、测试类(Test Fixture)管理共享资源
当多个测试需要共用初始化/清理逻辑(如打开文件、构造对象),用测试类更清晰:
class StringHelperTest : public ::testing::Test {
protected:
void SetUp() override { // 每个 TEST 运行前调用
str_ = "hello";
}
void TearDown() override { } // 每个 TEST 运行后调用(可选)
std::string str_;
};
TEST_F(StringHelperTest, LengthIsFive) {
EXPECTEQ(str.length(), 5);
}
TEST_F(StringHelperTest, StartsWithHe) {
EXPECTTRUE(str.starts_with("he"));
}
- 继承
::testing::Test,重写SetUp/TearDown - 用
TEST_F替代TEST,第一个参数必须是该类名 - 每个测试运行在独立实例上,成员变量互不干扰
四、运行与调试技巧
- 编译后直接运行可执行文件:
./my_tests,默认输出简洁结果 - 加参数查看详情:
./my_tests --gtest_print_time --gtest_color=yes - 只运行匹配名字的测试:
./my_tests --gtest_filter=*Add*或./my_tests --gtest_filter=CalculatorTest.* - 在 IDE(如 CLion / VS Code)中配置运行目标,点击 ▶️ 即可单步调试测试函数
- 遇到 “undefined reference to testing::InitGoogleTest”?检查是否链接了
gtest_main,且未重复定义main()
不复杂但容易忽略:测试命名要有业务含义(比如 ParseJson_InvalidInput_ThrowsException),比 Test1 更易维护;每个 TEST 只验证一个关注点,避免堆砌多个断言掩盖真正问题。











