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

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.

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 the test suite means skipping the execution of every test unit inside.

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.) Test case test3 has a precondition that at either test1 or test2 passed. The precondition is satisfied, therefore test3 is run (and fails). Test case test4 has a precondition that either test2 or test3 passed. Since they both failed, the precondition is not satisfied, therefore test4 is skipped.


PrevUpHomeNext