gtest是Google开发的一个开源单元测试框架,代码提供丰富的注释和实例,参考实际用例可以很快上手基本单元测试,丰富的代码注释能够让有兴趣的开发者深入了解gtest的代码结构并做部分针对性的二次开发。gtest主要针对c/c++提供了针对函数接口和类方法丰富测试方法,针对单元测试特有的数据或者代码反复编写的这种特性做了集成和优化,满足当前绝大部分对于单元测试的需求。其有如下特点:
- 自动收集测试用例,无需开发者再次组织
- 提供强大的断言集,支持包括布尔、整型、浮点型、字符串等。提供断言方法自定义扩展
- 提供死亡测试功能
- 使用参数化自动生成多个相似的测试用例
- 可以将公共的用例初始化和清理工作放入测试夹具中,由gtest自动调用减少重复测试代码
- 提供监听事件,能够对测试开始或者结束进行状态分析。
结合如上的特点,gtest涉及知识主要是断言、参数化、夹具、死亡测试、监听这么几个点。本章主要讲解gtest的编译和基本实例执行。
1. gtest的获取和编译
1.1 gtest获取
gtest在GitHub上是开源项目,可以直接clone或者下载软件包。
git clone https://gitee.com/mirrors/googletest.git
1.2 ubuntu18.04编译
cd googletest-main
mkdir build
cd build
cmake ..
make
编译以后的静态库在build/lib下面,共四个静态库文件。
1.3 简单实例
创建测试用例目录utest,里面包含了gtest的源码和编译结果库文件。在测试中建立include、lib两个目录分别用来存放gtest对外提供的头文件和编译出来的库文件。注意include和lib下面的gtest子目录是最终实际保存头文件或者库的最终内容。
book@100ask:~/utest$ tree
.
├── a.out
├── googletest-main
├── gtest.cpp
├── include
│ └── gtest
└── lib
└── gtest
目录建立成功以后,通过如下命令将gtest中结果拷贝到需要编译的架构中:
cp gtest1110/build/lib/*.a lib/gtest/
cp -r gtest1110/googletest/include/gtest/ include/
建立测试文件gtest.cpp,代码内容如下
#include<gtest/gtest.h>
using namespace testing;
int add(int a,int b){
return a+b;
}
TEST(testCase,test0){
EXPECT_EQ(add(2, 3), 5); // 正确
EXPECT_EQ(add(2, 3), 4); // 错误
}
int main(int argc,char **argv){
InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}
通过如下命令将代码和库文件编译成一个可执行文件进行测试
g++ gtest.cpp -L lib/gtest -I include -lgtest -pthread
测试执行结果如下:
book@100ask:~/utest$ ./a.out
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from testCase
[ RUN ] testCase.test0
gtest.cpp:9: Failure
Expected equality of these values:
add(2, 3)
Which is: 5
4
[ FAILED ] testCase.test0 (0 ms)
[----------] 1 test from testCase (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] testCase.test0
1 FAILED TEST
2. Gtest简单说明
测试用例编写需要包含gtest.h头文件,文件中包含了核心的对外测试接口。
2.1 基本测试单元
gtest代码中包含了一些简单的测试用例,比方说sample_unitest.c中如下这一段
// Tests factorial of positive numbers.
TEST(FactorialTest, Positive) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
这一段给定了一个case基本的结构, TEST宏两个参数官方解释为:[TestCaseName,TestName],而我对这两个参数的定义是:[TestSuiteName,TestCaseName],在下一篇我们再来看为什么这样定义。
对检查点的检查,我们上面使用到了EXPECT_EQ这个宏,这个宏用来比较两个数字是否相等。Google还包装了一系列EXPECT_* 和ASSERT_*的宏,而EXPECT系列和ASSERT系列的区别是:
- EXPECT_* 失败时,案例继续往下执行。
- ASSERT_* 失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行。
另外,测试一个case中测试的前后顺序是有讲究的,前面的顺序要首先满足然后依次推进。也就是前面一个测试用例是后面一个测试用例成立的必要不充分条件。
2.2 测试运行
测试运行主要包含两个核心内容,main函数中开始部分使用中可以根据自己情况编写部分定制的初始化代码或者过滤代码。之后调用gtest初始化函数,然后调用执行接口即可完成整个执行过程。执行结束以后可能需要用户自己编写部分代码针对自己特定的需求完成部分定制的结果解析。这里面最基本的两个单元如下:
- “testing::InitGoogleTest(&argc, argv);” :gtest的测试案例允许接收一系列的命令行参数,因此,我们将命令行参数传递给gtest,进行一些初始化操作。gtest的命令行参数非常丰富,在后面我们也会详细了解到。
- “RUN_ALL_TESTS()” :运行所有测试案例。
版权归原作者 生活需要深度 所有, 如有侵权,请联系我们删除。