Выполняйте один тест несколько раз с различным креплением каждый раз

У меня есть тестовый пример, который я хочу выполнить для разных состояний базы данных. Я вставляю объекты в DB в fixture (и я хотел бы сохранить его таким образом). Я хочу создать метод для инициализации виртуального БД и специализировать приспособление для различных конфигураций в БД.

Один из способов, о котором я могу думать, - сделать что-то вроде:

void doTest(){
    //test code here
}

BOOST_FIXTURE_TEST_CASE(test1, fixture1)
{
    doTest();
}

BOOST_FIXTURE_TEST_CASE(test2, fixture2)
{
    doTest();
}

BOOST_FIXTURE_TEST_CASE(test3, fixture3)
{
    doTest();
}

Но есть ли более чистый, более аккуратный способ? Или, может быть, я не должен этого делать вообще? Я буду признателен за любые рекомендации экспертов по тестированию.

Ответ 1

Вы можете использовать BOOST_FIXTURE_TEST_CASE_TEMPLATE для создания нескольких тестов:

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE TestModuleName
#include <boost/test/unit_test.hpp>
#include <boost/mpl/vector.hpp>

struct Fixture1 { int i; Fixture1() : i(1) {} };
struct Fixture2 { int i; Fixture2() : i(2) {} };
struct Fixture3 { int i; Fixture3() : i(3) {} };

typedef boost::mpl::vector<Fixture1, Fixture2, Fixture3> Fixtures;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(Test, T, Fixtures, T){
    std::cout << T::i << "\n";
}

Будет напечатан

1
2
3

Этот код создает собственный тестовый пример для каждого типа в mpl::vector 'Fixtures'. Каждый тип Fixture будет передан как T (второй параметр BOOST_FIXTURE_TEST_CASE_TEMPLATE), а T будет использоваться как инструмент для тестового примера (последний параметр).

Caveat

Из-за характера шаблона тестового примера (класса) вам нужно добавить T:: для доступа к элементам приборов, чтобы указать, что они являются (зависимыми от шаблона) именами.

Улучшение

Поскольку BOOST_FIXTURE_TEST_CASE_TEMPLATE является таким общим, может потребоваться определить удобный "ярлык", который более подробно говорит о том, что делается:

#define MULTI_FIXTURE_TEST_CASE(NAME, TPARAM, ...) \
        typedef boost::mpl::vector<__VA_ARGS__> NAME##_fixtures; \
        BOOST_FIXTURE_TEST_CASE_TEMPLATE(NAME, TPARAM, NAME##_fixtures, TPARAM)

MULTI_FIXTURE_TEST_CASE(Test, T, Fixture1, Fixture2, Fixture3){
    std::cout << T::i << "\n";
}

Как вы можете видеть, он несколько скрывает mpl::vector. Я думаю, было бы лучше определить этот макрос в своем собственном заголовке, который также делает #include <boost/mpl/vector.hpp>, чтобы избежать отсутствия зависимости. Имя списка приборов - это имя тестового примера плюс "_fixtures", поэтому он, надеюсь, не столкнется с существующими именами и будет несколько значимым.