• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<a id="top"></a>
2# Assertion Macros
3
4**Contents**<br>
5[Natural Expressions](#natural-expressions)<br>
6[Exceptions](#exceptions)<br>
7[Matcher expressions](#matcher-expressions)<br>
8[Thread Safety](#thread-safety)<br>
9[Expressions with commas](#expressions-with-commas)<br>
10
11Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
12
13Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there is a rich set of auxiliary macros as well. We'll describe all of these here.
14
15Most of these macros come in two forms:
16
17## Natural Expressions
18
19The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails.
20The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure.
21
22* **REQUIRE(** _expression_ **)** and
23* **CHECK(** _expression_ **)**
24
25Evaluates the expression and records the result. If an exception is thrown, it is caught, reported, and counted as a failure. These are the macros you will use most of the time.
26
27Examples:
28```
29CHECK( str == "string value" );
30CHECK( thisReturnsTrue() );
31REQUIRE( i == 42 );
32```
33
34* **REQUIRE_FALSE(** _expression_ **)** and
35* **CHECK_FALSE(** _expression_ **)**
36
37Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure.
38(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed).
39
40Example:
41```
42REQUIRE_FALSE( thisReturnsFalse() );
43```
44
45Do note that "overly complex" expressions cannot be decomposed and thus will not compile. This is done partly for practical reasons (to keep the underlying expression template machinery to minimum) and partly for philosophical reasons (assertions should be simple and deterministic).
46
47Examples:
48* `CHECK(a == 1 && b == 2);`
49This expression is too complex because of the `&&` operator. If you want to check that 2 or more properties hold, you can either put the expression into parenthesis, which stops decomposition from working, or you need to decompose the expression into two assertions: `CHECK( a == 1 ); CHECK( b == 2);`
50* `CHECK( a == 2 || b == 1 );`
51This expression is too complex because of the `||` operator. If you want to check that one of several properties hold, you can put the expression into parenthesis (unlike with `&&`, expression decomposition into several `CHECK`s is not possible).
52
53
54### Floating point comparisons
55
56When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
57
58Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called `Approx`. `Approx` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
59
60```cpp
61REQUIRE( performComputation() == Approx( 2.1 ) );
62```
63
64Catch also provides a user-defined literal for `Approx`; `_a`. It resides in
65the `Catch::literals` namespace and can be used like so:
66```cpp
67using namespace Catch::literals;
68REQUIRE( performComputation() == 2.1_a );
69```
70
71`Approx` is constructed with defaults that should cover most simple cases.
72For the more complex cases, `Approx` provides 3 customization points:
73
74* __epsilon__ - epsilon serves to set the coefficient by which a result
75can differ from `Approx`'s value before it is rejected.
76_By default set to `std::numeric_limits<float>::epsilon()*100`._
77* __margin__ - margin serves to set the the absolute value by which
78a result can differ from `Approx`'s value before it is rejected.
79_By default set to `0.0`._
80* __scale__ - scale is used to change the magnitude of `Approx` for relative check.
81_By default set to `0.0`._
82
83#### epsilon example
84```cpp
85Approx target = Approx(100).epsilon(0.01);
86100.0 == target; // Obviously true
87200.0 == target; // Obviously still false
88100.5 == target; // True, because we set target to allow up to 1% difference
89```
90
91#### margin example
92```cpp
93Approx target = Approx(100).margin(5);
94100.0 == target; // Obviously true
95200.0 == target; // Obviously still false
96104.0 == target; // True, because we set target to allow absolute difference of at most 5
97```
98
99#### scale
100Scale can be useful if the computation leading to the result worked
101on different scale than is used by the results. Since allowed difference
102between Approx's value and compared value is based primarily on Approx's value
103(the allowed difference is computed as
104`(Approx::scale + Approx::value) * epsilon`), the resulting comparison could
105need rescaling to be correct.
106
107
108## Exceptions
109
110* **REQUIRE_NOTHROW(** _expression_ **)** and
111* **CHECK_NOTHROW(** _expression_ **)**
112
113Expects that no exception is thrown during evaluation of the expression.
114
115* **REQUIRE_THROWS(** _expression_ **)** and
116* **CHECK_THROWS(** _expression_ **)**
117
118Expects that an exception (of any type) is be thrown during evaluation of the expression.
119
120* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
121* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
122
123Expects that an exception of the _specified type_ is thrown during evaluation of the expression. Note that the _exception type_ is extended with `const&` and you should not include it yourself.
124
125* **REQUIRE_THROWS_WITH(** _expression_, _string or string matcher_ **)** and
126* **CHECK_THROWS_WITH(** _expression_, _string or string matcher_ **)**
127
128Expects that an exception is thrown that, when converted to a string, matches the _string_ or _string matcher_ provided (see next section for Matchers).
129
130e.g.
131```cpp
132REQUIRE_THROWS_WITH( openThePodBayDoors(), Contains( "afraid" ) && Contains( "can't do that" ) );
133REQUIRE_THROWS_WITH( dismantleHal(), "My mind is going" );
134```
135
136* **REQUIRE_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)** and
137* **CHECK_THROWS_MATCHES(** _expression_, _exception type_, _matcher for given exception type_ **)**
138
139Expects that exception of _exception type_ is thrown and it matches provided matcher (see next section for Matchers).
140
141
142_Please note that the `THROW` family of assertions expects to be passed a single expression, not a statement or series of statements. If you want to check a more complicated sequence of operations, you can use a C++11 lambda function._
143
144```cpp
145REQUIRE_NOTHROW([&](){
146    int i = 1;
147    int j = 2;
148    auto k = i + j;
149    if (k == 3) {
150        throw 1;
151    }
152}());
153```
154
155
156
157## Matcher expressions
158
159To support Matchers a slightly different form is used. Matchers have [their own documentation](matchers.md#top).
160
161* **REQUIRE_THAT(** _lhs_, _matcher expression_ **)** and
162* **CHECK_THAT(** _lhs_, _matcher expression_ **)**
163
164Matchers can be composed using `&&`, `||` and `!` operators.
165
166## Thread Safety
167
168Currently assertions in Catch are not thread safe.
169For more details, along with workarounds, see the section on [the limitations page](limitations.md#thread-safe-assertions).
170
171## Expressions with commas
172
173Because the preprocessor parses code using different rules than the
174compiler, multiple-argument assertions (e.g. `REQUIRE_THROWS_AS`) have
175problems with commas inside the provided expressions. As an example
176`REQUIRE_THROWS_AS(std::pair<int, int>(1, 2), std::invalid_argument);`
177will fail to compile, because the preprocessor sees 3 arguments provided,
178but the macro accepts only 2. There are two possible workarounds.
179
1801) Use typedef:
181```cpp
182using int_pair = std::pair<int, int>;
183REQUIRE_THROWS_AS(int_pair(1, 2), std::invalid_argument);
184```
185
186This solution is always applicable, but makes the meaning of the code
187less clear.
188
1892) Parenthesize the expression:
190```cpp
191TEST_CASE_METHOD((Fixture<int, int>), "foo", "[bar]") {
192    SUCCEED();
193}
194```
195
196This solution is not always applicable, because it might require extra
197changes on the Catch's side to work.
198
199---
200
201[Home](Readme.md#top)
202