1<a id="top"></a> 2# Test cases and sections 3 4**Contents**<br> 5[Tags](#tags)<br> 6[Tag aliases](#tag-aliases)<br> 7[BDD-style test cases](#bdd-style-test-cases)<br> 8[Type parametrised test cases](#type-parametrised-test-cases)<br> 9[Signature based parametrised test cases](#signature-based-parametrised-test-cases)<br> 10 11While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style. 12 13Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#test-cases-and-sections). 14 15Test cases and sections are very easy to use in practice: 16 17* **TEST_CASE(** _test name_ \[, _tags_ \] **)** 18* **SECTION(** _section name_ **)** 19 20_test name_ and _section name_ are free form, quoted, strings. The optional _tags_ argument is a quoted string containing one or more tags enclosed in square brackets. Tags are discussed below. Test names must be unique within the Catch executable. 21 22For examples see the [Tutorial](tutorial.md#top) 23 24## Tags 25 26Tags allow an arbitrary number of additional strings to be associated with a test case. Test cases can be selected (for running, or just for listing) by tag - or even by an expression that combines several tags. At their most basic level they provide a simple way to group several related tests together. 27 28As an example - given the following test cases: 29 30 TEST_CASE( "A", "[widget]" ) { /* ... */ } 31 TEST_CASE( "B", "[widget]" ) { /* ... */ } 32 TEST_CASE( "C", "[gadget]" ) { /* ... */ } 33 TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ } 34 35The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases. 36 37For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run) 38 39Tag names are not case sensitive and can contain any ASCII characters. This means that tags `[tag with spaces]` and `[I said "good day"]` are both allowed tags and can be filtered on. Escapes are not supported however and `[\]]` is not a valid tag. 40 41### Special Tags 42 43All tag names beginning with non-alphanumeric characters are reserved by Catch. Catch defines a number of "special" tags, which have meaning to the test runner itself. These special tags all begin with a symbol character. Following is a list of currently defined special tags and their meanings. 44 45* `[!hide]` or `[.]` - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them. 46 47* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`. 48 49* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests. 50 51* `[!shouldfail]` - like `[!mayfail]` but *fails* the test if it *passes*. This can be useful if you want to be notified of accidental, or third-party, fixes. 52 53* `[!nonportable]` - Indicates that behaviour may vary between platforms or compilers. 54 55* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped), as a tag to all contained tests, e.g. tests in testfile.cpp would all be tagged `[#testfile]`. 56 57* `[@<alias>]` - tag aliases all begin with `@` (see below). 58 59* `[!benchmark]` - this test case is actually a benchmark. This is an experimental feature, and currently has no documentation. If you want to try it out, look at `projects/SelfTest/Benchmark.tests.cpp` for details. 60 61## Tag aliases 62 63Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form: 64 65 CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> ) 66 67Aliases must begin with the `@` character. An example of a tag alias is: 68 69 CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" ) 70 71Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden. 72 73## BDD-style test cases 74 75In addition to Catch's take on the classic style of test cases, Catch supports an alternative syntax that allow tests to be written as "executable specifications" (one of the early goals of [Behaviour Driven Development](http://dannorth.net/introducing-bdd/)). This set of macros map on to ```TEST_CASE```s and ```SECTION```s, with a little internal support to make them smoother to work with. 76 77* **SCENARIO(** _scenario name_ \[, _tags_ \] **)** 78 79This macro maps onto ```TEST_CASE``` and works in the same way, except that the test case name will be prefixed by "Scenario: " 80 81* **GIVEN(** _something_ **)** 82* **WHEN(** _something_ **)** 83* **THEN(** _something_ **)** 84 85These macros map onto ```SECTION```s except that the section names are the _something_s prefixed by "given: ", "when: " or "then: " respectively. 86 87* **AND_GIVEN(** _something_ **)** 88* **AND_WHEN(** _something_ **)** 89* **AND_THEN(** _something_ **)** 90 91Similar to ```GIVEN```, ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```GIVEN```s, ```WHEN```s and ```THEN```s together. 92 93> `AND_GIVEN` was [introduced](https://github.com/catchorg/Catch2/issues/1360) in Catch 2.4.0. 94 95When any of these macros are used the console reporter recognises them and formats the test case header such that the Givens, Whens and Thens are aligned to aid readability. 96 97Other than the additional prefixes and the formatting in the console reporter these macros behave exactly as ```TEST_CASE```s and ```SECTION```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer! 98 99## Type parametrised test cases 100 101In addition to `TEST_CASE`s, Catch2 also supports test cases parametrised 102by types, in the form of `TEMPLATE_TEST_CASE`, 103`TEMPLATE_PRODUCT_TEST_CASE` and `TEMPLATE_LIST_TEST_CASE`. 104 105* **TEMPLATE_TEST_CASE(** _test name_ , _tags_, _type1_, _type2_, ..., _typen_ **)** 106 107> [Introduced](https://github.com/catchorg/Catch2/issues/1437) in Catch 2.5.0. 108 109_test name_ and _tag_ are exactly the same as they are in `TEST_CASE`, 110with the difference that the tag string must be provided (however, it 111can be empty). _type1_ through _typen_ is the list of types for which 112this test case should run, and, inside the test code, the current type 113is available as the `TestType` type. 114 115Because of limitations of the C++ preprocessor, if you want to specify 116a type with multiple template parameters, you need to enclose it in 117parentheses, e.g. `std::map<int, std::string>` needs to be passed as 118`(std::map<int, std::string>)`. 119 120Example: 121```cpp 122TEMPLATE_TEST_CASE( "vectors can be sized and resized", "[vector][template]", int, std::string, (std::tuple<int,float>) ) { 123 124 std::vector<TestType> v( 5 ); 125 126 REQUIRE( v.size() == 5 ); 127 REQUIRE( v.capacity() >= 5 ); 128 129 SECTION( "resizing bigger changes size and capacity" ) { 130 v.resize( 10 ); 131 132 REQUIRE( v.size() == 10 ); 133 REQUIRE( v.capacity() >= 10 ); 134 } 135 SECTION( "resizing smaller changes size but not capacity" ) { 136 v.resize( 0 ); 137 138 REQUIRE( v.size() == 0 ); 139 REQUIRE( v.capacity() >= 5 ); 140 141 SECTION( "We can use the 'swap trick' to reset the capacity" ) { 142 std::vector<TestType> empty; 143 empty.swap( v ); 144 145 REQUIRE( v.capacity() == 0 ); 146 } 147 } 148 SECTION( "reserving smaller does not change size or capacity" ) { 149 v.reserve( 0 ); 150 151 REQUIRE( v.size() == 5 ); 152 REQUIRE( v.capacity() >= 5 ); 153 } 154} 155``` 156 157* **TEMPLATE_PRODUCT_TEST_CASE(** _test name_ , _tags_, (_template-type1_, _template-type2_, ..., _template-typen_), (_template-arg1_, _template-arg2_, ..., _template-argm_) **)** 158 159> [Introduced](https://github.com/catchorg/Catch2/issues/1468) in Catch 2.6.0. 160 161_template-type1_ through _template-typen_ is list of template template 162types which should be combined with each of _template-arg1_ through 163 _template-argm_, resulting in _n * m_ test cases. Inside the test case, 164the resulting type is available under the name of `TestType`. 165 166To specify more than 1 type as a single _template-type_ or _template-arg_, 167you must enclose the types in an additional set of parentheses, e.g. 168`((int, float), (char, double))` specifies 2 template-args, each 169consisting of 2 concrete types (`int`, `float` and `char`, `double` 170respectively). You can also omit the outer set of parentheses if you 171specify only one type as the full set of either the _template-types_, 172or the _template-args_. 173 174 175Example: 176```cpp 177template< typename T> 178struct Foo { 179 size_t size() { 180 return 0; 181 } 182}; 183 184TEMPLATE_PRODUCT_TEST_CASE("A Template product test case", "[template][product]", (std::vector, Foo), (int, float)) { 185 TestType x; 186 REQUIRE(x.size() == 0); 187} 188``` 189 190You can also have different arities in the _template-arg_ packs: 191```cpp 192TEMPLATE_PRODUCT_TEST_CASE("Product with differing arities", "[template][product]", std::tuple, (int, (int, double), (int, double, float))) { 193 TestType x; 194 REQUIRE(std::tuple_size<TestType>::value >= 1); 195} 196``` 197 198_While there is an upper limit on the number of types you can specify 199in single `TEMPLATE_TEST_CASE` or `TEMPLATE_PRODUCT_TEST_CASE`, the limit 200is very high and should not be encountered in practice._ 201 202* **TEMPLATE_LIST_TEST_CASE(** _test name_, _tags_, _type list_ **)** 203 204> [Introduced](https://github.com/catchorg/Catch2/issues/1627) in Catch 2.9.0. 205 206_type list_ is a generic list of types on which test case should be instantiated. 207List can be `std::tuple`, `boost::mpl::list`, `boost::mp11::mp_list` or anything with 208`template <typename...>` signature. 209 210This allows you to reuse the _type list_ in multiple test cases. 211 212Example: 213```cpp 214using MyTypes = std::tuple<int, char, float>; 215TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside std::tuple", "[template][list]", MyTypes) 216{ 217 REQUIRE(sizeof(TestType) > 0); 218} 219``` 220 221 222## Signature based parametrised test cases 223 224> [Introduced](https://github.com/catchorg/Catch2/issues/1609) in Catch 2.8.0. 225 226In addition to [type parametrised test cases](#type-parametrised-test-cases) Catch2 also supports 227signature base parametrised test cases, in form of `TEMPLATE_TEST_CASE_SIG` and `TEMPLATE_PRODUCT_TEST_CASE_SIG`. 228These test cases have similar syntax like [type parametrised test cases](#type-parametrised-test-cases), with one 229additional positional argument which specifies the signature. 230 231### Signature 232Signature has some strict rules for these tests cases to work properly: 233* signature with multiple template parameters e.g. `typename T, size_t S` must have this format in test case declaration 234 `((typename T, size_t S), T, S)` 235* signature with variadic template arguments e.g. `typename T, size_t S, typename...Ts` must have this format in test case declaration 236 `((typename T, size_t S, typename...Ts), T, S, Ts...)` 237* signature with single non type template parameter e.g. `int V` must have this format in test case declaration `((int V), V)` 238* signature with single type template parameter e.g. `typename T` should not be used as it is in fact `TEMPLATE_TEST_CASE` 239 240Currently Catch2 support up to 11 template parameters in signature 241 242### Examples 243 244* **TEMPLATE_TEST_CASE_SIG(** _test name_ , _tags_, _signature_, _type1_, _type2_, ..., _typen_ **)** 245 246Inside `TEMPLATE_TEST_CASE_SIG` test case you can use the names of template parameters as defined in _signature_. 247 248```cpp 249TEMPLATE_TEST_CASE_SIG("TemplateTestSig: arrays can be created from NTTP arguments", "[vector][template][nttp]", 250 ((typename T, int V), T, V), (int,5), (float,4), (std::string,15), ((std::tuple<int, float>), 6)) { 251 252 std::array<T, V> v; 253 REQUIRE(v.size() > 1); 254} 255``` 256 257* **TEMPLATE_PRODUCT_TEST_CASE_SIG(** _test name_ , _tags_, _signature_, (_template-type1_, _template-type2_, ..., _template-typen_), (_template-arg1_, _template-arg2_, ..., _template-argm_) **)** 258 259```cpp 260 261template<typename T, size_t S> 262struct Bar { 263 size_t size() { return S; } 264}; 265 266TEMPLATE_PRODUCT_TEST_CASE_SIG("A Template product test case with array signature", "[template][product][nttp]", ((typename T, size_t S), T, S), (std::array, Bar), ((int, 9), (float, 42))) { 267 TestType x; 268 REQUIRE(x.size() > 0); 269} 270``` 271 272 273--- 274 275[Home](Readme.md#top) 276