Boost logo

Boost Users :

From: Thijs Koerselman (thijskoerselman_at_[hidden])
Date: 2008-08-22 15:34:12


Hi,

I'm trying to integrate the unit test framework in a library I'm developing
but I'm really stuck at something. I suspect its something simple, but I've
tried everything I could think of and can't seem to figure it out.

My library is loaded as a 3rd party plugin in a host application. On windows
it's a dll on OSX its a loadable carbon bundle. I'm currently only
developing on OSX. When the bundle is loaded, its main function registers
the methods that make up the public interface.

So I trigger a method from the host which starts the unit testing. It's
something like this

    #define BOOST_TEST_NO_MAIN
    #undef nil // because of Carbon nil definition
    #include <boost/test/included/unit_test.hpp>
    using namespace boost::unit_test;

    /* UnitTest class declaration and other member functions */

    void UnitTest::run()
    {
        BOOST_GLOBAL_FIXTURE( MyConfig ); // setting log output stream
etc.
        unit_test_main( &init_mylib_test_suite, 0, 0 );
    }

    test_suite* init_mylib_test_suite( int argc, char* argv[] )
    {
        std::string header = "Testing MyLib ";
        header += MYLIB_VERSION_STRING;

        std::string rule = std::string(header.length(),'=');

        BOOST_MESSAGE(rule);
        BOOST_MESSAGE(header);
        BOOST_MESSAGE(rule);

        return 0;
    }

Then I'm trying to organize it so that I have different unit test suits for
each logical module within the library. I'm separating the test suits into
each its own compilation unit (object file output), because I don't want to
recompile all the tests if I change something in one of them.

So one testing module would have a source file with something like:

    #define BOOST_TEST_MODULE Example
    #define BOOST_TEST_NO_MAIN
    #undef nil // because of Carbon nil definition
    #include <boost/test/included/unit_test.hpp>
    using namespace boost::unit_test;

    BOOST_AUTO_TEST_SUITE( "MyModuleSuite" );

    BOOST_AUTO_TEST_CASE( test_case1 )
    {
        BOOST_CHECK( true );
    }

    BOOST_AUTO_TEST_CASE( test_case2 )
    {
        BOOST_CHECK( false );
    }

    BOOST_AUTO_TEST_SUITE_END()

With this approach I keep getting linker errors about a duplicate symbol
between these 2 object files that result from it :
"duplicate symbol
boost::unit_test::traverse_test_tree(boost::unit_test::test_case const&,
boost::unit_test::test_tree_visitor&)in ......"

I've tried linking the framework as a static and a dynamic library. I've
also tried including the framework by using the "BOOST_TEST_NO_LIB" flag.
All without luck.

Am I approaching this the wrong way? Am I missing something obvious?

I would really appreciate some help with this. Tips on how to best organize
the unit testing in my library are also very welcome.

Note that I'm testing the internals of my library, not just the public API,
so linking against the library from a simple command line app won't work.
The library is also dependant on the host API. In order for those parts to
work/initialize properly I'm forced to launch my plugin inside the host at
all time.

Cheers, Thijs



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net