Catch-断言宏

大部分的测试框架都有许多的断言宏去捕获所有可能的条件形式(_EQUALS, _NOTEQUALS, _GREATER_THAN 等等)。

Catch不一样,因为它分解了C风格条件表达式,大多数的形式都被简化为一两个你将一直使用的形式。也就是说,也有大量的辅助宏。我们来看一下所有的宏形式。

大多数的宏来自两种形式:

自然表达式

REQUIRE 族的宏测试一个表达式,当测试失败的时候终止单元测试。CHECK 族宏也用来测试表达式,但即使当前断言失败,也会继续执行后续的测试用例。如果你有一系列本质上正交的断言,这是很有用的它有助于你看到所有的结果而不是在第一次失败时停止。

  • REQUIRE( 表达式 )
  • CHECK( 表达式 )

评估并记录结果。如果抛出异常,它将捕获,报告并将失败的用例数加一。这就是你大部分时间将使用的宏。

示例:

CHECK( str == "string value" );
CHECK( thisReturnsTrue() );
REQUIRE( i == 42 );

  • REQUIRE_FALSE( 表达式 )
  • CHECK_FALSE( 表达式 )

评估表达式并记录逻辑不的结果。如果表达式抛一场将被捕获,记录并将失败的用例数加一(这些形式作为一种事实存在的解决方法存在!前缀表达式不能被分解)。

示例:

REQUIRE_FALSE( thisReturnsFalse() );

一定要注意“过于复杂”的表达式不能被分解而且会导致编译失败。这部分是出于实际的原因(为了保持底层的表达式模板机制最小化),部分是出于哲学原因(断言应该是简单和确定的)。
示例:

  • CHECK(a == 1 && b == 2); 这个表达式太复杂了,因为存在&&运算符。如果你想检查2个或更多的属性,你可以把表达式放到括号里,这样可以阻止分解工作,或者你需要把表达式分解成两个断言:CHECK( a == 1 ); CHECK( b == 2);
  • CHECK( a == 2 || b == 1 ); 这个表达式太复杂了,因为存在||运算符。如果你想要检查几个属性中的一个,你可以将表达式放入括号中(与&&不同,将表达式分解成几个检查是不可能的)。

浮点数比较

比较浮点数,特别是如果他们中至少有一个被计算的时候,必须非常小心,以便舍入误差和不精确的表示。
Catch提供了一种方法来执行宽容浮点值比较,该方法通过使用称为“Approx”的包装类。可以使用“Approx”两侧的比较表达式。它通过重载比较运算符来处理宽容。这是一个简单的例子:

REQUIRE( performComputation() == Approx( 2.1 ) );

这时会用合理的默认值来构造Approx,覆盖最简单情况下的舍入误差。如果这些还不够,每个Approx实例有3个调谐旋钮,可以用来定制你的计算。

  • epsilon - epsilon 设置误差比例。默认值是:
    std::numeric_limits::epsilon()*100
  • margin - margin设置绝对值,默认值是:0.0
  • scale - scale调整误差的乘数。默认值是:0.0

epsilon示例

Approx target = Approx(100).epsilon(0.01);
100.0 == target; // Obviously true
200.0 == target; // Obviously still false
100.5 == target; // True, because we set target to allow up to 1% error

margin示例

Approx target = Approx(100).margin(5);
100.0 == target; // Obviously true
200.0 == target; // Obviously still false
104.0 == target; // True, because we set target to allow absolute error up to 5

scale

如果scale可能是有用的,如果计算结果导致工作在不同的规模比使用的结果。因为允许大约价值和价值相比的区别主要是基于大约价值(允许差异计算的(大约::规模+约::值)*ε’),由此产生的比较可能需要重新调节是正确的。
Scale can be useful if the computation leading to the result worked on different scale than is used by the results. Since allowed difference between Approx's value and compared value is based primarily on Approx's value (the allowed difference is computed as (Approx::scale + Approx::value) * epsilon), the resulting comparison could need rescaling to be correct.

异常

  • REQUIRE_NOTHROW( 表达式 )

  • CHECK_NOTHROW( 表达式 )
    期望在评估表达式时,没有异常被抛出。

  • REQUIRE_THROWS( 表达式 )

  • CHECK_THROWS( 表达式 )
    期望在评估表达式时,有异常(任何类型)被抛出。

  • REQUIRE_THROWS_AS( 表达式, 异常类型 )

  • CHECK_THROWS_AS( 表达式, 异常类型 )

在评估表达式时,期望一个指定类型的异常被抛出。注意指定类型const&扩展,并且你不能包含自己。

  • REQUIRE_THROWS_WITH( 表达式, string or string matcher )
  • CHECK_THROWS_WITH( 表达式, string or string matcher )

期望一个异常被抛出,当转换成字符串的时候,与提供的stringstring matcher匹配(见下一节:匹配器)。

实例:

REQUIRE_THROWS_WITH( openThePodBayDoors(), Contains( "afraid" ) && Contains( "can't do that" ) );
REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" );
  • REQUIRE_THROWS_MATCHES( 表达式, 异常类型, 异常类型匹配器 )
  • CHECK_THROWS_MATCHES( 表达式, 异常类型, 异常类型匹配器 )
    期望一个特定异常类型的异常被抛出并且与提供的匹配器匹配(见下一节:匹配器)。

请注意THROW断言族期望期望单一的表达式,而不是语句或一系列的语句。如果你要检查更复杂的操作序列,你可以使用一个C++11的lambda表达式。

REQUIRE_NOTHROW([&](){
    int i = 1;
    int j = 2;
    auto k = i + j;
    if (k == 3) {
        throw 1;
    }
}());

匹配器表达式

为了支持匹配器,使用的形式略有不同。匹配器有自己的文档.

  • REQUIRE_THAT( lhs, 匹配器表达式 )
  • CHECK_THAT( lhs, 匹配器表达式 )

匹配器可以由操作符&&, ||!组成。

线程安全

当前Catch的断言不是线程安全的。更多细节,以及解决方法,请参阅部分限制页面.

你可能感兴趣的:(Catch-断言宏)