doctest

FORK: The fastest feature-rich C++11/14/17/20 single-header testing framework
git clone https://git.neptards.moe/neptards/doctest.git
Log | Files | Refs | README

assertions.html (10927B)


      1 <!DOCTYPE html>
      2 <html>
      3 <title>assertions</title>
      4 <xmp theme="united" style="display:none;">
      5 
      6 ## Assertion macros
      7 
      8 Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
      9 
     10 **doctest** is different (but it's like [**Catch**](https://github.com/catchorg/Catch2) in this regard). Because it decomposes comparison 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.
     11 
     12 There are 3 levels of assert severity for all assertion macros:
     13 
     14 - ```REQUIRE``` - this level will immediately quit the test case if the assert fails and will mark the test case as failed.
     15 - ```CHECK``` - this level will mark the test case as failed if the assert fails but will continue with the test case.
     16 - ```WARN``` - this level will only print a message if the assert fails but will not mark the test case as failed.
     17 
     18 The ```CHECK``` level is mostly 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.
     19 
     20 All asserts evaluate the expressions only once and if they fail - the values are [**stringified**](stringification.html) properly. 
     21 
     22 Since **doctest** is [**thread-safe**](faq.html#is-doctest-thread-aware) all asserts and [**logging**](logging.html) macros can be used in threads spawned from test cases.
     23 
     24 Note that the ```REQUIRE``` level of asserts uses exceptions to end the current test case. It might be dangerous to use this level of asserts inside destructors of user-defined classes - if a destructor is called during stack unwinding due to an exception and a ```REQUIRE``` assert fails then the program will terminate. Also since C++11 all destructors are by default ```noexcept(true)``` unless specified otherwise so such an assert will lead to ```std::terminate()``` being called.
     25 
     26 ## Expression decomposing asserts
     27 
     28 These are of the form ```CHECK(expression)```  (Same for ```REQUIRE``` and ```WARN```).
     29 
     30 ```expression``` can be a binary comparison like ```a == b``` or just a single thing like ```vec.isEmpty()```.
     31 
     32 If an exception is thrown it is caught, reported, and counted as a failure (unless the assert is of level ```WARN```).
     33 
     34 Examples:
     35 
     36 ```
     37 CHECK(flags == state::alive | state::moving);
     38 CHECK(thisReturnsTrue());
     39 REQUIRE(i < 42);
     40 ```
     41 
     42 - Negating asserts - ```<LEVEL>_FALSE(expression)``` - evaluates the expression and records the _logical NOT_ of the result.
     43 
     44 These forms exist as a workaround for the fact that ```!``` prefixed expressions cannot be decomposed properly.
     45 
     46 Example:
     47 
     48 ```
     49 REQUIRE_FALSE(thisReturnsFalse());
     50 ```
     51 
     52 - Using the [**```DOCTEST_CONFIG_SUPER_FAST_ASSERTS```**](configuration.html#doctest_config_super_fast_asserts) config option can make compilation of asserts up to [**31-63%**](benchmarks.html#cost-of-an-assertion-macro) faster!
     53 - These asserts also have a ```_MESSAGE``` form - like ```CHECK_MESSAGE(expression, message)``` which is basically a code block ```{}``` with a scoped [**```INFO()```**](logging.html#info) logging macro together with the ```CHECK``` macro - that way the message will be relevant only to that assert. The binary/unary asserts don't have this variation yet.
     54 
     55 Examples:
     56 
     57 ```
     58 INFO("this is relevant to all asserts, and here is some var: ", local);
     59 
     60 CHECK_MESSAGE(a < b, "relevant only to this assert ", other_local, " more text!");
     61 
     62 CHECK(b < c); // here only the first INFO() will be relevant
     63 ```
     64 
     65 For more information about the ```INFO()``` macro visit the [logging page](logging.html).
     66 
     67 ## Binary and unary asserts
     68 
     69 These asserts don't use templates to decompose the comparison expressions for the left and right parts.
     70 
     71 These have the same guarantees as the expression decomposing ones but [**57-68% faster**](benchmarks.html#cost-of-an-assertion-macro) for compilation.
     72 
     73 ```<LEVEL>``` is one of 3 possible: ```REQUIRE```/```CHECK```/```WARN```.
     74 
     75 - ```<LEVEL>_EQ(left, right)``` - same as ```<LEVEL>(left == right)```
     76 - ```<LEVEL>_NE(left, right)``` - same as ```<LEVEL>(left != right)```
     77 - ```<LEVEL>_GT(left, right)``` - same as ```<LEVEL>(left >  right)```
     78 - ```<LEVEL>_LT(left, right)``` - same as ```<LEVEL>(left <  right)```
     79 - ```<LEVEL>_GE(left, right)``` - same as ```<LEVEL>(left >= right)```
     80 - ```<LEVEL>_LE(left, right)``` - same as ```<LEVEL>(left <= right)```
     81 - ```<LEVEL>_UNARY(expr)``` - same as ```<LEVEL>(expr)```
     82 - ```<LEVEL>_UNARY_FALSE(expr)``` - same as ```<LEVEL>_FALSE(expr)```
     83 
     84 Using the [**```DOCTEST_CONFIG_SUPER_FAST_ASSERTS```**](configuration.html#doctest_config_super_fast_asserts) config option can make the binary asserts to compile up to [**84-91%**](benchmarks.html#cost-of-an-assertion-macro) faster!
     85 
     86 ## Exceptions
     87 
     88 ```<LEVEL>``` is one of 3 possible: ```REQUIRE```/```CHECK```/```WARN```.
     89 
     90 - ```<LEVEL>_THROWS(expression)```
     91 
     92 Expects that an exception (of any type) is thrown during evaluation of the expression.
     93 
     94 - ```<LEVEL>_THROWS_AS(expression, exception_type)```
     95 
     96 Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
     97 
     98 Note that ```const``` and ```&``` are added to the exception type if missing (users shouldn't care) - the standard practice for exceptions in C++ is ```Throw by value, catch by (const) reference```.
     99 
    100 ```
    101 CHECK_THROWS_AS(func(), const std::exception&);
    102 CHECK_THROWS_AS(func(), std::exception); // same as above
    103 ```
    104 
    105 - ```<LEVEL>_THROWS_WITH(expression, c_string)```
    106 
    107 Expects that an exception is thrown during evaluation of the expression and is successfully translated to the _specified c string_ (see [**translating exceptions**](stringification.html#translating-exceptions)).
    108 
    109 ```
    110 CHECK_THROWS_WITH(func(), "invalid operation!");
    111 ```
    112 
    113 - ```<LEVEL>_THROWS_WITH_AS(expression, c_string, exception_type)```
    114 
    115 This is a combination of ```<LEVEL>_THROWS_WITH``` and ```<LEVEL>_THROWS_AS```.
    116 
    117 ```
    118 CHECK_THROWS_WITH_AS(func(), "invalid operation!", std::runtime_error);
    119 ```
    120 
    121 - ```<LEVEL>_NOTHROW(expression)```
    122 
    123 Expects that no exception is thrown during evaluation of the expression.
    124 
    125 Note that these asserts also have a ```_MESSAGE``` form - like ```CHECK_THROWS_MESSAGE(expression, message)``` - these work identically to the ```_MESSAGE``` form of the normal macros (```CHECK_MESSAGE(a < b, "this shouldn't fail")```) described earlier.
    126 
    127 One may use the [**```DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS```**](configuration.html#doctest_config_void_cast_expressions) config identifier to cast the expression in these asserts to void to avoid warnings or other issues - for example nodiscard statements whose result isn't checked. This will however limit the ability to write entire ```{}``` blocks of code as the expression (or multiple statements) but in that case a simple lambda can be used. This should have been the default behavior from day 1 of the framework...
    128 
    129 ## Using asserts out of a testing context
    130 
    131 Asserts can be used outside of a testing context (in code not called from a ```TEST_CASE()```) instead of [```assert()```](https://en.cppreference.com/w/cpp/error/assert).
    132 
    133 A ```doctest::Context``` object still has to be created somewhere and set as the default one using the ```setAsDefaultForAssertsOutOfTestCases()``` method - and then asserts will work. A handler can be registered by calling the ```setAssertHandler()``` method on the context object. If no handler is set then ```std::abort()``` is called on failure.
    134 
    135 The results would be best when using the [**```DOCTEST_CONFIG_SUPER_FAST_ASSERTS```**](configuration.html#doctest_config_super_fast_asserts) config identifier.
    136 
    137 Checkout the [**example**](../../examples/all_features/asserts_used_outside_of_tests.cpp) showcasing how that is done. For more information see the [**issue for the feature request**](https://github.com/doctest/doctest/issues/114).
    138 
    139 Currently [**logging macros**](logging.html) cannot be used for extra context for asserts outside of a test run. That means that the ```_MESSAGE``` variants of asserts are also not usable - since they are just a packed ```INFO()``` with an assert right after it.
    140 
    141 ## String containment
    142 
    143 ```doctest::Contains``` can be used to check whether the string passed to its constructor is contained within the string it is compared with. Here's a simple example:
    144 
    145 ```
    146 REQUIRE("foobar" == doctest::Contains("foo"));
    147 ```
    148 
    149 It can also be used with the ```THROWS_WITH``` family of assertion macros to check whether the thrown exception [translated to a string](stringification.html#translating-exceptions) contains the provided string. Here's another example:
    150 ```
    151 REQUIRE_THROWS_WITH(func(), doctest::Contains("Oopsie"));
    152 ```
    153 
    154 ## Floating point comparisons
    155 
    156 When 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.
    157 
    158 **doctest** provides a way to perform tolerant comparisons of floating point values through the use of a wrapper class called ```doctest::Approx```. ```doctest::Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a relative tolerance into account. Here's a simple example:
    159 
    160 ```
    161 REQUIRE(performComputation() == doctest::Approx(2.1));
    162 ```
    163 
    164 By default a small epsilon value (relative - in percentages) is used that covers many simple cases of rounding errors. When this is insufficient the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```doctest::Approx``` instance. e.g.:
    165 
    166 ```
    167 REQUIRE(22.0/7 == doctest::Approx(3.141).epsilon(0.01)); // allow for a 1% error
    168 ```
    169 
    170 When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```doctest::Approx``` instance.
    171 
    172 ## NaN checking
    173 
    174 Two NaN floating point numbers do not compare equal to each other. This makes it quite inconvenient to check for NaN while capturing the value.
    175 ```
    176 CHECK(std::isnan(performComputation()); // does not capture the result of the call
    177 ```
    178 
    179 **doctest** provides `doctest::IsNaN` which can be used in assertions to check if a float (or any other floating point fundamental type) is indeed NaN, outputting the actual value if it is not.
    180 ```
    181 CHECK(doctest::IsNaN(performComputation()); // captures the result!
    182 ```
    183 
    184 `IsNaN` is able to capture the value, even if negated via `!`.
    185 
    186 --------
    187 
    188 - Check out the [**example**](../../examples/all_features/assertion_macros.cpp) which shows many of these macros
    189 - Do not wrap assertion macros in ```try```/```catch``` - the REQUIRE macros throw exceptions to end the test case execution!
    190 
    191 ---------------
    192 
    193 [Home](readme.html#reference)
    194 
    195 <p align="center"><img src="../../scripts/data/logo/icon_2.svg"></p>
    196 
    197 
    198 </xmp>
    199 <script src="strapdown.js/strapdown.js"></script>
    200 </html>