Boost unittest framework with dynamic linking and

2019-06-24 14:28发布

问题:

I am trying to setup a boost unittest framework with dynamic linking and manual setup (Not BOOST_AUTO_TEST_CASE). I have made a trivial example to reproduce my errors:

//SomeLib.cpp
#define BOOST_TEST_DYN_LINK
#include "SomeLib.h"
int getImportantNumber(){return 1729;}
int increaseNumber(int number){return number+1;}

//SomeTests.cpp
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "lib/SomeLib.h"
#include "SomeTests.h"
using namespace boost::unit_test;

void SomeTests::numberIs1729(){
    BOOST_CHECK(getImportantNumber() == 1729);
}
void SomeTests::increase(){
    BOOST_CHECK(increaseNumber(1) == 2);
}

//ChainedInc.cpp
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "lib/SomeLib.h"
#include "ChainedInc.h"
using namespace boost::unit_test;

void ChainedInc::incinc(){
    BOOST_CHECK(increaseNumber(increaseNumber(1)) == 3);
}
void ChainedInc::incincinc(){
    BOOST_CHECK(increaseNumber(increaseNumber(increaseNumber(1))) == 4);
}

//Master.cpp
#define BOOST_TEST_DYN_LINK
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/test/unit_test.hpp>
#include "SomeTests.h"

using namespace boost::unit_test;
test_suite* init_unit_test_suite( int, char** )
{
    test_suite* ts1 = BOOST_TEST_SUITE( "Suite1" );

    boost::shared_ptr<SomeTests> test1 ( new SomeTests());
    ts1->add( BOOST_TEST_CASE( boost::bind(&SomeTests::numberIs1729, test1)));
    ts1->add( BOOST_TEST_CASE( boost::bind(&SomeTests::increase, test1)));

    framework::master_test_suite().add( ts1 );
    return 0;
}

When I run this code I get the following error:

/usr/bin/g++ test/ChainedInc.cpp.1.o test/Master.cpp.1.o test/SomeTests.cpp.1.o lib/SomeLib.cpp.2.o -o /home/mto/src/manualBoost/build/test/app -Wl-Bdynamic -L/usr/lib64 -lboost_unit_test_framework

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

This is usally solved by adding

#define BOOST_TEST_DYN_LINK

to all test files and

#define BOOST_TEST_MODULE something

to exactly one arbitrary test file. However the last define does not work well when the boost tests are registered manually. If I try to run my tests after using this define I get

build/test/app

Test setup error: test tree is empty

See Boost test does not init_unit_test_suite. Is it possible to use boost manual registration and dynamic linking against boost?

回答1:

BOOST_TEST_MAIN should only ever be defined in one module. It pulls in a definition of main. If you define it in multiple modules, then you'll have multiply defined main.

See my documentation rewrite for explanation of these configuration macros.



回答2:

The required define is #define BOOST_TEST_MAIN as per your linked question.

Your code as presented does not contain this define (nor BOOST_TEST_MODULE)

As I understand the docs, you need BOOST_TEST_MAIN when you define init_unit_test_suite yourself and you use BOOST_TEST_MODULE if you use the automatic stuff:

BOOST_TEST_MODULE-- Define this flag to generate the test module initialization function, which uses the defined value to name the master test suite. In case of dynamic library variant default function main() implementation is generated as well


Also, an old example from the boost docs shows this:

test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
    test_suite* test = BOOST_TEST_SUITE( "Master test suite" );

    test->add( BOOST_TEST_CASE( &my_test_function ) );

    return test;  //++++++++++++++
}

which is what we do for master test suite setup (we're on Boost 1.44 atm.)

But your code above shows this:

    ...
    framework::master_test_suite().add( ts1 );
    return 0;
}

which seems to be from some newer part of the Boost.Test docs.

Maybe you need to return the master test suite (once) in the init_unit_test_suite function? Have you tried this?



回答3:

I managed to get Manual setup of test to work with dynamic linking to boost when I used the header only libraries.

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