Boost logo

Boost :

From: Noel Llopis (nll_pub_at_[hidden])
Date: 2005-01-11 14:37:09


I've tried out the suggestions Gennadiy had for streamlining the use of
Boost.Test fixtures and suites, and I'm extremely pleased with the results.

This is what I ended up with (compiled and tested with gcc under Linux).
Feel free to adapt anything into Boost.Test:

#define BOOST_TEST_SUITE_MODULE( name ) \
namespace { \
static boost::unit_test::test_suite* suite = BOOST_TEST_SUITE( #name ); \
static boost::unit_test::ut_detail::auto_unit_test_registrar \
    BOOST_JOIN( test_registrar, __LINE__)( suite ); \
\
struct suite_registrar { \
    suite_registrar( boost::unit_test::test_case* tc ) { suite->add( tc ); } \
}; \
} \
/**/

#define BOOST_AUTO_UNIT_TEST_WITH_FIXTURE_AND_SUITE( fixture, test_name ) \
struct fixture ## test_name : public fixture { \
      void test_name(); \
}; \
\
void fixture ## test_name ## _invoker () \
{ \
    fixture ## test_name mt; \
    mt.test_name(); \
} \
\
static suite_registrar \
    BOOST_JOIN( suite_registrar, __LINE__) \
        ( boost::unit_test::create_test_case( fixture ## test_name ## _invoker,
#test_name " fixture " #fixture) ); \
void fixture ## test_name::test_name() \
/**/

#define BOOST_AUTO_UNIT_TEST_WITH_SUITE(test_name) \
static void test_name(); \
static suite_registrar \
    BOOST_JOIN( suite_registrar, __LINE__) \
        ( BOOST_TEST_CASE( test_name ) ); \
static void test_name() \
/**/

// Shortcuts to avoid lots of typing
#define TEST_F(fixture,test_name)
BOOST_AUTO_UNIT_TEST_WITH_FIXTURE_AND_SUITE(fixture,test_name)
#define TEST(test_name) BOOST_AUTO_UNIT_TEST_WITH_SUITE(test_name)

Now, if we can only have a unit_test_log_formatter that uses DebugOutputString,
that would be fantastic. I'd volunteer to look into it, but I don't use Windows
for development at home anymore.

A couple of questions:

What was the reason behind the choice of using the function
init_unit_test_suite() as the initialization point? Why not let the user create
main() and use a very simple object to accomplish the same thing. Something
along these lines:

int main ( int /* argc */, char* /* argv */ [] )
{
    test_suite * testsuite = BOOST_TEST_SUITE("Master test suite");
    testrunner runner(testsuite);
    return runner.run();
}

That way we can do whatever we want before and after the test runs
much more easily.

Also, if I wanted to add timings around each test, where would be
the best place to hook them up? I'm also interested in the timings
around the whole set of tests, but that's something I could accomplish
easily if we had an exposed main() function.

I think that with these changes, Boost.Test has tipped the balance as the
favorite. I'm going to have to run a few more tests, but if all continues to
look good, I'm going to put up another article on my web site with everything
I've learned about Boost.Test

Thanks.

--Noel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk