Boost.Test и Forking - PullRequest
       5

Boost.Test и Forking

1 голос
/ 28 июня 2010

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

Я думал о том, чтобы сделать что-то вроде этого:

MY_TEST()
if (fork() == 0) {
    runMockServer();  // responds to test requests or times out, then returns
    exit(0);
}
// Connect to MockServ and Run actual test here
END_TEST()

но я беспокоюсь, что это испортит рамки тестирования.

Это безопасно? Кто-нибудь делал что-то подобное?

Я использую Boost 1.34.1 в Ubuntu 8.04, если это имеет значение.

Ответы [ 2 ]

3 голосов
/ 21 декабря 2012

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

Одно препятствие, которое нужно преодолеть, - это сигнализация об ошибках дочернего процесса без использования макросов boost assert. Например, если BOOST_REQUIRE будет использовано для преждевременного прерывания теста, и любые последующие тесты будут выполняться как в родительских, так и в дочерних процессах. Я закончил тем, что использовал код завершения процесса, чтобы сообщить об ошибке ожидающему родительскому процессу. Тем не менее, не используйте exit() в качестве повышения, имеют atexit() хуки, которые сигнализируют об ошибках в дочернем процессе, даже если их нет. Вместо этого используйте _exit().

Настройка, которую я использовал для тестов, была примерно такой.

BOOST_AUTO_TEST_CASE(Foo)
{
  int pid = fork();
  BOOST_REQUIRE( pid >= 0 );
  if( pid  == 0 ) // child
  {
    // Don't use Boost assert macros here
    // signal errors with exit code

    // Don't use exit() since Boost test hooks 
    // and signal error in that case, use _exit instead.
    int rv = something(); 
    _exit(rv);
  }else{ // parent
    // OK to use boost assert macros in parent
    BOOST_REQUIRE_EQUAL(0,0);
    // Lastly wait for the child to exit
    int childRv;
    wait(&childRv);
    BOOST_CHECK_EQUAL(childRv, 0);
  }

}
3 голосов
/ 28 июня 2010

Это не похоже на юнит-тестирование того, чего вы хотите достичь. Хотя я не понимаю, почему это не будет безопасно. У вас может быть состояние гонки, когда ваш юнит-тест подключается к MockServ, если он еще не готов, но это легко решаемо.

Я никогда не делал ничего подобного напрямую, но я написал модульные тесты для библиотек, которые запускают / исполняют дочерние процессы, и это работает безупречно.

...