1<a id="top"></a> 2# Test fixtures 3 4Although Catch allows you to group tests together as sections within a test case, it can still be convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure: 5 6```c++ 7class UniqueTestsFixture { 8 private: 9 static int uniqueID; 10 protected: 11 DBConnection conn; 12 public: 13 UniqueTestsFixture() : conn(DBConnection::createConnection("myDB")) { 14 } 15 protected: 16 int getID() { 17 return ++uniqueID; 18 } 19 }; 20 21 int UniqueTestsFixture::uniqueID = 0; 22 23 TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/No Name", "[create]") { 24 REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "")); 25 } 26 TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal", "[create]") { 27 REQUIRE(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs")); 28 } 29``` 30 31The two test cases here will create uniquely-named derived classes of UniqueTestsFixture and thus can access the `getID()` protected method and `conn` member variables. This ensures that both the test cases are able to create a DBConnection using the same method (DRY principle) and that any ID's created are unique such that the order that tests are executed does not matter. 32 33 34Catch2 also provides `TEMPLATE_TEST_CASE_METHOD` and 35`TEMPLATE_PRODUCT_TEST_CASE_METHOD` that can be used together 36with templated fixtures and templated template fixtures to perform 37tests for multiple different types. Unlike `TEST_CASE_METHOD`, 38`TEMPLATE_TEST_CASE_METHOD` and `TEMPLATE_PRODUCT_TEST_CASE_METHOD` do 39require the tag specification to be non-empty, as it is followed by 40further macro arguments. 41 42Also note that, because of limitations of the C++ preprocessor, if you 43want to specify a type with multiple template parameters, you need to 44enclose it in parentheses, e.g. `std::map<int, std::string>` needs to be 45passed as `(std::map<int, std::string>)`. 46In the case of `TEMPLATE_PRODUCT_TEST_CASE_METHOD`, if a member of the 47type list should consist of more than single type, it needs to be enclosed 48in another pair of parentheses, e.g. `(std::map, std::pair)` and 49`((int, float), (char, double))`. 50 51Example: 52```cpp 53template< typename T > 54struct Template_Fixture { 55 Template_Fixture(): m_a(1) {} 56 57 T m_a; 58}; 59 60TEMPLATE_TEST_CASE_METHOD(Template_Fixture,"A TEMPLATE_TEST_CASE_METHOD based test run that succeeds", "[class][template]", int, float, double) { 61 REQUIRE( Template_Fixture<TestType>::m_a == 1 ); 62} 63 64template<typename T> 65struct Template_Template_Fixture { 66 Template_Template_Fixture() {} 67 68 T m_a; 69}; 70 71template<typename T> 72struct Foo_class { 73 size_t size() { 74 return 0; 75 } 76}; 77 78TEMPLATE_PRODUCT_TEST_CASE_METHOD(Template_Template_Fixture, "A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test succeeds", "[class][template]", (Foo_class, std::vector), int) { 79 REQUIRE( Template_Template_Fixture<TestType>::m_a.size() == 0 ); 80} 81``` 82 83_While there is an upper limit on the number of types you can specify 84in single `TEMPLATE_TEST_CASE_METHOD` or `TEMPLATE_PRODUCT_TEST_CASE_METHOD`, 85the limit is very high and should not be encountered in practice._ 86 87--- 88 89[Home](Readme.md#top) 90