Является ли хорошей практикой запуск потока из модульного теста?

У меня есть класс, который имеет функцию execute (). Выполнение execute ()
Функция останавливается только когда вызывается функция terminate (). Я хочу проверить функцию execute ().

class Process{
public:

void execute(){ // start execution until terminate() is called.. }

void terminate(){ //stop the processing of execute()... }

}

Мой пример модульного теста приведен ниже. Я использую MSTest.

TEST_METHOD(StartTest)
{
Process p;
bool isRunning = true;
std::thread th([&](){
p.execute();
isRunning = false;
});
th.detach();
std::this_thread::sleep_for(std::chrono::milliseconds(300));

Assert::isTrue(isRunning);
}

Если использование потока является хорошей практикой, следует ли мне закрывать поток внутри контрольного примера, а не отсоединять его от основного потока?

Также лучшее предложение заметно.

1

Решение

Прежде всего доступ к isRunning должны быть синхронизированы. В вашем примере вы можете просто использовать std::atomic<bool> и покончим с этим.

Отказ от ответственности: прошло много времени с тех пор, как я выполнил какую-либо серию многопоточности, поэтому возьмите это с крошкой соли. Кроме того, я не проверял код, кроме проверки его компиляции.

Вот где я бы начал:

auto test()
{
std::condition_variable cv{};
std::mutex m{};

Process p{};
bool isRunning{true};

std::thread th([&] {
p.execute();
{
std::lock_guard<std::mutex> lk{m};
isRunning = false;
}
cv.notify_one();
});

{
std::unique_lock<std::mutex> lk{m};
// expect timeout
Assert::isFalse(cv.wait_for(lk, std::chrono::milliseconds(300),
[&] () { return !isRunning; }));
}

p.terminate();

{
std::unique_lock<std::mutex> lk{m};
// expect condition to change
Assert::isTrue(cv.wait_for(lk, std::chrono::milliseconds(300),
[&] () { return !isRunning; }));
}

th.join();
}

Таким образом, вы проверяете оба execute блокировать и для terminate прекратить и у вас есть больше гибкости. Если execute разблокирует рано, вы не ждете своего полного тайм-аута и для terminate у вас есть движение, чтобы дождаться завершения другого потока, и вы разблокируете его, как только он это сделает.


Если terminate () не может остановить выполнение, будет ли продолжен поток
его выполнение после окончания этого теста?

Если terminate не останавливает исполнение тогда 2 wait_for заканчивается после возвращения тайм-аута false и утверждение вступает в силу. Я не знаю, какие рамки тестирования вы используете и что Assert делает.

  • если он возвращает исполнение test тогда тест будет заблокирован на join пока нить не закончится

  • если он выдает исключение, то join не называется и у деструктора th если поток еще не закончился std::terminate будет называться. Это можно изменить с помощью try catch

  • если это вызывает выход (например, звонки std::terminate) тогда … ну … ваша программа заканчивается независимо

Это действительно проблема, которую вы должны проанализировать. Все зависит от того, что вы хотите сделать, если terminate не может остановиться execute в пределах вашего интервала ожидания.

  • если вы в порядке с ожиданием в течение testтогда все, что вам нужно сделать, это убедиться, join называется. Как я уже сказал, это решаемо с try catch,

  • если вы хотите завершить текущий тест, но все в порядке с продолжающимся потоком, то вам нужно отсоединить поток, если terminate не смог покончить с этим.

  • если вы хотите убить поток, тогда … это невозможно. Вместо этого вы можете убить все приложение через std::terminate,

3

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

Других решений пока нет …

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