...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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:
The following two methods are available for declaring a fixture attached to one particular test case:
BOOST_FIXTURE_TEST_CASE
in
place of BOOST_AUTO_TEST_CASE
, which
let access to the members of the fixture
fixture
, which does not let
access to the members but enables the definition of several fixtures
for one test case.
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 | |
---|---|
You can't access private members of fixture, but then why would you make anything private? |
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
decorator
By using the decorator fixture
, it is possible to:
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) |
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 | |
---|---|
If necessary you can reset the fixture for a particular test case using
the macro |
Note | |
---|---|
The fixture assignment is deep. In other words unless
reset by another |
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 | |
---|---|
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.