如何测试异步代码

How to test asynchronuous code

本文关键字:异步 代码 测试 何测试      更新时间:2023-10-16

我已经编写了自己的游戏引擎访问层。有一个GameLoop,它在每一帧都被调用,让我处理自己的代码。我能够做一些具体的事情,并检查这些事情是否发生过。在一个非常基本的方式上,它可以看起来像这样:

void cycle()
{
//set a specific value
Engine::setText("Hello World");
//read the value
std::string text = Engine::getText();
}

我想通过编写自动测试来测试我的Engine层是否正常工作。我在使用BoostUnittest框架进行类似这样的简单比较测试方面有一些经验。

问题是,我希望引擎做的一些事情只是在调用cycle()之后处理的。因此,在Engine::setText(...)之后直接调用Engine::getText()将返回一个空字符串。如果我要等到cycle()的下一次调用,就会返回正确的值。

我现在想知道,如果不可能在同一个周期中处理测试,我应该如何编写测试。有什么最佳实践吗?在这样的环境中,是否可以使用Boost Unittest Framework给出的"传统测试"方法?是否有其他针对此类专门案例的框架?

我对这里的所有内容都使用C++,但我可以想象,有些答案与编程语言无关。

更新:无法访问cycle()之外的Engine

在上面的示例中,std::string text = Engine::getText();是您希望在一个周期中记住但在下一个周期执行的代码。您可以将其保存以便以后执行。例如,使用C++11,您可以使用lambda将测试封装到内联指定的简单函数中。

有两个选项:

如果你拥有的库可以同步使用,或者使用类似c++11期货的工具(它可以指示结果的就绪性),那么在你的测试用例中,你可以做下面的

void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (!Engine::isResultReady());
//read the value
assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT");
}

如果你没有以上最好的,你可以有一个超时(这不是一个好的选择,因为你可能有虚假的失败):

void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") {
wait(1 millisec);
if (total_wait_time > 1 sec) // you can put whatever max time
assert(0);
}
}