あめだまふぁくとりー

Boost.Graphとかできますん

Boost.Test で Test Suite と Test Case の Fixture の併用

Boost.Test では,Test Case に対して Fixture を設定すると,Test Suite レベルの Fixture がその Test Case に対して使用されなくなります. よって,以下のようなコードはコンパイルエラーになってしまいます.

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE fixture_test
#include <boost/test/unit_test.hpp>
#include <iostream>

struct suite_fixture {
    suite_fixture() : suite_fix{1}
    { std::cout << __func__ << std::endl; }
    ~suite_fixture()
    { std::cout << __func__ << std::endl; }
    int suite_fix;
};

struct case_fixture {
    case_fixture() : case_fix{2}
    { std::cout << __func__ << std::endl; }
    ~case_fixture()
    { std::cout << __func__ << std::endl; }
    int case_fix;
};

// set test suite level fixture
BOOST_FIXTURE_TEST_SUITE(suite1, suite_fixture)

BOOST_AUTO_TEST_CASE(case1)
{
    BOOST_CHECK_EQUAL(1, suite_fix); // ok
}

// set test case fixture
BOOST_FIXTURE_TEST_CASE(case2, case_fixture)
{
    BOOST_CHECK_EQUAL(1, suite_fix); // compile error
    BOOST_CHECK_EQUAL(2, case_fix);
}

BOOST_AUTO_TEST_SUITE_END()

Boost.Test の Fixture の仕組みは,各 Test Case は Fixture のクラスを指定された場合は,そのクラスから派生し,そうでない場合はデフォルトのクラス,つまり,Test Suite で指定した Fixture のクラスから派生するといったものになっています.

なので,Test Case に渡すクラスを,指定したい Fixture クラスとデフォルトのクラスのリストにしてあげれば,多重継承になって両方の Fixture を利用できそうです. 以下がそのコードと出力になります.

ソースコード

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE fixture_test
#include <boost/test/unit_test.hpp>
#include <boost/preprocessor/tuple/enum.hpp>
#include <iostream>

// クラス F とデフォルトの Fixture クラスのリストを BOOST_FIXTURE_TEST_CASE に指定
#define CANARD_FIXTURE_TEST_CASE(test_name, F) \
    BOOST_FIXTURE_TEST_CASE(test_name, BOOST_PP_TUPLE_ENUM(2, (BOOST_AUTO_TEST_CASE_FIXTURE, F)))

struct suite_fixture {
    suite_fixture() : suite_fix{1}
    { std::cout << __func__ << std::endl; }
    ~suite_fixture()
    { std::cout << __func__ << std::endl; }
    int suite_fix;
};

struct case_fixture {
    case_fixture() : case_fix{2}
    { std::cout << __func__ << std::endl; }
    ~case_fixture()
    { std::cout << __func__ << std::endl; }
    int case_fix;
};

BOOST_FIXTURE_TEST_SUITE(suite1, suite_fixture)

CANARD_FIXTURE_TEST_CASE(case2, case_fixture)
{
    BOOST_CHECK_EQUAL(1, suite_fix); // ok
    BOOST_CHECK_EQUAL(2, case_fix);
}

BOOST_AUTO_TEST_SUITE_END()

出力

!!!*** No errors detected!!!
Running 1 test case...
suite_fixture
case_fixture
~case_fixture
~suite_fixture