gtest 学习二

再接再励,在Primer之后接着走向AdvancedGuide

其他的断言:

  • 明确的失败和成功

这里列了三个断言,

FAIL(); ADD_FAILURE(); ADD_FAILURE_AT("file_path", line_number);

这三个断言根据举例应该是明确型断言,只不过针对失败定了三个等级。加上SCCEED()就是四个等级。应用实例就是:

1 switch(expression) {
2   case 1: ... some checks ...
3   case 2: ... some other checks
4   ...
5   default: FAIL() << "We shouldn't get here.";
6 }
  • 例外断言

用来检测一段代码扔出异常。分为ASSERT和EXPECT两种

Fatal assertion Nonfatal assertion Verifies
ASSERT_THROW(statementexception_type); EXPECT_THROW(statementexception_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

代码实例:

1 ASSERT_THROW(Foo(5), bar_exception);
2 
3 EXPECT_NO_THROW({
4   int n = 5;
5   Bar(&n);
6 });
  • 针对更好的错误信息的谓语断言

即使Gtest里面断言非常的充足,但是还是不够的,因为我们没有办法预期使用者的所有可能进入的情形。由于缺少比较好的宏,有些时候我们不得不用 EXPECT_TRUE()去测试一个复杂的语句。这样就导致没有显示足够的信息而带来的麻烦。针对这种问题,有的开发人员会自己组织错误信息,并把它们加入到EXPECT_TRUE()当中,但是这种方法有时候会显得很笨拙,特别是语句计算代价太大或者其他不良情况的时候。

Gtest给你提供了一下三种选择:

  1. 用一个已存在的bool函数:  
    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
    ... ... ...

    从宏的形式可以理解,宏的第一个参数是一个bool函数,后面两个或者多个参数是bool函数的变量,当调用断言宏的时候,bool函数的返回值既是这个断言的成功或者失败。举个简单的例子:
    1 // Returns true iff m and n have no common divisors except 1.
    2 bool MutuallyPrime(int m, int n) { ... }
    3 const int a = 3;
    4 const int b = 4;
    5 const int c = 10;

     EXPECT_PRED2(MutuallyPrime, a, b)将会成功, EXPECT_PRED2(MutuallyPrime, b, c)将会失败。注意一下两点:                                  1)当你使用这种方法遇到no matching function to call错误的时候,请到此查阅:http://code.google.com/p/googletest/wiki/V1_7_FAQ#The_compiler_complains_%22no_matching_function_to_call%22                       2)现在gtest提供的谓语断言最多只能有5个参数。

  2. 用一个能返回断言结果的函数:用一个断言结果对象来代表断言的结果,对象里面可以有结果的具体描述流。可以用工厂函数创建一个断言结果。
     1 namespace testing {
     2 
     3 // Returns an AssertionResult object to indicate that an assertion has
     4 // succeeded.
     5 AssertionResult AssertionSuccess();
     6 
     7 // Returns an AssertionResult object to indicate that an assertion has
     8 // failed.
     9 AssertionResult AssertionFailure();
    10 
    11 }

    可以在断言结果对象中使用<<操作符插入消息。为了在bool断言中提供更加详细的信息,可以写一个断言函数返回的是断言对象而不是bool变量。例如:定义IsEven()

    1 ::testing::AssertionResult IsEven(int n) {
    2   if ((n % 2) == 0)
    3     return ::testing::AssertionSuccess();
    4   else
    5     return ::testing::AssertionFailure() << n << " is odd";
    6 }

    而不是定义如下:

    1 bool IsEven(int n) {
    2   return (n % 2) == 0;
    3 }

    如果失败了会返回如下信息:

    Value of: IsEven(Fib(4))
         Actual: false (*3 is odd*)
       Expected: true

    而不是朦胧的

     Value of: IsEven(Fib(4))
         Actual: false
       Expected: true

    你也可以为对的断言加入描述信息如下:

    1 ::testing::AssertionResult IsEven(int n) {
    2   if ((n % 2) == 0)
    3     return ::testing::AssertionSuccess() << n << " is even";
    4   else
    5     return ::testing::AssertionFailure() << n << " is odd";
    6 }

    将会打印出

      Value of: IsEven(Fib(6))
         Actual: true (8 is even)
       Expected: false
  3. 用一个断言格式化:如果上述两中方法不合适,你可以用断言格式化
    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 PredicateFormattern(const char* expr1, const char* expr2, ... const char* exprn, T1 val1, T2val2, ... Tn valn);

    where val1val2, ..., and valn are the values of the predicate arguments, and expr1expr2, ..., and exprn are the corresponding expressions as they appear in the source code. The types T1T2, ..., and Tn can be either value types or reference types. For example, if an argument has typeFoo, you can declare it as either Foo or const Foo&, whichever is appropriate.举例如下:

     1 // Returns the smallest prime common divisor of m and n,
     2 // or 1 when m and n are mutually prime.
     3 int SmallestPrimeCommonDivisor(int m, int n) { ... }
     4 
     5 // A predicate-formatter for asserting that two integers are mutually prime.
     6 ::testing::AssertionResult AssertMutuallyPrime(const char* m_expr,
     7                                                const char* n_expr,
     8                                                int m,
     9                                                int n) {
    10   if (MutuallyPrime(m, n))
    11     return ::testing::AssertionSuccess();
    12  
    13   return ::testing::AssertionFailure()
    14       << m_expr << " and " << n_expr << " (" << m << " and " << n
    15       << ") are not mutually prime, " << "as they have a common divisor "
    16       << SmallestPrimeCommonDivisor(m, n);
    17 }

    当你输入如下:

    EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c);

    得到的消息是:

    b and c (4 and 10) are not mutually prime, as they have a common divisor 2.

     

今晚主要学习了几个新的断言,主要作用是使断言信息更完善,断言方法更方便易用。

 

 

posted @ 2014-03-14 00:07  虾米的虾皮  阅读(389)  评论(0编辑  收藏  举报