Home | History | Annotate | Download | only in docs
      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