一、前言
这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:
1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。
2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。
二、示例
// int型比较,预期值:3,实际值:Add(1, 2)
 EXPECT_EQ(3, Add(1, 2))
 // 
假如你的Add(1, 2) 结果为4的话,会在结果中输出:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(16): error: Value of: Add(1, 2)
   Actual: 4
 Expected:3
如果是将结果输出到xml里的话,将输出:(关于将结果输出为xml,见:玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数 - CoderZh - 博客园)

<testcase name="Demo" status="run" time="0" classname="AddTest">
       <failure message="Value of: Add(1, 2)   Actual: 4 Expected: 3" type=""><![CDATA[g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp:16
 Value of: Add(1, 2)
   Actual: 4
 Expected: 3]]></failure>
 </testcase>

如果你对自动输出的出错信息不满意的话,你还可以通过操作符<<将一些自定义的信息输出,通常,这对于调试或是对一些检查点的补充说明来说,非常有用!
下面举个例子:
 如果不使用<<操作符自定义输出的话:
for (int i = 0; i < x.size(); ++i)
 {
     EXPECT_EQ(x[i], y[i]);
 }
 看到的结果将是这样的,你根本不知道出错时 i 等于几:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i]
   Actual: 4
 Expected: x[i]
 Which is: 3
如果使用<<操作符将一些重要信息输出的话:
for (int i = 0; i < x.size(); ++i)
 {
     EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
 }
从输出结果中就可以定位到在 i = 2 时出现了错误。这样的输出结果看起来更加有用,容易理解:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i]
   Actual: 4
 Expected: x[i]
 Which is: 3
 Vectors x and y differ at index 2
三、布尔值检查
| Fatal assertion | Nonfatal assertion | Verifies | 
| ASSERT_TRUE(condition); | EXPECT_TRUE(condition); | condition is true | 
| ASSERT_FALSE(condition); | EXPECT_FALSE(condition); | condition is false | 
四、数值型数据检查
  
| 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 | 
五、字符串检查
  
| Fatal assertion | Nonfatal assertion | Verifies | 
| ASSERT_STREQ(expected_str, actual_str); | EXPECT_STREQ(expected_str, actual_str); | the two C strings have the same content | 
| ASSERT_STRNE(str1, str2); | EXPECT_STRNE(str1, str2); | the two C strings have different content | 
| ASSERT_STRCASEEQ(expected_str, actual_str); | EXPECT_STRCASEEQ(expected_str, actual_str); | the two C strings have the same content, ignoring case | 
| ASSERT_STRCASENE(str1, str2); | EXPECT_STRCASENE(str1, str2); | the two C strings have different content, ignoring case | 
*STREQ*和*STRNE*同时支持char*和wchar_t*类型的,*STRCASEEQ*和*STRCASENE*却只接收char*,估计是不常用吧。下面是几个例子:

TEST(StringCmpTest, Demo)
 {
     char* pszCoderZh = "CoderZh";
     wchar_t* wszCoderZh = L"CoderZh";
     std::string strCoderZh = "CoderZh";
     std::wstring wstrCoderZh = L"CoderZh";
     EXPECT_STREQ("CoderZh", pszCoderZh);
     EXPECT_STREQ(L"CoderZh", wszCoderZh);
     EXPECT_STRNE("CnBlogs", pszCoderZh);
     EXPECT_STRNE(L"CnBlogs", wszCoderZh);
     EXPECT_STRCASEEQ("coderzh", pszCoderZh);
     //EXPECT_STRCASEEQ(L"coderzh", wszCoderZh);    不支持
     EXPECT_STREQ("CoderZh", strCoderZh.c_str());
     EXPECT_STREQ(L"CoderZh", wstrCoderZh.c_str());
 }

六、显示返回成功或失败
直接返回成功:SUCCEED();
返回失败:
| Fatal assertion | Nonfatal assertion | 
| FAIL(); | ADD_FAILURE(); | 
 
 
TEST(ExplicitTest, Demo)
 {
     ADD_FAILURE() << "Sorry"; // None Fatal Asserton,继续往下执行。
     //FAIL(); // Fatal Assertion,不往下执行该案例。
     SUCCEED();
 }

