Boost logo

Boost :

From: r.lichtenberger_at_[hidden]
Date: 2003-02-03 02:09:34


I suggest adding the following (or a similar) macro to test_tools.hpp:

#define BOOST_CHECK_EQUAL_MESSAGE(left_, right_, message_) \
    boost::test_toolbox::detail::equal_and_continue_impl((left_),
(right_), \
        boost::test_toolbox::detail::wrapstrstream() << #left_ " == "
#right_ << " (" << message_ << ")" , __FILE__, __LINE__)

Sometimes in a unit test one has got a function/method to check certain
properties of an object in order to avoid duplicating lots of code

--- SNIP Example ---
MyObject* my1 = new MyObject(1, 2, 3);
BOOST_CHECK_EQUAL(my1->getA(), 1);
BOOST_CHECK_EQUAL(my1->getB(), 2);
BOOST_CHECK_EQUAL(my1->getC(), 3);

MyObject* my2 = new MyObject(4, 5, 6);
BOOST_CHECK_EQUAL(my2->getA(), 4);
BOOST_CHECK_EQUAL(my2->getB(), 5);
BOOST_CHECK_EQUAL(my2->getC(), 6);
--- SNIP ---

can be refactored into:

--- SNIP Example refactored ---
void checkMyObject(MyObject* my, int a, int b, int c)
{
        BOOST_CHECK_EQUAL(my->getA(), a);
        BOOST_CHECK_EQUAL(my->getB(), b);
        BOOST_CHECK_EQUAL(my->getC(), c);
}

MyObject* my1 = new MyObject(1, 2, 3);
checkMyObject(my1, 1, 2, 3);
MyObject* my2 = new MyObject(4, 5, 6);
checkMyObject(my2, 4, 5, 6);
--- SNIP ---

The problem with the second version is that if the check for equality
fails, the only output is the line number within checkMyObject() that
failed. No hint about the calling line is present. Ideally all macros
should print out a stack trace (as done in e.g. Java), but from my limited
knowledge of C++ I guess that this is not (easily) possible, so
introducing a BOOST_CHECK_EQUAL_MESSAGE macro is the second best solution
IMHO:

--- SNIP Example with new macro ---
void checkMyObject(MyObject* my, int context, int a, int b, int c)
{
        BOOST_CHECK_EQUAL_MESSAGE(my->getA(), a, context);
        BOOST_CHECK_EQUAL_MESSAGE(my->getB(), b, context);
        BOOST_CHECK_EQUAL_MESSAGE(my->getC(), c, context);
}

MyObject* my1 = new MyObject(1, 2, 3);
checkMyObject(my1, __LINE__, 1, 2, 3);
MyObject* my2 = new MyObject(4, 5, 6);
checkMyObject(my2, __LINE__, 4, 5, 6);
--- SNIP ---

Note that instead of using an int context we could also have a std::string
or any other streamable object. Using an int and the __LINE__ macro is
just convenient here.

Best regards,
        Robert


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