C++ GoogleTest
外观
C++ GoogleTest[编辑 | 编辑源代码]
GoogleTest(简称gtest)是Google开发的C++单元测试框架,用于编写自动化测试用例。它支持多种测试模式(如单元测试、集成测试),提供丰富的断言宏和测试组织工具,是C++项目中广泛采用的测试解决方案。
核心概念[编辑 | 编辑源代码]
测试用例结构[编辑 | 编辑源代码]
GoogleTest中测试由以下层级构成:
- 测试套件(Test Suite):一组相关测试用例的集合
- 测试用例(Test Case):独立的测试单元
- 断言(Assertion):验证条件是否满足的检查点
断言类型[编辑 | 编辑源代码]
GoogleTest提供两类断言:
- 非致命断言:
EXPECT_*
,测试继续执行即使失败 - 致命断言:
ASSERT_*
,失败时立即终止当前测试
常见断言示例:
断言类型 | 示例 | 说明 |
---|---|---|
相等检查 | EXPECT_EQ(a, b) |
验证a == b |
布尔检查 | ASSERT_TRUE(cond) |
验证条件为真 |
异常检查 | EXPECT_THROW(stmt, exc_type) |
验证语句抛出指定异常 |
安装与配置[编辑 | 编辑源代码]
Linux安装[编辑 | 编辑源代码]
# 下载源码
git clone https://github.com/google/googletest.git
cd googletest
mkdir build && cd build
cmake ..
make
sudo make install # 安装到系统目录
CMake集成[编辑 | 编辑源代码]
现代C++项目通常通过CMake集成GoogleTest:
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(MyTests test1.cpp test2.cpp)
target_link_libraries(MyTests ${GTEST_LIBRARIES} pthread)
基础用法示例[编辑 | 编辑源代码]
简单测试用例[编辑 | 编辑源代码]
#include <gtest/gtest.h>
// 被测函数
int Factorial(int n) {
return n <= 1 ? 1 : n * Factorial(n - 1);
}
// 测试套件定义
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(Factorial(1), 1);
EXPECT_EQ(Factorial(2), 2);
EXPECT_EQ(Factorial(3), 6);
EXPECT_EQ(Factorial(10), 3628800);
}
TEST(FactorialTest, HandlesZeroInput) {
ASSERT_EQ(Factorial(0), 1);
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
输出示例:
[==========] Running 2 tests from 1 test suite. [----------] Global test environment set-up. [----------] 2 tests from FactorialTest [ RUN ] FactorialTest.HandlesPositiveInput [ OK ] FactorialTest.HandlesPositiveInput (0 ms) [ RUN ] FactorialTest.HandlesZeroInput [ OK ] FactorialTest.HandlesZeroInput (0 ms) [==========] 2 tests from 1 test suite ran. (2 ms total) [ PASSED ] 2 tests.
高级特性[编辑 | 编辑源代码]
测试夹具(Test Fixtures)[编辑 | 编辑源代码]
用于共享测试配置和资源:
class StackTest : public ::testing::Test {
protected:
void SetUp() override {
stack.push(1);
stack.push(2);
}
void TearDown() override {
// 清理代码
}
std::stack<int> stack;
};
TEST_F(StackTest, PushIncreasesSize) {
stack.push(3);
ASSERT_EQ(stack.size(), 3);
}
TEST_F(StackTest, PopReturnsLastValue) {
int val = stack.top();
stack.pop();
EXPECT_EQ(val, 2);
EXPECT_EQ(stack.size(), 1);
}
参数化测试[编辑 | 编辑源代码]
允许使用不同参数运行相同测试逻辑:
class IsPrimeTest : public ::testing::TestWithParam<int> {};
TEST_P(IsPrimeTest, HandlesVariousInputs) {
int n = GetParam();
EXPECT_TRUE(IsPrime(n));
}
INSTANTIATE_TEST_SUITE_P(PrimeValues, IsPrimeTest,
::testing::Values(2, 3, 5, 7, 11, 13, 17));
类型参数化测试[编辑 | 编辑源代码]
支持模板测试:
template <typename T>
class VectorTest : public ::testing::Test {};
using MyTypes = ::testing::Types<int, float, double>;
TYPED_TEST_SUITE(VectorTest, MyTypes);
TYPED_TEST(VectorTest, InitialSizeIsZero) {
std::vector<TypeParam> vec;
EXPECT_EQ(vec.size(), 0);
}
实际应用案例[编辑 | 编辑源代码]
数学库测试[编辑 | 编辑源代码]
验证矩阵运算库的正确性:
TEST(MatrixTest, Multiplication) {
Matrix a = {{1, 2}, {3, 4}};
Matrix b = {{5, 6}, {7, 8}};
Matrix expected = {{19, 22}, {43, 50}};
Matrix result = Multiply(a, b);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
EXPECT_NEAR(result[i][j], expected[i][j], 1e-5);
}
}
}
网络协议测试[编辑 | 编辑源代码]
验证协议解析器:
TEST(ProtocolTest, ParsesValidPacket) {
Packet p = ParsePacket("\x01\x02\x03\x04");
EXPECT_EQ(p.header, 0x01);
EXPECT_EQ(p.length, 0x02);
EXPECT_EQ(p.type, 0x03);
EXPECT_EQ(p.checksum, 0x04);
}
TEST(ProtocolTest, ThrowsOnShortPacket) {
EXPECT_THROW(ParsePacket("\x01\x02"), InvalidPacketError);
}
最佳实践[编辑 | 编辑源代码]
- 测试命名应清晰表达测试目的
- 每个测试用例应聚焦单一功能点
- 优先使用
EXPECT_
而非ASSERT_
以获取更多失败信息 - 测试应独立,不依赖执行顺序
- 定期运行测试(建议集成到CI/CD流程中)
数学公式支持[编辑 | 编辑源代码]
当测试涉及数学计算时,可明确表达预期关系:
对应测试用例:
TEST(SumOfSquaresTest, ValidatesFormula) {
int n = 10;
int expected = n*(n+1)*(2*n+1)/6;
EXPECT_EQ(SumOfSquares(n), expected);
}
调试技巧[编辑 | 编辑源代码]
- 使用
--gtest_filter
运行特定测试 --gtest_repeat=N
重复测试N次--gtest_break_on_failure
在失败时启动调试器- 使用
SCOPED_TRACE
定位失败位置
通过系统学习GoogleTest,开发者可以构建健壮的测试体系,显著提高C++代码质量和可维护性。