第1步:环境安装与配置
对于Linux系统
# 安装编译依赖
sudo apt-get install build-essential cmake libgtest-dev# 编译安装
cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make
sudo cp *.a /usr/lib
CMake集成示例
cmake_minimum_required(VERSION 3.14)
project(MyTests)find_package(GTest REQUIRED)
add_executable(runTests test.cpp)
target_link_libraries(runTests GTest::GTest GTest::Main)
第2步:编写第一个测试
创建test.cpp:
#include <gtest/gtest.h>TEST(MyFirstTest, BasicAssertion) {EXPECT_EQ(2+2, 4); // 期望相等ASSERT_TRUE(1 < 2); // 断言为真
}int main(int argc, char **argv) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
编译运行:
mkdir build && cd build
cmake .. && make
./runTests
第3步:核心断言类型
基本断言
ASSERT_TRUE(condition); // 致命断言
EXPECT_FALSE(condition); // 非致命断言
值比较
EXPECT_EQ(val1, val2); // ==
ASSERT_NE(val1, val2); // !=
EXPECT_LT(val1, val2); // <
ASSERT_LE(val1, val2); // <=
字符串比较
ASSERT_STREQ(str1, str2); // C字符串相等
EXPECT_STRCASEEQ(str1, str2); // 忽略大小写
第4步:测试夹具(Test Fixtures)
创建可复用的测试环境:
class VectorTest : public ::testing::Test {
protected:void SetUp() override {vec.push_back(1);vec.push_back(2);}void TearDown() override {vec.clear();}std::vector<int> vec;
};TEST_F(VectorTest, SizeTest) {ASSERT_EQ(vec.size(), 2);
}TEST_F(VectorTest, CapacityTest) {EXPECT_GE(vec.capacity(), 2);
}
第5步:参数化测试
使用不同参数运行相同测试逻辑:
class NumberTest : public ::testing::TestWithParam<int> {};INSTANTIATE_TEST_SUITE_P(EvenNumbers, NumberTest,::testing::Values(2, 4, 6, 8));TEST_P(NumberTest, IsEven) {int num = GetParam();ASSERT_EQ(num % 2, 0);
}
第6步:高级断言
异常断言
TEST(ExceptionTest, ThrowTest) {EXPECT_THROW({throw std::runtime_error("error");}, std::runtime_error);
}
浮点数比较
ASSERT_DOUBLE_EQ(1.0000001, 1.0); // 4ULP精度
EXPECT_NEAR(1.0, 1.0001, 0.001); // 绝对误差
死亡测试(验证程序崩溃)
TEST(DeathTest, InvalidAccess) {int* ptr = nullptr;EXPECT_DEATH(*ptr = 1, ".*");
}
第7步:Mocking(需要GoogleMock)
创建模拟对象:
#include <gmock/gmock.h>class Database {
public:virtual ~Database() = default;virtual int query(const std::string&) = 0;
};class MockDB : public Database {
public:MOCK_METHOD(int, query, (const std::string&), (override));
};TEST(DatabaseTest, QueryTest) {MockDB db;EXPECT_CALL(db, query("test")).WillOnce(::testing::Return(42));ASSERT_EQ(db.query("test"), 42);
}
第8步:最佳实践
-
测试命名规范:TestSuiteName.TestCaseName
-
每个测试保持独立,不依赖执行顺序
-
使用夹具减少重复代码
-
断言失败信息增强:
ASSERT_EQ(a, b) << "a=" << a << ", b=" << b;
- 控制测试执行:
./runTests --gtest_filter=TestSuite.* # 运行指定测试
./runTests --gtest_repeat=1000 --gtest_break_on_failure # 重复测试
第9步:高级功能
类型参数化测试:
template <typename T>
class TypedTest : public ::testing::Test {};
TYPED_TEST_SUITE_P(TypedTest);TYPED_TEST_P(TypedTest, Size) {TypeParam vec;EXPECT_EQ(vec.size(), 0);
}REGISTER_TYPED_TEST_SUITE_P(TypedTest, Size);
using MyTypes = ::testing::Types<std::vector<int>, std::list<float>>;
INSTANTIATE_TYPED_TEST_SUITE_P(My, TypedTest, MyTypes);
时间测量
TEST(TimingTest, FastOperation) {EXPECT_EXIT({// 被测代码}, ::testing::ExitedWithCode(0), "") << "Operation took too long";
}
第10步:集成到CI/CD
示例GitLab CI配置:
test_job:stage: testscript:- mkdir build- cd build- cmake ..- make- ./runTests --gtest_output="xml:test_results.xml"artifacts:reports:junit: build/test_results.xml
学习资源:
官方文档:https://google.github.io/googletest/
GitHub仓库:https://github.com/google/googletest
高级技巧:https://chromium.googlesource.com/external/github.com/google/googletest/+/HEAD/docs/advanced.md