Boost_Data_Test_Case with Fixture Support

Boost_Data_Test_Case with Fixture Support

I'm looking for fixture support in BOOST_DATA_TEST_CASE. I wrote following C++ macros for it, but may be somebody has something better?

#include <boost/test/unit_test.hpp>
#include <boost/test/data/test_case.hpp>

#define BOOST_FIXTURE_DATA_TEST_CASE_IMPL( arity, test_name, F, dataset, params )  \
struct test_name : public F {                                                      \
    template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                            \
    static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) )               \
    {                                                                              \
        BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");           \
        test_name t;                                                               \
        BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry.");                   \
        BOOST_TEST_CONTEXT( ""                                                     \
            BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params))             \
        t._impl(BOOST_PP_SEQ_ENUM(params));                                        \
        BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit.");                    \
    }                                                                              \
private:                                                                           \
    template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                            \
    void _impl(BOOST_DATA_TEST_CASE_PARAMS( params ));                             \
};                                                                                 \
                                                                                   \
BOOST_AUTO_TU_REGISTRAR( test_name )(                                              \
    boost::unit_test::data::ds_detail::make_test_case_gen<test_name>(              \
          BOOST_STRINGIZE( test_name ),                                            \
          __FILE__, __LINE__,                                                      \
          boost::unit_test::data::make(dataset) ),                                 \
    boost::unit_test::decorator::collector::instance() );                          \
                                                                                   \
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                                \
void test_name::_impl( BOOST_DATA_TEST_CASE_PARAMS( params ) )                     \
/**/

#define BOOST_AUTO_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, ... )          \
    BOOST_FIXTURE_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),       \
                               test_name, BOOST_AUTO_TEST_CASE_FIXTURE, dataset,  \
                               BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) )            \
/**/
#define BOOST_AUTO_DATA_TEST_CASE_NO_PARAMS( test_name, dataset )       \
    BOOST_AUTO_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, sample ) \
/**/

#if BOOST_PP_VARIADICS_MSVC

#define BOOST_AUTO_DATA_TEST_CASE( ... )                                     \
    BOOST_PP_CAT(                                                            \
    BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2),      \
                     BOOST_AUTO_DATA_TEST_CASE_NO_PARAMS,                    \
                     BOOST_AUTO_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__), ) \
/**/
#else

#define BOOST_AUTO_DATA_TEST_CASE( ... )                                     \
    BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2),      \
                     BOOST_AUTO_DATA_TEST_CASE_NO_PARAMS,                    \
                     BOOST_AUTO_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__)    \
/**/
#endif

Example of BOOST_DATA_TEST_CASE usage:

#include <boost/range/iterator_range.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>

struct fixure
{
    fixure() :
        _Mydir(boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("test-%%%%-%%%%-%%%%-%%%%"))
    {
        create_directory(_Mydir);
    }

    ~fixure()
    {
        _TRY_BEGIN
            remove_all(_Mydir);
        _CATCH_ALL
        _CATCH_END
    }

    boost::filesystem::path const _Mydir;
};

BOOST_FIXTURE_TEST_SUITE(suite, fixure)

namespace {

std::array<char const *, 4> const _Ourdata = { "A", "B", "C", "D" };

}

BOOST_AUTO_DATA_TEST_CASE(test, _Ourdata, _Str)
{
    BOOST_REQUIRE(_Str);
    BOOST_REQUIRE(is_directory(_Mydir));
    auto const _File = _Mydir / _Str;
    BOOST_TEST_MESSAGE(_File);
    std::fstream _Stream;
    _Stream.open(_File.c_str(), std::ios::out);
    _Stream << _Str;
    _Stream.close();
    BOOST_REQUIRE(is_regular_file(_File));
}

BOOST_AUTO_TEST_SUITE_END()

Output in test_suite mode:

Running 4 test cases...
Entering test module "example"
Entering test suite "suite"
Entering test case "test"
"C:\Users\XXX\AppData\Local\Temp\test-4445-a983-8ba6-09ef\A"
Failure occurred in a following context:
    _Str = A;
Leaving test case "test"; testing time: 17ms
Entering test case "test"
"C:\Users\XXX\AppData\Local\Temp\test-d4c4-c5f6-6154-7200\B"
Failure occurred in a following context:
    _Str = B;
Leaving test case "test"; testing time: 10ms
Entering test case "test"
"C:\Users\XXX\AppData\Local\Temp\test-9f96-4f2c-b132-c541\C"
Failure occurred in a following context:
    _Str = C;
Leaving test case "test"; testing time: 9ms
Entering test case "test"
"C:\Users\XXX\AppData\Local\Temp\test-f0cf-962c-aed3-1cf8\D"
Failure occurred in a following context:
    _Str = D;
Leaving test case "test"; testing time: 10ms
Leaving test suite "suite"; testing time: 61ms
Leaving test module "example"; testing time: 76ms

*** No errors detected

Update: Test suite was updated to std::array<> using

5

1 Answer

As of Boost 1.62, you can use BOOST_DATA_TEST_CASE_F for this:

Declares and registers a data-driven test case, using a particular dataset and a fixture.

BOOST_DATA_TEST_CASE_F(my_fixture, test_case_name, dataset, var1, var2..., varN)

Reference:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.