Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Enabling or disabling test unit execution

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] Warning

There is a difference between a disabled test and a skipped test:

  • a disabled test has a run status set to disabled, and is completely discarded by the Unit Test Framework.
  • a skipped test is a test that has a run status set to enabled, but which execution has been skipped at runtime.

Unconditional run status

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.

Example: decorators enabled and disabled

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.

Compilation-time run status

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.

Example: decorator enable_if

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().

Runtime run status

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] Tip

The precondition may return an assertion_result instead of a boolean. In that case, the message contained in the assertion_result will be printed by the Unit Test Framework.

Example: decorator precondition

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.)

[Note] Note

A precondition that evaluates to false does not yield an error and does not fail the attached unit test. However the Unit Test Framework returns an error if the test tree is empty (see this section for more details).


PrevUpHomeNext