七、异常检查
  
| 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 | 
例如:

int Foo(int a, int b)
 {
     if (a == 0 || b == 0)
     {
         throw "don't do that";
     }
     int c = a % b;
     if (c == 0)
         return b;
     return Foo(b, c);
 }
 TEST(FooTest, HandleZeroInput)
 {
     EXPECT_ANY_THROW(Foo(10, 0));
     EXPECT_THROW(Foo(0, 5), char*);
 }
 
 
八、Predicate Assertions
在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:
| Fatal assertion | Nonfatal assertion | Verifies | 
| ASSERT_PRED1(pred1, val1); | EXPECT_PRED1(pred1, val1); | pred1(val1) returns true | 
| ASSERT_PRED2(pred2, val1, val2); | EXPECT_PRED2(pred2, val1, val2); | pred2(val1, val2) returns true | 
| ... | ... | ... | 
Google人说了,他们只提供<=5个参数的,如果需要测试更多的参数,直接告诉他们。下面看看这个东西怎么用。

bool MutuallyPrime(int m, int n)
 {
     return Foo(m , n) > 1;
 }
 TEST(PredicateAssertionTest, Demo)
 {
     int m = 5, n = 6;
     EXPECT_PRED2(MutuallyPrime, m, n);
 }
 
 
当失败时,返回错误信息:
error: MutuallyPrime(m, n) evaluates to false, where
 m evaluates to 5
 n evaluates to 6
如果对这样的输出不满意的话,还可以自定义输出格式,通过如下:
| Fatal assertion | Nonfatal assertion | Verifies | 
| ASSERT_PRED_FORMAT1(pred_format1, val1);` | EXPECT_PRED_FORMAT1(pred_format1, val1); | pred_format1(val1) is successful | 
| ASSERT_PRED_FORMAT2(pred_format2, val1, val2); | EXPECT_PRED_FORMAT2(pred_format2, val1, val2); | pred_format2(val1, val2) is successful | 
| ... | ... | 
用法示例:

testing::AssertionResult AssertFoo(const char* m_expr, const char* n_expr, const char* k_expr, int m, int n, int k) {
     if (Foo(m, n) == k)
         return testing::AssertionSuccess();
     testing::Message msg;
     msg << m_expr << " 和 " << n_expr << " 的最大公约数应该是:" << Foo(m, n) << " 而不是:" << k_expr;
     return testing::AssertionFailure(msg);
 }
 TEST(AssertFooTest, HandleFail)
 {
     EXPECT_PRED_FORMAT3(AssertFoo, 3, 6, 2);
 }

失败时,输出信息:
error: 3 和 6 的最大公约数应该是:3 而不是:2
是不是更温馨呢,呵呵。
九、浮点型检查
  
| 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 | 
同时,还可以使用:
EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
 EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);
十、Windows HRESULT assertions
  
| Fatal assertion | Nonfatal assertion | Verifies | 
| ASSERT_HRESULT_SUCCEEDED(expression); | EXPECT_HRESULT_SUCCEEDED(expression); | expression is a success HRESULT | 
| ASSERT_HRESULT_FAILED(expression); | EXPECT_HRESULT_FAILED(expression); | expression is a failure HRESULT | 
例如:
CComPtr shell;
 ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
 CComVariant empty;
 ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
十一、类型检查
类型检查失败时,直接导致代码编不过,难得用处就在这?看下面的例子:
 
 
template <typename T> class FooType {
 public:
     void Bar() { testing::StaticAssertTypeEq<int, T>(); }
 };
 TEST(TypeAssertionTest, Demo)
 {
     FooType<bool> fooType;
     fooType.Bar();
 }

十二、总结
本篇将常用的断言都介绍了一遍,内容比较多,有些还是很有用的。要真的到写案例的时候,也行只是一两种是最常用的,现在时知道有这么多种选择,以后才方便查询。
系列链接:
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)之八 - 打造自己的单元测试框架



















