...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The Unit Test Framework provides a way for enabling or disabling a test unit execution. If a test case is disabled, it will not be run by the test runner. If a test suite is disabled, its status is inherited by the test units under its subtree, unless otherwise specified.
The run status can be overridden by the command line parameters: by providing the appropriate arguments to the command line, a disabled test may still be executed. The test unit filtering section covers this feature in details.
Warning | |
---|---|
There is a difference between a disabled test and a skipped test:
|
Decorator disabled
indicates that the test
unit's default run status
is false. This means that that test cases inside this
test unit will not be run by default, unless otherwise specified. Decorator
enabled
indicates that the test
unit's default run status is true. This means that that
test cases inside this test unit will be run by default, unless otherwise
specified.
Code |
---|
#define BOOST_TEST_MODULE decorator_05 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; BOOST_AUTO_TEST_SUITE(suite1, * utf::disabled()) BOOST_AUTO_TEST_CASE(test1) { BOOST_TEST(1 != 1); } BOOST_AUTO_TEST_CASE(test2, * utf::enabled()) { BOOST_TEST(2 != 2); } BOOST_AUTO_TEST_SUITE_END() |
Output |
---|
> decorator_05 Running 1 test case... test.cpp(14): error: in "suite1/test2": check 2 != 2 has failed [2 == 2] *** 1 failure is detected in the test module "decorator_05" > decorator_05 --list_content suite1* test1 test2* |
Syntactically, it is possible to apply both decorators enabled
and disabled
to the same
test unit. This is reported as set-up error when the test program is run.
Decorator enable_if
indicates that the test
unit's default run status
is either true or false, depending
on the value of Condition
.
This means that that test cases inside this test unit will or will not be
run by default.
Code |
---|
#define BOOST_TEST_MODULE decorator_06 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; const bool io_implemented = true; const bool db_implemented = false; BOOST_AUTO_TEST_CASE(test_io, * utf::enable_if<io_implemented>()) { BOOST_TEST(1 != 1); } BOOST_AUTO_TEST_CASE(test_db, * utf::enable_if<db_implemented>()) { BOOST_TEST(2 != 2); } |
Output |
---|
> decorator_06 Running 1 test case... test.cpp(11): error: in "test_io": check 1 != 1 has failed [1 == 1] *** 1 failure is detected in the test module "decorator_06" > decorator_06 --list_content test_io* test_db |
Decorator enable_if<true>()
is equivalent to decorator enabled()
. Similarly, enable_if<false>()
is equivalent to decorator disabled()
.
Decorator precondition
associates a predicate
with a test unit. Before the test unit is executed, the predicate is evaluated
with the test unit's ID passed as the argument. If it evaluates to false
, execution of the test unit is skipped.
Skipping a test suite means skipping the execution of every test unit inside.
Tip | |
---|---|
The precondition may return an |
Code |
---|
#define BOOST_TEST_MODULE decorator_08 #include <boost/test/included/unit_test.hpp> namespace utf = boost::unit_test; namespace tt = boost::test_tools; BOOST_AUTO_TEST_CASE(test1) { BOOST_TEST(true); } BOOST_AUTO_TEST_CASE(test2) { BOOST_TEST(false); } struct if_either { std::string tc1, tc2; if_either(std::string t1, std::string t2) : tc1(t1), tc2(t2) {} tt::assertion_result operator()(utf::test_unit_id) { auto& master = utf::framework::master_test_suite(); auto& collector = utf::results_collector_t::instance(); auto& test1_result = collector.results(master.get(tc1)); auto& test2_result = collector.results(master.get(tc2)); if (test1_result.passed() || test2_result.passed()) return true; tt::assertion_result ans(false); ans.message() << tc1 << " and " << tc2 << " failed"; return ans; } }; BOOST_AUTO_TEST_CASE(test3, * utf::precondition(if_either("test1", "test2"))) { BOOST_TEST(false); } BOOST_AUTO_TEST_CASE(test4, * utf::precondition(if_either("test2", "test3"))) { BOOST_TEST(false); } |
Output |
---|
> decorator_08 --log_level=test_suite Running 4 test cases... Entering test module "decorator_08" test.cpp(6): Entering test case "test1" test.cpp(6): Leaving test case "test1"; testing time: 1ms test.cpp(11): Entering test case "test2" test.cpp(13): error: in "test2": check false has failed test.cpp(11): Leaving test case "test2"; testing time: 2ms test.cpp(39): Entering test case "test3" test.cpp(41): error: in "test3": check false has failed test.cpp(39): Leaving test case "test3"; testing time: 2ms test.cpp(45): Test case "test4" is skipped because test2 and test3 failed Leaving test module "decorator_08"; testing time: 16ms *** 2 failures are detected in the test module "decorator_08" |
In the example above, the user defined a custom predicate if_either
that evaluates to true
if at
least one of the two specified tests passed. (It assumes that the tests are
registered in the specific order.)
test3
has a
precondition that at either test1
or test2
passed. The
precondition is satisfied, therefore test3
is run (and fails),
test4
has a
precondition that either test2
or test3
passed. Since
they both failed, the precondition is not satisfied, therefore test4
is skipped.
Note | |
---|---|
A |