我有一个具有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);
}
如果使用线程是一种好的做法,我应该关闭测试用例内的线程而不是将其与主线程分离吗?
更好的建议也是值得赞赏的。
最佳答案
首先访问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
您需要等待另一个线程完成,并在完成后立即解除阻塞。
If terminate() fails to stop the execution, will th thread continue his execution after the end of this test case?
如果terminate
第二个 wait_for
不会停止执行超时后结束返回false
我不知道你使用什么测试框架以及 Assert
是什么。确实如此。
如果它将执行返回到
test
那么测试将在join
上阻塞直到线程结束如果它抛出异常,则
join
没有被调用并且在th
的析构函数中如果线程仍未结束std::terminate
将被调用。这可以通过try catch
进行更改如果它强制退出(例如调用
std::terminate
)那么......好吧......你的程序无论如何都会结束
这确实是一个需要你分析的问题。这完全取决于您想做什么,如果 terminate
无法停止execute
在您的等待间隔内。
如果您可以在
test
内等待,那么您需要做的就是确保join
叫做。正如我所说,这可以通过try catch
来解决.如果您想结束当前测试,但同意线程仍在继续,那么您需要分离线程,如果
terminate
未能结束。如果你想终止线程那么...那是不可能的。您可以通过
std::terminate
杀死整个应用程序.
关于c++ - 从单元测试用例运行线程是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53018505/