views:

592

answers:

2

The Boost.Test documentation and examples don't really seem to contain any non-trivial examples and so far the two tutorials I've found here and here while helpful are both fairly basic.

I would like to have a master test suite for the entire project, while maintaining per module suites of unit tests and fixtures that can be run independently. I'll also be using a mock server to test various networking edge cases.

I'm on Ubuntu 8.04, but I'll take any example Linux or Windows since I'm writing my own makefiles anyways.

Edit

As a test I did the following:

// test1.cpp
#define BOOST_TEST_MODULE Regression
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(test1_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(2 < 1);
}

BOOST_AUTO_TEST_SUITE_END()

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

BOOST_AUTO_TEST_SUITE(test2_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(1<2);
}

BOOST_AUTO_TEST_SUITE_END()

Then I compile it: g++ test1.cpp test2.cpp -o tests

This gives me about a bazillion "multiple definition of" errors during linking.

When it's all in a single file it works fine.

+4  A: 

I don't know what else you really need than what's in the later tutorial. I've done everything I need to in just that way. Not sure I understand your description either.

One thing that you might be asking for is the ability to have more than one .cpp file in your test program. That's as simple as only defining BOOST_TEST_MODULE in one of those .cpp files. We have a "driver.cpp" file in all our test programs that just defines that and includes the unit test header. All the rest of the .cpp files (scoped by module or concept) only include the unit test header, they do not define that variable.

If you want to both be able to compile them together and compile them separately then you could use your own -D variable to define BOOST_TEST_MODULE or not.

If you're looking for a way to run a bunch of test programs in one single run and get a report then you could look at the automake method of doing tests or, better yet, the CMake method (CTest). Pretty sure you can use CTest from your own makefile if you insist.

Noah Roberts
As a test I created 2 files with auto test suites and auto test cases and defined `BOOST_TEST_MODULE` in only one of the files. During linking I got about a bazillion "multiple definition of" errors. Everything works fine when it's all in one file.
Robert S. Barnes
Try without the BOOST_AUTO_TEST_SUITE() definitions. I don't use that. It may be that there are slightly different steps that are needed if you use that macro. Trying to remove them will solve your build error if that's the case and then if you do need them some further experimentation will be needed. Also, don't name both tests Test1. I have had trouble with that when two tests in different files have the same name. In fact, try fixing that first.
Noah Roberts
Yeah, after reviewing the link posted below in the comment that includes code resembling your edit code (and has two Test1 definitions) I think that this multiple definition of one test is the issue. The linked tutorial doesn't share this feature and uses different names even within different suites.
Noah Roberts
+1 Thanks, I finally figured out the whole solution if you're interested.
Robert S. Barnes
Yeah, I'd be interested. I have something that works but am always open to new methods.
Noah Roberts
+1  A: 

C++ Unit Testing With Boost.Test

The above is a brilliant article and better than the actual Boost documentation.

Edit:

I also wrote a Perl script which will auto-generate the makefile and project skeleton from a list of class names, including both the "all-in-one" test suite and a stand alone test suite for each class. It's called makeSimple and can be downloaded from Sourceforge.net.

What I found to be the basic problem is that if you want to split your tests into multiple files you have to link against the pre-compiled test runtime and not use the "headers only" version of Boost.Test. You have to add #define BOOST_TEST_DYN_LINK to each file and when including the Boost headers for example use <boost/test/unit_test.hpp> instead of <boost/test/included/unit_test.hpp>.

So to compile as a single test:

g++ test_main.cpp test1.cpp test2.cpp -lboost_unit_test_framework -o tests

or to compile an individual test:

g++ test1.cpp -DSTAND_ALONE -lboost_unit_test_framework -o test1

.

// test_main.cpp
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Main
#include <boost/test/unit_test.hpp>

// test1.cpp
#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
#   define BOOST_TEST_MODULE Main
#endif
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(test1_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(2<1);
}

BOOST_AUTO_TEST_SUITE_END()

// test2.cpp
#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
#   define BOOST_TEST_MODULE Main
#endif
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(test2_suite)

BOOST_AUTO_TEST_CASE(Test1)
{
    BOOST_CHECK(1<2);
}

BOOST_AUTO_TEST_SUITE_END()
Robert S. Barnes
It would be great if you could edit your link to point to the top of the page, not the comments.
danio
@danio: Edited the link, and added a link to a Perl script which will auto generate the makefile, project skeleton and unit test suites.
Robert S. Barnes