Google C++ 自动测试框架入门
Google C++ 测试框架入门
简介: 为什么需要Google C++ 测试框架
Google C++ 测试框架 可以帮助你更好地编写C++测试。
无论你是工作在Linux、Windows、还是在Mac,只要你编写C++代码,Google测试框架都可以帮上忙。
那么,哪些因素才能构成一个好的测试?以及,Google C++ 测试框架怎样满足这些因素?我们相信:
- 测试应该是 独立、可重复 的。因为其他测试成功或失败而导致我们要对自己的测试进行debug是非常痛苦的。Google C++ 测试框架通过将每个测试在不同的对象中运行,使得测试分离开来。当一个测试失败时,Google C++ 测试框架允许你独立运行它以进行快速除错。
- 测试应该能够被很好地组织,并反映被测代码的结构。Google C++ 测试框架将测试组织成测试案例,案例中的测试可以共享数据和程序分支。这样一种通用模式能够很容易辨识,使得我们的测试容易维护。当开发人员在项目之间转换,开始在一个新的代码基上开始工作时,这种一致性格外有用。
- 测试应该是 可移植、可重用的。开源社区有很多平台独立的代码,它们的测试也应该是平台独立的。除开一些特殊情况,Google C++ 测试框架运行在不同的操作系统上、与不同的编译器(gcc、icc、MSVC)搭配,Google C++ 测试框架的测试很容易与不同的配置一起工作。
- 当测试失败时,应该提供尽可能多的、关于问题的信息。Google C++ 测试框架在第一个测试失败时不会停下来。相反,它只是将当前测试停止,然后继续接下来的测试。你也可以设置对一些非致命的错误进行报告,并接着进行当前的测试。这样,你就可以在一次“运行-编辑-编译”循环中检查到并修复多个bug。
- 测试框架应该能将测试编写人员从一些环境维护的工作中解放出来,使他们能够集中精力于测试的内容。Google C++ 测试框架自动记录下所有定义好的测试,不需要用户通过列举来指明哪些测试需要运行。
- 测试应该快速。使用Google C++ 测试框架,你可以重用多个测试的共享资源,一次性完成设置/解除设置,而不用使一个测试去依赖另一测试。
因为Google C++ 测试框架基于著名的xUnit架构,如果你之前使用过JUnit或PyUnit的话,你将会感觉非 常熟悉。如果你没有接触过这些测试框架,它也只会占用你大约10分钟的时间来学习基本概念和上手。所以,让我们开始吧!
Note: 本文偶尔会用“Google Test”来代指“Google C++ 测试框架”。
基本概念
使用Google Test时,你是从编写断言开始的,而断言是一些检查条件是否为真的语句。一个断言的结果 可能是成功、非致命失败,或者致命失败。如果一个致命失败出现,他会结束当前的函数;否则,程序继续正常运行。
测试使用断言来验证被测代码的行为。如果一个测试崩溃或是出现一个失败的断言,那么,该测试失败;否则该测试成功。
一个测试案例(test case)包含了一个或多个测试。你应该将自己的测试分别归类到测试案例中,以反 映被测代码的结构。当测试案例中的多个测试需要共享通用对象和子程序时,你可以把他们放到一个测试固件(test fixture)类中。
一个测试程序可以包含多个测试案例。
从编写单个的断言开始,到创建测试和测试案例,我们将会介绍怎样编写一个测试程序。
断言
Google Test中的断言是一些与函数调用相似的宏。要测试一个类或函数,我们需要对其行为做出断言。 当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信 息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错 误信息之后。
断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。
因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。根据泄漏本身的特质,这种情况也许值得修复,也可能不值得我们关心——所以,如果你得到断言错误的同时,还得到了一个堆检查的错误,记住上面我们所说的这一点。
要提供一个自定义的错误消息,只需要使用<<操作符,或一个<<操作符的序列,将其输入到框架定义的宏中。下面是一个例子:
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
for (int i = 0; i < x.size(); ++i) {
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
任何能够被输出到ostream中的信息都可以被输出到一个断言宏中——特别是C字符串和string对象。如果一个宽字符串(wchar_t*,windows上 UNICODE模式TCHAR*或std::wstring)被输出到一个断言中,在打印时它会被转换成UTF-8编码。
基本断言
下面这些断言实现了基本的true/false条件测试。
致命断言 | 非致命断言 | 验证条件 |
ASSERT_TRUE(condition); | EXPECT_TRUE(condition); | condition为真 |
ASSERT_FALSE(condition); | EXPECT_FALSE(condition); | condition为假 |
记住,当它们失败时,ASSERT_*产生一个致命失败并从当前函数返回,而EXCEPT_*产生一个非致命失败,允许函数继续运行。在两种情况下,一个断言失败都意味着它所包含的测试失败。
有效平台:Linux、Windows、Mac。
二进制比较
本节描述了比较两个值的一些断言。
致命断言 | 非致命断言 | 验证条件 |
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 |
在出现失败事件时,Google Test会将两个值(Val1和Val2)都打印出来。在ASSERT_EQ*和EXCEPT_EQ*断言(以及我们随后介绍类似的断言)中,你应该把你希望测试的表达式放在actual(实际值)的位置上,将其期望值放在expected(期望值)的位置上,因为Google Test的测试消息为这种惯例做了一些优化。
文章来源于领测软件测试网 https://www.ltesting.net/