Выполнение модульных тестов Boost на разных процессах

Я хочу провести модульное тестирование в программе SystemC. Идея состоит в том, чтобы иметь несколько наборов тестов с несколькими тестами в каждом комплекте. Каждый из тестов потребует сброса платформы SystemC (например, путем вызова sc_simcontext::reset()), но это на самом деле невозможно из-за некоторой ошибки, которая, по-видимому, не будет исправлена ​​в ближайшее время. Поэтому я решил придумать обходной путь.

Я обнаружил, что если я запускаю каждый тест в отдельном процессе, все работает нормально. Следующий фрагмент кода дает обзор схемы, которую я использовал, чтобы заставить ее работать:

void test1() {
// ...
sc_start();
}

void test2() {
// ...
sc_start();
}

typedef std::function<void()> TestFunction;

void run_test(TestFunction test_function) {
pid_t pid = fork();
switch (pid) {
case -1:
throw std::runtime_error("Error forking process");
case 0:
test_function();
exit(0);
default:
waitpid(pid, nullptr, 0);
break;
}
}

int main() {
run_test(test1);
run_test(test2);
}

Теперь я хочу реализовать такую ​​схему тестирования с помощью Boost Unit Test.

Я изучал внутреннюю часть библиотеки Boost Unit Test и обнаружил, что unit_test_main Кажется, это функция, которая запускает выполнение всех тестов. Но я не мог придумать ненавязчивый способ взаимодействия с Boost Unit Test для запуска каждого теста в отдельном процессе.

Кто-нибудь знает простое решение для запуска каждого теста в другом процессе?

5

Решение

Я не на 100% удовлетворен решением, которое я предложил, но я все равно опубликую его. Для удобства я инкапсулировал все в пространство имен:

Заголовочный файл:

namespace util {

typedef std::function<void()> TestFunction;

void run_test(TestFunction test_function);

} // namespace util

#define SYSTEMC_TEST_CASE(name)       \
void name##_impl();                 \
BOOST_AUTO_TEST_CASE(name) {        \
util::run_test(name##_impl);      \
}                                   \
void name##_impl()

Исходный файл:

namespace util {

void run_test(TestFunction test_function) {
pid_t pid = fork();
switch (pid) {
case -1:
throw std::runtime_error("Error forking process");
case 0:
try { test_function(); }
catch (const std::exception& e) {
std::cout << boost::format("Exception caught: %1%") % e.what() << std::endl;
exit(1);
}
catch (...) { exit(1); }
exit(0);
default:
waitpid(pid, nullptr, 0);
break;
}
}

} // namespace util

Пример использования:

BOOST_AUTO_TEST_SUITE(suite)

SYSTEMC_TEST_CASE(test_case1) {
// ...
}

SYSTEMC_TEST_CASE(test_case2) {
// ...
}

BOOST_AUTO_TEST_SUITE_END()

main.cpp содержит:

#define BOOST_TEST_MODULE TestModule
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_NO_MAIN
#include <boost/test/unit_test.hpp>

#include <systemc.h>

boost::unit_test::test_suite* init_unit_test_suite(int, char*[]) {
using namespace ::boost::unit_test;
assign_op(framework::master_test_suite().p_name.value,
BOOST_TEST_STRINGIZE(BOOST_TEST_MODULE).trim("\""), 0);
return 0;
}

int sc_main(int argc, char* argv[]) {
return boost::unit_test::unit_test_main(&init_unit_test, argc, argv);
}

Каждый тестовый пример теперь будет выполняться по другому процессу. Поэтому SystemC запускается несколько раз за одно выполнение без каких-либо проблем.

Единственная реальная проблема этого решения заключается в том, что по какой-то причине невозможно использовать приемник файлов при выводе результатов XML. Но я обнаружил, что все работает нормально, если раковина stderr и вывод перенаправляется в файл.

2

Другие решения


По вопросам рекламы [email protected]