gtest的简单使用

adtxl
2025-07-14 / 0 评论 / 16 阅读 / 正在检测是否收录...

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字符串 str1str2 相等
EXPECT_STRNE(str1, str2)C字符串 str1str2 不相等
EXPECT_STRCASEEQ(str1, str2)C字符串 str1str2 相等(忽略大小写)
EXPECT_STRCASENE(str1, str2)C字符串 str1str2 不相等(忽略大小写)
EXPECT_FLOAT_EQ(val1, val2)两个 floatval1val2 近似相等
EXPECT_DOUBLE_EQ(val1, val2)两个 doubleval1val2 近似相等
EXPECT_NEAR(val1, val2, abs_error)val1val2 之差的绝对值不超过 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

评论 (0)

取消