gtest断言学习

1、前言
    作为一个成熟的单元测试框架,gtest自然拥有一些用于判断值是否与期望一致的断言。在gtest中,断言分为两大类:ASSERT_*和EXPECT_*。它们的区别在于,ASSERT_*类断言在失败时,会立即退出当前的测试用例(即其所在的函数,但不会结束整个测试);EXPECT_*类断言在失败时,会继续执行,不会退出当前测试用例。
    在每一个大类中,有分为多个小类别,它们分别用于不同目的的测试,如布尔测试、数值测试、字符串测试等等,下面我们逐个认识gtest中,为它们所定义的宏。

2、布尔测试
    布尔测试用于测试给定的值为真还是假,它们包括:
    *_TRUE(condition):期望condition为true,若condition为false,则断言失败;
    *_FALSE(condition):期望condition为false,若condition为true,则断言失败;
    其中“*“为”ASSERT“或者”EXPECT“,后续所有的宏都将采用这种形式。

3、数值比较测试
    数值比较测试即比较两个数值之间的大小关系,它们包括:
    *_EQ(expected, actual):expected == actual则成功,否则失败;
    *_NE(expected, actual):expedted !=  actual则成功,否则失败;
    *_LT(val1, val2):val1 < val2则成功,否则失败;
    *_LE(val1, val2):val1 <= val2 则成功,否则失败;
    *_GT(val1, val2):val1 > val2则成功,否则失败;
    *_GE(val1,val2): val1 >= val2则成功,否则失败;
    
4、浮点数类型比较
    gtest针对浮点数是否相等专门定义了宏,它们包括:
    *_FLOAT_EQ(expected, actual):expected与actual相差很小时成功,否则失败;
    *_DOUBLE_EQ(expected, actual):expected与actual相差很小时成功,否则失败;
    *_NEAR(val1, val2, abs):|val1 - val2| <= abs时成功,否则失败;

5、字符串类型比较
    对于字符串,gtest提供字符串相等及不等断言,但它们都只支持C类型的字符串,不支持C++中的std::string和std::wstring,它们包括:
    *_STREQ(expected, actual):同时支持char*和wchar_t*,expected和actual的字符串内容相同则成功,否则失败;
    *_STRNE(str1, str2):同时支持char*和wchar_t*,str1和str2字符串内容不同则成功,否则失败;
    *_STRCASEEQ(expected, actual):只支持char*, expected和actual的字符串内容相同则成功,否则失败;
    *_STRCASENE(str1, str2):只支持char*,str1和str2字符串内容不同则成功,否则失败;

6、执行成功与失败标记
    在gtest中,测试通过与否有三种状态,它们对应于一个枚举:
    enum Type {
        kSuccess,          // Succeeded.
        kNonFatalFailure,  // Failed but the test can continue.
        kFatalFailure      // Failed and the test should be terminated.
      };
    每一个枚举值都对应一个宏,通过这个宏我们可以返回相应的执行状态:
    kSuccess:成功,对应的宏为SUCCEED();
    kNonFatalFailure:虽然失败,但当前测试用例的后续测试仍然继续运行,对应ADD_FAIL();
    kFatalFailure:致命错误,当前测试用例后续测试不会执行,对应FAIL();

7、异常检查
    gtest中提供检查代码是否抛出异常的方法,它们包括:
    *_THROW(statement, exception_type):statement如果抛出exception_type类型异常则成功,否则失败;
    *_ANY_THROW(statement):只要statement抛出任何异常则成功,否则失败;
    *_NO_THROW(statement):只要statement抛出任何异常则失败,否则成功;

8、谓词检查
    在gtest中,有一系列的宏,它们第一个参数为运行的函数或可执行体(要求返回值能够转换为bool类型),后续为执行函数所需要的参数,然后这些宏会自动运行这个函数,如果函数返回true则断言成功,否则失败,它们包括:
    *_PRED1(pred,  param1):pred位可执行体,它接收一个参数,当pred(param1)返回true则断言成功,否则失败;
    *_PRED2(pred, param1, param2):pred位可执行体,它接收两个参数,当pred(param1, param2)返回true则断言成功,否则失败;
    … …
    gtest中最多提供了对5个参数的支持,即从*_PRED1到*_PRED5。如下测试代码:
   
  1. bool isEven(int n)  
  2.    {  
  3.     return !(n & 1);  
  4.    }  
  5.      
  6.    TEST(HelloGtest, FirstTest)  
  7.    {  
  8.     int n = 3;  
  9.     EXPECT_PRED1(isEven, n);  
  10.    }  
  bool isEven(int n)
     {
      return !(n & 1);
     }

     TEST(HelloGtest, FirstTest)
     {
      int n = 3;
      EXPECT_PRED1(isEven, n);
     }

    它的运行结果如下图所示:
    
    从图中可以看到,谓词断言比EXPECT_TRUE断言给了更加详细的错误信息,为了方便对比,我们给出EXPECT_TRUE的运行结果:
    
    当然,如果我们队输出的错误信息仍然不满意,还可以使用gtest中的格式化断言,它们包括:
    *_PRED_FORMAT1(pred_format1, param1):如果pred_format1(param1)失败,则会按用户自定义的format来输出错误信息;
    ……(同样支持最多5个参数)
    要使用这些宏,我们需要自己额外定义一个函数来提供对错误信息的格式化,依然以判断偶数为例:
     
  1. testing::AssertionResult AssertNumberIsEven(const char* n_expr, int n) {  
  2.      if (isEven(n))  
  3.       return testing::AssertionSuccess();  
  4.      testing::Message msg;  
  5.      msg <<  n_expr << ” is not an even number”;  
  6.      return testing::AssertionFailure(msg);  
  7.     }  
  8.       
  9.     TEST(HelloGtest, FirstTest)  
  10.     {  
  11.      int n = 3;  
  12.      EXPECT_PRED_FORMAT1(AssertNumberIsEven, n);  
  13.     }  
 testing::AssertionResult AssertNumberIsEven(const char* n_expr, int n) {
      if (isEven(n))
       return testing::AssertionSuccess();
      testing::Message msg;
      msg <<  n_expr << " is not an even number";
      return testing::AssertionFailure(msg);
     }

     TEST(HelloGtest, FirstTest)
     {
      int n = 3;
      EXPECT_PRED_FORMAT1(AssertNumberIsEven, n);
     }

    其中AssertNumberIsEven这个函数即我们需要额外定义的函数,它返回一个testing::AssertionResult,在这个函数中,如果用于*_PRED_FORMAT1,则它最第一个参数为一个const char*类型,用于保存格式化后的错误信息,后续为待测试函数的参数;如果用于*_PRED_FORMAT2,则它前两个参数为const char*,后续两个为函数参数,以此类推…然后在调用*_PRED_FORMAT1时,将这个函数作为第一个参数传给宏即可,后续为待测试函数的参数,不包括上述的字符串。
    运行结果如下所示:
    

9、windows HRESULT检查
    它们包括:
    *_HRESULT_SUCCEEDED及*_HRESULT_FAILED。

10、类型检查
    gtest中的类型检查为testting::StaticAssertTypeEq,它是一个静态检查,主要用于模板编程之中,如果类型检查失败则无法通过编译,这样可以避免在运行时程序出错。这就类似于c++ 11中的static_assert一样。    


11、总结

    本章我们主要罗列了gtest中的一些断言的宏,及其使用。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值