GoogleTest 简介
GoogleTest 是一个面向 C++ 的测试框架。它把测试组织为测试套件和测试用例,并提供断言、测试夹具、参数化测试、死亡测试、事件监听器、过滤器和 XML 输出等能力。
核心术语
| 术语 | 含义 |
|---|---|
| Test Suite | 测试套件,通常对应一个模块、类或主题 |
| Test Case | 一个具体测试函数,现在官方文档中更多称为 test |
| Assertion | 断言,用于判断实际结果是否符合预期 |
| Fixture | 测试夹具,用于复用测试前后的准备和清理逻辑 |
| Failure | 失败结果,分为非致命失败和致命失败 |
第一个测试
#include <gtest/gtest.h>
int Factorial(int n) {
if (n < 0) {
return 0;
}
int result = 1;
for (int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
TEST(FactorialTest, HandlesZero) {
EXPECT_EQ(Factorial(0), 1);
}
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(Factorial(1), 1);
EXPECT_EQ(Factorial(5), 120);
}
TEST(FactorialTest, HandlesZero) 会在编译期生成一个测试类,并在静态初始化阶段把测试注册到 GoogleTest 的全局注册表中。运行测试程序时,GoogleTest 会遍历注册表并执行匹配的测试。
EXPECT_* 与 ASSERT_*
GoogleTest 的断言分为两类:
| 类型 | 失败后行为 | 适用场景 |
|---|---|---|
EXPECT_* |
记录失败,当前测试继续执行 | 可以继续检查后续条件 |
ASSERT_* |
记录失败,当前函数立即返回 | 后续代码依赖该条件成立 |
示例:
TEST(VectorTest, ReadsFirstElement) {
std::vector<int> values = {1, 2, 3};
ASSERT_FALSE(values.empty());
EXPECT_EQ(values.front(), 1);
}
如果 values 为空,ASSERT_FALSE 会阻止继续访问 front(),避免产生未定义行为。
测试命名
命名应该表达行为,而不是重复实现细节。
| 推荐 | 不推荐 |
|---|---|
ParserTest, RejectsEmptyInput |
ParserTest, Test1 |
RingBufferTest, PushFailsWhenFull |
RingBufferTest, Push |
ChecksumTest, CalculatesKnownCrc32 |
ChecksumTest, Crc |
常用运行参数
./unit_tests
./unit_tests --gtest_list_tests
./unit_tests --gtest_filter=FactorialTest.*
./unit_tests --gtest_filter=-*.Slow*
./unit_tests --gtest_repeat=10
./unit_tests --gtest_shuffle
./unit_tests --gtest_output=xml:test_report.xml
| 参数 | 说明 |
|---|---|
--gtest_list_tests |
列出测试,不执行 |
--gtest_filter=Suite.Test |
只执行匹配的测试 |
--gtest_repeat=N |
重复执行 N 次 |
--gtest_shuffle |
打乱测试顺序,发现顺序依赖 |
--gtest_output=xml:path |
输出 XML 报告 |
--gtest_break_on_failure |
失败时触发调试中断 |
最小 CMake 工程
cmake_minimum_required(VERSION 3.20)
project(gtest_demo LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(GTest REQUIRED)
add_executable(unit_tests factorial_test.cpp)
target_link_libraries(unit_tests PRIVATE GTest::gtest_main)
include(GoogleTest)
gtest_discover_tests(unit_tests)
构建并运行:
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failure
入门阶段常见错误
- 把多个无关行为塞进同一个测试,导致失败定位困难。
- 误用
EXPECT_TRUE(a == b),导致失败信息不如EXPECT_EQ(a, b)清晰。 - 测试之间共享全局状态,单独运行能过,批量运行失败。
- 只测试正常路径,不测试空输入、边界值、异常路径。
- 把实现细节写死在测试里,导致重构时测试脆弱。