Question

One of my favorite unit testing frameworks is PHPUnit because it supports test dependencies (i.e. the ability to mark tests as dependent upon other tests, running the dependent tests conditionally on the success of their dependencies). I've been using the Boost testing framework more recently to test my C++ code, and while it suits most of my unit testing needs, it doesn't appear to support test dependencies.

I've scoured the documentation for the Boost testing framework and have found various hints that Boost supports this feature, but I've yet to find a documentation page or any concrete examples of test dependency support in Boost. Are the previously given pages red herrings, or does the Boost testing framework actually support test dependencies?

Was it helpful?

Solution

Well, you've found yourself that the feature is there and according to the links, it's there for end user to use. It's not documented by accident and "should be added soon" (as per links).

Now, here's a nother post I've found which uses feature: http://boost.2283326.n4.nabble.com/Unit-Test-Framework-strange-behaviour-of-test-unit-depends-on-td2653654.html

Sample from there (unfortunately, looks like no BOOST_AUTO_TEST_CASE works there). Also note that code is incorrect because Dependency() is never called and therefore dependent test doesn't run as well.

#include <boost/test/included/unit_test.hpp>

using boost::unit_test::test_suite;

void Dependency()
{
  BOOST_MESSAGE( "Dependency!" );
  BOOST_CHECK( 1 );
}

void TC_TestCase()
{
  BOOST_MESSAGE( "A test case!" );
  BOOST_CHECK( 1 );
}

test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
  test_suite* ts = BOOST_TEST_SUITE( "Test_Test" );

  ts->add( BOOST_TEST_CASE( &TC_TestCase ) );

/*1*/  ts->depends_on( BOOST_TEST_CASE( &Dependency ) );

  return ts;
} 

Update

Performed some experimenting and here's an example with automatic test/suits and dependencies. Some notes about code:

  1. Boost here is 1.42, there may be slight differences for newer versions.
  2. If you put test_suite2 after test_suite1 in the cpp file, keeping dependencies the same, test_suite1 will be always skipped because test_suite2 is not run before it.
  3. I made test_case4 to fail so that test_suite1 is skipped, but if test_case4 succeeds, test_suite1 does execute.
  4. I'm pretty sure you'll be able to make dependencies registration much prettier and shorter.

The code:

#include <boost/test/included/unit_test.hpp>
using namespace boost::unit_test;

BOOST_AUTO_TEST_SUITE(test_suite2)
BOOST_AUTO_TEST_CASE(test_case4)
{
    BOOST_CHECK(false);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(test_suite1)
BOOST_AUTO_TEST_CASE(test_case1) 
{ 
    BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE(test_case2) 
{
    BOOST_CHECK(true);
}

BOOST_AUTO_TEST_SUITE_END()


//____________________________________________________________________________//

test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
    const auto testSuite1Id = framework::master_test_suite().get("test_suite1");

    if( testSuite1Id != INV_TEST_UNIT_ID ) {
        auto test_suite1 = &framework::get<test_suite>( testSuite1Id );

        const auto testSuite2Id = framework::master_test_suite().get("test_suite2");
        if (testSuite2Id != INV_TEST_UNIT_ID) {
            auto testSuite2 = &framework::get<test_suite>( testSuite2Id );

            const auto testCase4Id = testSuite2->get("test_case4");
            if (testCase4Id != INV_TEST_UNIT_ID) {
                // test_suite1 depends on test_suite2/test_case4 
                test_suite1->depends_on( &framework::get<test_case>( testCase4Id ));
            }
        }
    }

    return 0;
}

Output:

Running 3 test cases...
Entering test suite "Master Test Suite"
Entering test suite "test_suite2"
Entering test case "test_case4"
<blahblahblah>/consoleapplication5/consoleapplication5.cpp(10): error in "test_case4": check false failed
Leaving test case "test_case4"; testing time: 14ms
Leaving test suite "test_suite2"
Test suite "test_suite1"is skipped
Leaving test suite "Master Test Suite"

*** 1 failure detected in test suite "Master Test Suite"

OTHER TIPS

Starting on Boost 1.59 you have better tools for this: depends_on: http://www.boost.org/doc/libs/1_59_0/libs/test/doc/html/boost_test/utf_reference/test_org_reference/decorator_depends_on.html

Usage is pretty simple (from Boost docu):

namespace utf = boost::unit_test;

BOOST_AUTO_TEST_CASE(test3, * utf::depends_on("s1/test1"))
{
  BOOST_TEST(false);
}

BOOST_AUTO_TEST_CASE(test4, * utf::depends_on("test3"))
{
  BOOST_TEST(false);
}

BOOST_AUTO_TEST_SUITE(s1)

  BOOST_AUTO_TEST_CASE(test1)
  {
    BOOST_TEST(true);
  }

BOOST_AUTO_TEST_SUITE_END()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top