2014-09-07 8 views
4

Я хочу выполнить модульное тестирование в программе 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); 
} 

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

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

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

ответ

0

Я не на 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, и выход перенаправляется в файл.