1. 安装
本地使用ubuntu的环境,可以直接使用apt安装预编译的库。使用下面的命令
sudo apt update
sudo apt update
# 如果需要 Google Test 的测试工具(如 gtest-config),可以额外安装 googletest:
sudo apt install googletest
安装完成后,Google Test 的头文件通常位于 /usr/include/gtest/,静态库文件(如 libgtest.a 和 libgtest_main.a)位于 /usr/lib 或 /usr/lib/x86_64-linux-gnu/(具体路径取决于 Ubuntu 版本)。
使用 Google Test 时,编译器需要链接 libgtest 和 libgtest_main,并且通常需要链接 pthread 库。例如,在编译测试程序时:
g++ -std=c++17 test_file.cc -lgtest -lgtest_main -pthread -o test
2. 使用Google Test的CMake配置
如果你使用 CMake 构建项目,推荐在 CMakeLists.txt 中配置 Google Test。以下是一个示例:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找 GTest
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
# 添加测试可执行文件
add_executable(my_test test_file.cc)
target_link_libraries(my_test GTest::GTest GTest::Main pthread)
运行以下命令构建和测试:
mkdir build
cd build
cmake ..
make
./my_test
3. 断言
在gtest中,通过断言(assertion)来判断代码中实现的功能是否符合预期。断言的结果分为success、non-fatal failture和fatal failture。
根据断言失败的种类,gtest提供了两种断言函数:
success:即断言成功,程序的行为符合预期,程序继续向下允许。
non-fatal failure:即断言失败,但是程序没有直接crash,而是继续向下运行。
gtest提供了宏函数EXPECT_XXX(expected, actual):如果condition(expected, actual)返回false,则EXPECT_XXX产生的就是non-fatal failure错误,并显示相关错误。
fatal failure:断言失败,程序直接crash,后续的测试案例不会被运行。
gtest提供了宏函数ASSERT_XXX(expected, actual)。
在写单元测试时,更加倾向于使用EXPECT_XXX,因为ASSERT_XXX是直接crash退出的,可能会导致一些内存、文件资源没有释放,因此可能会引入一些bug。
具体的EXPECT_XXX、ASSERT_XXX函数及其判断条件,如下所示
断言 | 验证条件 |
---|---|
EXPECT_TRUE(condition) | condition 为真 |
EXPECT_FALSE(condition) | condition 为假 |
EXPECT_EQ(val1, val2) | val1 == val2 |
EXPECT_NE(val1, val2) | val1 != val2 |
EXPECT_LT(val1, val2) | val1 < val2 |
EXPECT_LE(val1, val2) | val1 <= val2 |
EXPECT_GT(val1, val2) | val1 > val2 |
EXPECT_GE(val1, val2) | val1 >= val2 |
EXPECT_STREQ(str1, str2) | C字符串 str1 和 str2 相等 |
EXPECT_STRNE(str1, str2) | C字符串 str1 和 str2 不相等 |
EXPECT_STRCASEEQ(str1, str2) | C字符串 str1 和 str2 相等(忽略大小写) |
EXPECT_STRCASENE(str1, str2) | C字符串 str1 和 str2 不相等(忽略大小写) |
EXPECT_FLOAT_EQ(val1, val2) | 两个 float 值 val1 和 val2 近似相等 |
EXPECT_DOUBLE_EQ(val1, val2) | 两个 double 值 val1 和 val2 近似相等 |
EXPECT_NEAR(val1, val2, abs_error) | val1 和 val2 之差的绝对值不超过 abs_error |
EXPECT_THROW(statement, exception_type) | statement 抛出 exception_type 类型的异常 |
EXPECT_ANY_THROW(statement) | statement 抛出任何类型的异常 |
EXPECT_NO_THROW(statement) | statement 不抛出任何异常 |
EXPECT_THAT(val, matcher) | val 满足匹配器 matcher |
完整列表参考:https://google.github.io/googletest/reference/assertions.html
断言宏返回一个ostream对象,可以使用<<运算符输出自定义的失败信息。
EXPECT_TRUE(my_condition) << "my condition is not true";
4. TEST宏
TEST宏用于定义一个测试,语法如下
TEST(TestSuiteName, TestName) {
test body
}
其中第一个参数是测试套件名称,第二个参数是测试用例名称,二者都必须是合法的C++标识符,并且不应该包含下划线。
测试体可以包含断言和任何C++语句。如果任何断言失败或者崩溃,则整个测试失败,否则成功。
注:TEST()宏实际上定义了一个名为TestSuiteName_TestName_Test的类,该类继承了::testing::Test类并覆盖了成员函数TestBody(),测试体就是其函数体。其(简化的)定义如下:
#define TEST(TestSuiteName, TestName) \
class TestSuiteName##_##TestName##_Test : public ::testing::Test { \
private: \
void TestBody() override; \
}; \
void TestSuiteName##_##TestName##_Test::TestBody()
5. TEST_F宏
test fixture,即测试夹具,可以让多个测试用例共用相同的的对象或数据。要创建一个fixture,只需继承::testing::Test
类,在类中定义要使用的对象,在默认构造函数或SetUp()函数中进行初始化,在析构函数或TearDown()函数中进行清理(释放资源),此外还可以定义需要共用的函数。如下所示:
// The fixture for testing class Foo.
class FooTest : public ::testing::Test {
protected:
FooTest() {
// You can do set-up work for each test here.
}
~FooTest() override {
// You can do clean-up work that doesn't throw exceptions here.
}
void SetUp() override {
// Code here will be called immediately after the constructor (right before each test).
}
void TearDown() override {
// Code here will be called immediately after each test (right before the destructor).
}
// Class members declared here can be used by all tests in the test suite for Foo.
};
TEST_F语法如下:
TEST_F(TestFixtureName, TestName) {
test body
}
其中TestFixtureName既是fixture类名,也是测试套件名,在测试体中可以使用fixture类定义的数据成员。
对于每一个使用TEST_F()定义的测试,GoogleTest都会创建一个新的 fixture对象,调用SetUp()初始化,运行测试,调用TearDown()清理,最后删除fixture对象。同一个测试套件中的不同测试使用不同的fixture对象,因此一个测试所做的改变不影响其他测试。
注:TEST_F()宏与TEST()唯一的区别是定义的类继承fixture类而不是::testing::Test:
#define TEST_F(TestFixtureName, TestName) \
class TestFixtureName##_##TestName##_Test : public TestFixtureName { \
private: \
void TestBody() override; \
}; \
void TestFixtureName##_##TestName##_Test::TestBody()
评论 (0)