1 <a id="top"></a> 2 # Test fixtures 3 4 Although 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++ 7 class 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 31 The 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 34 Catch2 also provides `TEMPLATE_TEST_CASE_METHOD` and 35 `TEMPLATE_PRODUCT_TEST_CASE_METHOD` that can be used together 36 with templated fixtures and templated template fixtures to perform 37 tests for multiple different types. Unlike `TEST_CASE_METHOD`, 38 `TEMPLATE_TEST_CASE_METHOD` and `TEMPLATE_PRODUCT_TEST_CASE_METHOD` do 39 require the tag specification to be non-empty, as it is followed by 40 further macro arguments. 41 42 Also note that, because of limitations of the C++ preprocessor, if you 43 want to specify a type with multiple template parameters, you need to 44 enclose it in parentheses, e.g. `std::map<int, std::string>` needs to be 45 passed as `(std::map<int, std::string>)`. 46 In the case of `TEMPLATE_PRODUCT_TEST_CASE_METHOD`, if a member of the 47 type list should consist of more than single type, it needs to be enclosed 48 in another pair of parentheses, e.g. `(std::map, std::pair)` and 49 `((int, float), (char, double))`. 50 51 Example: 52 ```cpp 53 template< typename T > 54 struct Template_Fixture { 55 Template_Fixture(): m_a(1) {} 56 57 T m_a; 58 }; 59 60 TEMPLATE_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 64 template<typename T> 65 struct Template_Template_Fixture { 66 Template_Template_Fixture() {} 67 68 T m_a; 69 }; 70 71 template<typename T> 72 struct Foo_class { 73 size_t size() { 74 return 0; 75 } 76 }; 77 78 TEMPLATE_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 84 in single `TEMPLATE_TEST_CASE_METHOD` or `TEMPLATE_PRODUCT_TEST_CASE_METHOD`, 85 the limit is very high and should not be encountered in practice._ 86 87 --- 88 89 [Home](Readme.md#top) 90