• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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