介绍
学习如下gtest课程,总结主要的部分
1.玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest
2.玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言
3.玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制
4.玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化
5.玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
6.玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数
7.玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest
8.玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架
其中:
初始gtest:讲了gtest环境搭建,及第一个demo (必会)
断言:是gtest结果判断,写测试用例必用(必会)
事件机制:是在用例前后执行的,减少公共代码(提高)
参数化: 构造一批参数多次执行测试用例(提高)
死亡测试:崩溃或退出断言(掌握,备查)
运行参数:介绍gtest执行时可以输入的系统参数(掌握,备查)
深入解析:通过展开gtest关键宏,看gtest源码,学习Gtest原理(高级,理解精髓)
Gtest通过很简单的原理实现了C++的单元测试,还是需要好好理解其中的设计思想。
打造自己…:学习原理后,自己实现一个简化的gtest(高级)
1 初识gtest
玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest
本篇将介绍一些gtest的基本使用,包括下载,安装,编译,建立我们第一个测试Demo工程,以及编写一个最简单的测试案例。
Gtest官网
http://code.google.com/p/googletest/
从官方的使用文档里,你几乎可以获得你想要的所有东西
http://code.google.com/p/googletest/wiki/GoogleTestPrimer
http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide
编译
用VS2017打开工程,直接编译即可。
可以修改CMakeLists.txt中的一些配置。
编译之后,在msvc里面的Debug或是Release目录里看到编译出来的gtestd.lib或是gtest.lib文件。
googletest\msvc\2010\gtest\Win32-Debug
2 断言
玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言
gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:
1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。
2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。
变量值检查,如整数,bool,字符串等
这种有很多,输入EXPECT_ 和 ASSERT_ 联想很容易认识
显式返回成功或失败
直接返回成功:SUCCEED();
返回失败:
Fatal assertion | Nonfatal assertion |
FAIL(); | ADD_FAILURE(); |
异常检查
EXPECT_THROW
EXPECT_ANY_THROW
EXPECT_NO_THROW
类型检查
testing::StaticAssertTypeEq<int, T>();
3 事件机制
玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制
gtest提供了多种事件机制,非常方便我们在案例之前或之后做一些操作,有如下三种。
全局事件
全局的,所有案例执行前后。
要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。
1. SetUp()方法在所有案例执行前执行
2. TearDown()方法在所有案例执行后执行
当然,这样还不够,我们还需要告诉gtest添加这个全局事件,我们需要在main函数中通过testing::AddGlobalTestEnvironment方法将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去。
TestSuite事件
TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后。
我们需要写一个类,继承testing::Test,然后实现两个静态方法
1. SetUpTestCase() 方法在第一个TestCase之前执行
2. TearDownTestCase() 方法在最后一个TestCase之后执行
在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite。
TestCase事件
TestCase级别的,每个TestCase前后。
TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:
1. SetUp()方法在每个TestCase之前执行
2. TearDown()方法在每个TestCase之后执行
4 参数化
玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化
在设计测试案例时,经常需要考虑给被测函数传入不同的值的情况。我们之前的做法通常是写一个通用方法,然后编写在测试案例调用它。即使使用了通用方法,这样的工作也是有很多重复性的,程序员都懒,都希望能够少写代码,多复用代码。Google的程序员也一样,他们考虑到了这个问题,并且提供了一个灵活的参数化测试的方案。
就是如果需要测试一个参数为很多值的时候,可以一次写好。具体先不看了。
5 死亡测试
玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
“死亡测试”名字比较恐怖,这里的“死亡”指的的是程序的崩溃。通常在测试过程中,我们需要考虑各种各样的输入,有的输入可能直接导致程序崩溃,这时我们就需要检查程序是否按照预期的方式挂掉,这也就是所谓的“死亡测试”。gtest的死亡测试能做到在一个安全的环境下执行崩溃的测试案例,同时又对崩溃结果进行验证。
Fatal assertion | Nonfatal assertion | Verifies |
ASSERT_DEATH(statement, regex`); | EXPECT_DEATH(statement, regex`); | statement crashes with the given error |
ASSERT_EXIT(statement, predicate, regex`); | EXPECT_EXIT(statement, predicate, regex`); | statement exits with the given error and its exit code matches predicate |
由于有些异常只在Debug下抛出,因此还提供了*_DEBUG_DEATH,用来处理Debug和Realease下的不同。
简单来说,通过*_DEATH(statement, regex`)和*_EXIT(statement, predicate, regex`),我们可以非常方便的编写导致崩溃的测试案例,并且在不影响其他案例执行的情况下,对崩溃案例的结果进行检查。
6 运行参数
玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数
gtest也为我们提供了一系列的运行参数(环境变量、命令行参数或代码里指定),使得我们可以对案例的执行进行一些有效的控制。
对于运行参数,gtest提供了三种设置的途径:
1. 系统环境变量
2. 命令行参数
3. 代码中指定FLAG
因为提供了三种途径,就会有优先级的问题, 有一个原则是,最后设置的那个会生效。不过总结一下,通常情况下,比较理想的优先级为:
命令行参数 > 代码中指定FLAG > 系统环境变量
在main函数中,将命令行参数交给了gtest,由gtest来搞定命令行参数的问题。
testing::InitGoogleTest(&argc, argv);
测试案例集合
命令行参数 | 说明 |
--gtest_list_tests | 使用这个参数时,将不会执行里面的测试案例, 而是输出一个案例的列表。 |
--gtest_filter | 对执行的测试案例进行过滤,支持通配符 |
--gtest_also_run_disabled_tests | 执行案例时,同时也执行被置为无效的测试案例。 |
--gtest_repeat=[COUNT] | 设置案例重复运行次数,非常棒的功能! |
测试案例输出
命令行参数 | 说明 |
--gtest_color=(yes|no|auto) | 输出命令行时是否使用一些五颜六色的颜色。默认是auto。 |
--gtest_print_time | 输出命令行时是否打印每个测试案例的执行时间。默认是不打印的。 |
--gtest_output=xml[:DIRECTORY_PATH\|:FILE_PATH] | 将测试结果输出到一个xml中。 |
对案例的异常处理
命令行参数 | 说明 |
--gtest_break_on_failure | 调试模式下,当案例失败时停止,方便调试 |
--gtest_throw_on_failure | 当案例失败时以C++异常的方式抛出 |
--gtest_catch_exceptions | 是否捕捉异常。 |
7 深入解析gtest
玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest
通过分析TEST宏和RUN_ALL_TEST宏,了解到了整个gtest运作过程。
总的来说,TEST负责测试用例的编写和注册。RUN_ALL_TEST负责测试用例的运行。
8 打造自己的单元测试框架
玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架
尝试编写一个精简版本的C++单元测试框架:nancytest ,通过编写这个简单的测试框架,将有助于我们理解gtest。