Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BOOST_CHECK_EQUAL (and dervatives) Add custom message

We recently started using the Boost Test framework, and like it so far. However, there are certain tests where it would be great if we could add custom messages to an existing helper.

For example, I can get the output in mytest and mytest2, but have found no way to get the output in mytest3:

#define BOOST_TEST_MODULE mytests
#include <boost/test/unit_test.hpp>


BOOST_AUTO_TEST_SUITE(myunit)

BOOST_AUTO_TEST_CASE(mytest)
{
    // This give a nice output [2+2 != 5]
    BOOST_CHECK_EQUAL(2+2, 5);
}

BOOST_AUTO_TEST_CASE(mytest2)
{
    // This give only a custom output
    BOOST_CHECK_MESSAGE(2+2 == 5, "comparison error");
}

BOOST_AUTO_TEST_CASE(mytest3)
{
    // Ideally, it should output [2+2 != 5] comparison error
    BOOST_CHECK_EQUAL_WITH_ADDITIONAL_MESSAGE(2+2, 5, "comparison error");
}

BOOST_AUTO_TEST_SUITE_END()

The reason I want this is because if I wish to have test cases like this:

BOOST_AUTO_TEST_CASE(mytest4)
{
    for(int i = 0; i < 10; ++i)
    {
        BOOST_CHECK_EQUAL_WITH_ADDITIONAL_MESSAGE(i%3, 0, i);
    }
}

In that case, there is no way to know for which i the test failed.

I have tried to "duplicate" the BOOST_CHECK_EQUAL macro as follows in hopes boost would append to the passed message as the original macro passes an empty literal:

#define BOOST_CHECK_EQUAL2( L, R ) \
    BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "hello world", CHECK, CHECK_EQUAL, (L)(R) )

However, "hello world: is overwritten somewhere in the test implementation with the failed condition.

Is there any (easy and clean) way to solve this?

UPDATE It appears as though the check_impl() implementation in test_tools.ipp doesn't utilize the check_descr parameter for the equality checks.

UPDATE 2020 BOOST_TEST_CONTEXT() and BOOST_TEST_INFO() , if you can use a reasonable recent boost version should now be the preferred method, as framework-provided operations are of course a lot cleaner.

Is there an elegant way to override/provide my own?

like image 413
namezero Avatar asked Oct 30 '14 12:10

namezero


2 Answers

Ok, I would just like to post for reference in case someone else runs into this that I solved it like this:

//____________________________________________________________________________//

#define BOOST_TEST_REL_EQ_MESSAGE_EXTENSION(L, R, M, CMP, ICMP, CT)         \
    {                                                                       \
        auto _1(L);                                                         \
        auto _2(R);                                                         \
        std::stringstream ss;                                               \
        ss << "check " << BOOST_TEST_STRINGIZE(L) << " " << BOOST_TEST_STRINGIZE(CMP) << " " << BOOST_TEST_STRINGIZE(R) << " failed [" << _1 << " " << BOOST_TEST_STRINGIZE(ICMP) << " " << _2 << "] : " << M;\
        BOOST_CHECK_IMPL( (_1 CMP _2), ss.str(), CT, CHECK_MSG );           \
    }                                                                       \
/**/

#define BOOST_CHECK_EQUAL_MESSAGE(L, R, M)      BOOST_TEST_REL_EQ_MESSAGE_EXTENSION(L, R, M, ==, !=, CHECK )
#define BOOST_WARN_EQUAL_MESSAGE(L, R, M)       BOOST_TEST_REL_EQ_MESSAGE_EXTENSION(L, R, M, ==, !=, WARN )
#define BOOST_REQUIRE_EQUAL_MESSAGE(L, R, M)    BOOST_TEST_REL_EQ_MESSAGE_EXTENSION(L, R, M, ==, !=, REQUIRE )

While this may not be optimal (mostly due to stringstream being used on every iteration in mytest4 above), it seems as through this provides a reasonably clean and non-intrusive solution for the few cases where the extra message might be required

UPDATE 2017-08

For newer boost test versions we can use BOOST_TEST_INFO() for outputting the message, which is much cleaner:

#define BOOST_CHECK_EQUAL_MESSAGE(L, R, M)      { BOOST_TEST_INFO(M); BOOST_CHECK_EQUAL(L, R); }
#define BOOST_WARN_EQUAL_MESSAGE(L, R, M)       { BOOST_TEST_INFO(M); BOOST_WARN_EQUAL(L, R); }
#define BOOST_REQUIRE_EQUAL_MESSAGE(L, R, M)    { BOOST_TEST_INFO(M); BOOST_REQUIRE_EQUAL(L, R); }
like image 199
namezero Avatar answered Nov 02 '22 06:11

namezero


For the need that you are describing, you should use the notion of context.

Otherwise, the assertion BOOST_TEST (and here) support a string as second argument that can be used for displaying a custom message.

like image 42
Raffi Avatar answered Nov 02 '22 04:11

Raffi