6

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 を使用してそのようなテスト スキームを実装したいと思います。

unit_test_mainBoost Unit Test ライブラリの内部を調べていると、すべてのテストの実行をトリガーする関数のように見えることがわかりました。しかし、各テストを別のプロセスで実行するために、Boost Unit Test と対話する非侵入型の方法を考案できませんでした。

各テストを異なるプロセスで実行するための簡単なソリューションを知っている人はいますか?

4

1 に答える 1

3

思いついた解決策に 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 は 1 回の実行で問題なく複数回実行されます。

このソリューションの唯一の問題は、何らかの理由で XML 結果を出力するときにファイル シンクを使用できないことです。stderrしかし、シンクがあり、出力がファイルにリダイレクトされている場合、すべてが正常に機能することがわかりました。

于 2014-10-27T22:25:46.400 に答える