Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Global fixture
PrevUpHomeNext

Any global initialization that needs to be performed before any test begins, or a cleanup that is to be performed after all tests are finished is called a global fixture. A global fixture is equivalent to a test-suite entry/exit fixture (executed once), where in this case the test-suite is the master test suite.

The Unit Test Framework global fixture design is based on the generic test class fixture model. The global fixture design allows any number of global fixtures to be defined in any test file that constitutes a test module. Though some initialization can be implemented in the test module initialization function, there are several reasons to prefer the global fixture approach:

  • There is no place for cleanup/teardown operations in the initialization function.
  • Unlike the initialization function, the global fixture construction, setup and teardown methods invocation are guarded by the execution monitor. That means that all uncaught errors that occur during initialization are properly reported.
  • Any number of different global fixtures can be defined, which allows you to split initialization code by category.
  • The fixture allows you to place matching setup/teardown code in close vicinity in your test module code.
  • If the whole test tree is constructed automatically, the initialization function is empty and auto-generated by the Unit Test Framework. Introducing the initialization function can be more work than using the global fixture facility, while global fixture is more to the point.
  • Since all fixtures follow the same generic model you can easily switch from local per test case fixtures to the global one.

To define a global test module fixture you need:

  1. to implement a class that matches the fixture model
  2. and to pass the class as an argument to the macro BOOST_TEST_GLOBAL_FIXTURE.
BOOST_TEST_GLOBAL_FIXTURE( fixture_name );

// if your fixture is within a namespace
namespace enclosing_namespace {
  struct fixture_in_namespace { /* ... */ };
}

namespace enclosing_namespace {
  BOOST_TEST_GLOBAL_FIXTURE( fixture_in_namespace );
}
[Caution] Caution

The statement defining the global fixture has to reside in a single compilation unit (no header).

[Caution] Caution

Beware of other fixtures in other compilation units having the same name: if the fixtures have different definition, this leads to an ODR violation.

Example: Global fixture

Code

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

struct MyGlobalFixture {
  MyGlobalFixture() {
      BOOST_TEST_MESSAGE( "ctor fixture i=" << i );
  }
  void setup() {
      BOOST_TEST_MESSAGE( "setup fixture i=" << i );
      i++;
  }
  void teardown() {
      BOOST_TEST_MESSAGE( "teardown fixture i=" << i );
      i += 2;
  }
  ~MyGlobalFixture() {
      BOOST_TEST_MESSAGE( "dtor fixture i=" << i );
  }
  static int i;
};
int MyGlobalFixture::i = 0;

BOOST_TEST_GLOBAL_FIXTURE( MyGlobalFixture );

BOOST_AUTO_TEST_CASE(test_case1)
{
  BOOST_TEST_MESSAGE("running test_case1");
  BOOST_TEST(MyGlobalFixture::i == 1);
}

BOOST_AUTO_TEST_CASE(test_case2)
{
  BOOST_TEST_MESSAGE("running test_case2");
  BOOST_TEST(MyGlobalFixture::i == 3);
}

Output

> fixture_04 --log_level=message
Running 2 test cases...
ctor fixture i=0
setup fixture i=0
running test_case1
running test_case2
./fixture_04.run-fail.cpp:42: error: in "test_case2": check MyGlobalFixture::i == 3 has failed [1 != 3]
teardown fixture i=1
dtor fixture i=3

*** 1 failure is detected in the test module "fixture_04"

PrevUpHomeNext