Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Test case fixture

A test case fixture is a fixture consumed by a test case: the fixture setup is called before the test case executes, and the fixture teardown is called after the test case finished its execution, independently from its execution state.

The Unit Test Framework provides several ways of defining fixtures for test-cases, each of which having their properties:

Single test case fixture

The following two methods are available for declaring a fixture attached to one particular test case:

Fixture with BOOST_FIXTURE_TEST_CASE

BOOST_FIXTURE_TEST_CASE serves as a test case declaration with a fixture, and is meant be used in place of the test case declaration with BOOST_AUTO_TEST_CASE:

BOOST_FIXTURE_TEST_CASE(test_case_name, fixture_name);

The only difference from the macro BOOST_AUTO_TEST_CASE is the presence of an extra argument fixture_name. The public and protected members of the fixture are directly accessible from the test case body. Only one fixture can be attached to a test-case [4].

[Note] Note

You can't access private members of fixture, but then why would you make anything private?

Example: Per test case fixture

Code

#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>

struct F {
  F() : i( 0 ) { BOOST_TEST_MESSAGE( "setup fixture" ); }
  ~F()         { BOOST_TEST_MESSAGE( "teardown fixture" ); }

  int i;
};

BOOST_FIXTURE_TEST_CASE( test_case1, F )
{
  BOOST_TEST( i == 1 );
  ++i;
}

BOOST_FIXTURE_TEST_CASE( test_case2, F )
{
  BOOST_CHECK_EQUAL( i, 1 );
}

BOOST_AUTO_TEST_CASE( test_case3 )
{
  BOOST_TEST( true );
}

Output

> example --log_level=message
Running 3 test cases...
setup fixture
test.cpp(13): error in "test_case1": check i == 1 has failed
teardown fixture
setup fixture
test.cpp(19): error in "test_case2": check i == 1 has failed [0 != 1]
teardown fixture

*** 2 failures are detected in test suite "example"

In this example only test_case1 and test_case2 have fixture F assigned. You still need to refer to the fixture name in every test case. This section explains how a same fixture can be declared for a subtree under a test suite.

Fixture with fixture decorator

By using the decorator fixture, it is possible to:

[Note] Note

Using the decorator approach, it is not possible to access the members of the fixture (in case the fixture is implemented as a class)

Fixture for a complete subtree

If all test cases in a test sub tree require the same fixture (you can group test cases in a test suite based on a fixture required) you can make another step toward an automation of a test fixture assignment. To assign the same shared fixture for all test cases in a test suite, use the macro BOOST_FIXTURE_TEST_SUITE in place of the macro BOOST_AUTO_TEST_SUITE for automated test suite creation and registration.

BOOST_FIXTURE_TEST_SUITE(suite_name, fixture_name);

Once again the only difference from the macro BOOST_AUTO_TEST_SUITE usage is the presence of an extra argument - the fixture name. And now, you not only have direct access to the public and protected members of the fixture, but also do not need to refer to the fixture name in test case definition. All test cases assigned the same fixture automatically.

[Tip] Tip

If necessary you can reset the fixture for a particular test case using the macro BOOST_FIXTURE_TEST_CASE. Similarly you can reset the fixture for a particular sub test suite using BOOST_FIXTURE_TEST_SUITE.

[Note] Note

The fixture assignment is deep. In other words unless reset by another BOOST_FIXTURE_TEST_SUITE or BOOST_FIXTURE_TEST_CASE definition the same fixture is assigned to all test cases of a test suite, including ones that belong to the sub test suites.

Example: Test suite level fixture

Code

#define BOOST_TEST_MODULE fixture_02
#include <boost/test/included/unit_test.hpp>

struct F {
  F() : i( 0 ) { BOOST_TEST_MESSAGE( "setup fixture" ); }
  ~F()         { BOOST_TEST_MESSAGE( "teardown fixture" ); }

  int i;
};

BOOST_FIXTURE_TEST_SUITE(s, F)

  BOOST_AUTO_TEST_CASE(test_case1)
  {
    BOOST_TEST_MESSAGE("running test_case1");
    BOOST_TEST(i == 0);
  }

  BOOST_AUTO_TEST_CASE(test_case2)
  {
    BOOST_TEST_MESSAGE("running test_case2");
    BOOST_TEST(i == 0);
  }

BOOST_AUTO_TEST_SUITE_END()

Output

> fixture_02 --log_level=message
Running 2 test cases...
setup fixture
running test_case1
teardown fixture
setup fixture
running test_case2
teardown fixture

*** No errors detected
[Caution] Caution

The fixture constructor/setup and teardown/destructor is called for each test cases (the state of the fixture is not shared among the test cases).



[4] it is still possible to define a class inheriting from several fixtures, that will act as a proxy fixture.


PrevUpHomeNext