GTest使用笔记
1. C++测试框架
1.1. CppUnit
这是一个与JUnit类似的框架,这个框架很陈旧了,并且有着一些缺点,例如一些类可以消失,一些类名应该修改,一些宏定义应该修改,帮助很少很乱等。
1.2. CxxTest
因为CppUnit有着一系列的缺点,CppUnit的鼻祖之一重写了一套C/C++单元测试框架,这就是CxxTest。与CppUnit相比,CxxTest具有如下一些优点:
- 不需要RTTI(运行时间类型信息);
- 不需要成员模板功能;
- 不需要异常处理;
- 不需要任何外部函数库(包括内存管理、文件/控制台的输入/输出和图形库等);
- 它完全是作为一套头文件的集合而进行发布的。
另外由于CppUnit带有Make文件,所以只能用在主要的操作系统中,而应用到不常见操作系统中源代码及Make文件修改的工作量就会很大。CxxTest不带Make文件,所以也可用于其他操作系统中,具有更好的可移植性和可用性。Gtest虽然也使用Makefile文件,但是通过libtool动态加载来实现,可以支持Supports Linux,Windows,Mac OS,以及其他操作系统。
CxxTest也有一些缺点,例如需要用到perl或者Python对测试代码的头文件进行文法扫描,生成可执行代码,准备工作比较麻烦。并且CxxTest的绝大多数功能都可以使用Gtest来完成,所以一般情况下就更加推荐Gtest。
1.3. GTest
Gtest是一个跨平台 (Linux, Mac OS X, Windows, Cygwin, Windows CE and Symbian) 的C++测试框架,由Google公司发布。Gtest测试框架是在不同平台上为编写C++测试而生成的。
这是Google的开源C++单元测试框架,是遵循 New BSD License(可用作商业用途)的开源项目。据说Google内部的大多数C++代码都已经使用这个测试框架进行单测,Gtest可以支持绝大多数大家所熟知的平台。
2. 安装GTest
下载源码
git clone https://github.com/google/googletest
3. 使用GTest
3.1. 代码
gtest_test.cpp文件
注意:如果有命名空间,main函数要放到命名空间外面,其实不建议使用main函数
#include "gtest/gtest.h"
#include "fun.h"
TEST(fun, add) {
EXPECT_EQ(1, add(2,-1));
EXPECT_EQ(5, add(2,3));
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
3.2. 编译
如果test中写了main函数,则编译比较简单;如果test中没有写main函数,则编译时需要链接gtest_main
3.3. 运行
make test CTEST_OUTPUT_ON_FAILURE=TRUE GTEST_COLOR=TRUE
4. GTest的一些基本概念
要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。
断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。 因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。
5. GTest的断言
5.1. 布尔值检查
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_TRUE(condition); |
EXPECT_TRUE(condition); |
condition is true |
|
ASSERT_FALSE(condition); |
EXPECT_FALSE(condition); |
condition is false |
5.2. 数值型数据检查
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_EQ(expected, actual); |
EXPECT_EQ(expected, actual); |
expected == actual |
|
ASSERT_NE(val1, val2); |
EXPECT_NE(val1, val2); |
val1 != val2 |
|
ASSERT_LT(val1, val2); |
EXPECT_LT(val1, val2); |
val1 < val2 |
|
ASSERT_LE(val1, val2); |
EXPECT_LE(val1, val2); |
val1 <= val2 |
|
ASSERT_GT(val1, val2); |
EXPECT_GT(val1, val2); |
val1 > val2 |
|
ASSERT_GE(val1, val2); |
EXPECT_GE(val1, val2); |
val1 >= val2 |
5.3. 字符串比较
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_STREQ(expected_str, actual_str); |
EXPECT_STREQ(expected_str, actual_str); |
两个C字符串有相同的内容 |
|
ASSERT_STRNE(str1, str2); |
EXPECT_STRNE(str1, str2); |
两个C字符串有不同的内容 |
|
ASSERT_STRCASEEQ(expected_str, actual_str); |
EXPECT_STRCASEEQ(expected_str, actual_str); |
两个C字符串有相同的内容,忽略大小写 |
|
ASSERT_STRCASENE(str1, str2); |
EXPECT_STRCASENE(str1, str2); |
两个C字符串有不同的内容,忽略大小写 |
5.4. 异常检查
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_THROW(statement, exception_type); |
EXPECT_THROW(statement, exception_type); |
statement throws an exception of the given type |
|
ASSERT_ANY_THROW(statement); |
EXPECT_ANY_THROW(statement); |
statement throws an exception of any type |
|
ASSERT_NO_THROW(statement); |
EXPECT_NO_THROW(statement); |
statement doesn't throw any exception |
5.5. 浮点型检查
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_FLOAT_EQ(expected, actual); |
EXPECT_FLOAT_EQ(expected, actual); |
the two float values are almost equal |
|
ASSERT_DOUBLE_EQ(expected, actual); |
EXPECT_DOUBLE_EQ(expected, actual); |
the two double values are almost equal |
对相近的两个数比较:
|
Fatal assertion |
Nonfatal assertion |
Verifies |
|
ASSERT_NEAR(val1, val2, abs_error); |
EXPECT_NEAR(val1, val2, abs_error); |
the difference between val1 and val2 doesn't exceed the given absolute error |
5.6. 此外还有类型检查、谓词检查等
6. 注意事项
6.1. 生成链接库时不要编UT文件
很多工程都包含UT文件,当这个工程编译链接库时,注意要把UT文件从链接库的源文件中剔除,然后单独把UT文件编成可执行文件。
6.2. 不建议使用main函数
如果链接了gtest_main,则不需要写main函数,建议使用这种方式。
参考文献
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)