用 GoogleTest 进行单元测试
2024-11-02 17:16:01

将 GoogleTest 添加到项目中

GoogleTest 仓库地址:https://github.com/google/googletest
包含两个项目:GoogleTest 和 GoogleMock,目录结构是这样的:

1
2
3
4
5
6
googletest/
├── googletest/
│ └── CMakeLists.txt
├── googlemock/
│ └── CMakeLists.txt
└── CMakeLists.txt

GoogleMock 是用于模拟数据用的,简单测试的话用不上它。只需要将 googletest 拷贝到项目中,大概是这样的结构:

1
2
3
4
5
6
7
8
MyProject/
├── CMakeLists.txt
├── ModuleA/
│ └── CMakeLists.txt
└── googletest/
├── googletest/
│ └── CMakeLists.txt
└── CMakeLists.txt

然后在根CMakeLists.txt文件中加入

1
2
set(BUILD_GMOCK OFF)
add_subdirectory(googletest)

接着创建一个测试项目,比如ModuleA-Test,在它的CMakeLists.txt中链接gtest_main即可。

1
target_link_libraries(ModuleA-Test PRIVATE gtest_main)

注意,GoogleTest 添加了两个 target,gtestgtest_main
gtest_main是 GoogleTest 测试框架中的一个库,它提供了一个预定义的main()函数,用于运行所有的测试用例。
在使用 GoogleTest 编写测试时,通常需要定义一个main()函数来初始化测试框架并运行测试用例。而gtest_main库提供了一个默认的main()函数实现,
通过使用gtest_main库,可以避免在每个测试文件中编写相同的main()函数,从而简化测试代码的编写和维护。
下面是一个使用gtest_main库的简单示例:

1
2
3
4
5
6
7
#include <gtest/gtest.h>

TEST(ExampleTest, SimpleTest) {
ASSERT_EQ(2, 1 + 1);
}

// 无需编写 main() 函数,gtest_main 会自动提供

gtest_main是依赖gtest的,所以我们只需要链接gtest_main即可。

断言

断言分成两大类:

  • ASSERT_*系列:如果检测失败就直接退出当前函数。
  • EXPECT_*系列:如果检测失败发出提示,并继续往下执行。

通常情况应该首选使用 EXPECT,因为 ASSERT 在报告完错误后不会进行清理工作。

判断布尔类型

1
2
3
4
5
ASSERT_TRUE(condition);      // 判断条件是否为真
ASSERT_FALSE(condition); // 判断条件是否为假

EXPECT_TRUE(condition); // 判断条件是否为真
EXPECT_FALSE(condition); // 判断条件是否为假

逻辑判断

1
2
3
4
5
6
7
8
9
10
11
12
13
ASSERT_EQ(val1, val2);       // 判断是否相等
ASSERT_NE(val1, val2); // 判断是否不相等
ASSERT_LT(val1, val2); // 判断是否小于
ASSERT_LE(val1, val2); // 判断是否小于等于
ASSERT_GT(val1, val2); // 判断是否大于
ASSERT_GE(val1, val2); // 判断是否大于等于

EXPECT_EQ(val1, val2); // 判断是否相等
EXPECT_NE(val1, val2); // 判断是否不相等
EXPECT_LT(val1, val2); // 判断是否小于
EXPECT_LE(val1, val2); // 判断是否小于等于
EXPECT_GT(val1, val2); // 判断是否大于
EXPECT_GE(val1, val2); // 判断是否大于等于

比较字符串类型

1
2
3
4
5
6
7
8
9
ASSERT_STREQ(str1,str2);     // 判断字符串是否相等
ASSERT_STRNE(str1,str2); // 判断字符串是否不相等
ASSERT_STRCASEEQ(str1,str2); // 判断字符串是否相等,忽视大小写
ASSERT_STRCASENE(str1,str2); // 判断字符串是否不相等,忽视大小写

EXPECT_STREQ(str1,str2); // 判断字符串是否相等
EXPECT_STRNE(str1,str2); // 判断字符串是否不相等
EXPECT_STRCASEEQ(str1,str2); // 判断字符串是否相等,忽视大小写
EXPECT_STRCASENE(str1,str2); // 判断字符串是否不相等,忽视大小写

谓词

谓词用于编写自定义的断言。这些宏允许你定义一个谓词函数,该函数接受一定数量的参数并返回一个布尔值,然后将该谓词函数应用于实际的参数,并根据返回值来确定断言是否通过。

1
2
3
4
5
6
7
8
9
10
11
EXPECT_PRED1(pred,val1);
EXPECT_PRED2(pred,val1,val2);
EXPECT_PRED3(pred,val1,val2,val3);
EXPECT_PRED4(pred,val1,val2,val3,val4);
EXPECT_PRED5(pred,val1,val2,val3,val4,val5);

ASSERT_PRED1(pred,val1);
ASSERT_PRED2(pred,val1,val2);
ASSERT_PRED3(pred,val1,val2,val3);
ASSERT_PRED4(pred,val1,val2,val3,val4);
ASSERT_PRED5(pred,val1,val2,val3,val4,val5);

一个使用 EXPECT_PRED2 的例子:

1
2
3
4
5
6
7
8
9
10
#include <gtest/gtest.h>

bool IsPositiveAndEven(int x, int y) {
return x > 0 && y > 0 && x % 2 == 0 && y % 2 == 0;
}

TEST(PredTest, IsPositiveAndEven) {
EXPECT_PRED2(IsPositiveAndEven, 2, 4);
EXPECT_PRED2(IsPositiveAndEven, 3, 4);
}

相关阅读

玩转Google开源C++单元测试框架Google Test系列
C++单元测试框架Google Test系列(gtest)
C++单元测试GoogleTest和GoogleMock十分钟快速上手
C++ 项目之Googletest单元测试
CLion 中使用 Google Test