2012-12-07 197 views
5

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

void cycle() 
{ 
    //set a specific value 
    Engine::setText("Hello World"); 

    //read the value 
    std::string text = Engine::getText(); 
} 

我想测试,如果我的Engine - 层是通过写自动化测试工作。我有一些使用Boost Unittest Framework进行简单比较测试的经验。

问题是,我想要引擎做的一些事情只是在cycle()的调用后处理。所以在Engine::setText(...)之后直接调用Engine::getText()会返回一个空字符串。如果我要等到cycle()的下一个呼叫,则会返回正确的值。

我现在想知道如果我不能在同一个循环中处理它们,我应该如何编写测试。有没有最佳做法?在这样的环境中是否可以使用Boost Unittest Framework提供的“传统测试”方法?有没有其他框架针对这样一个专门的案例?

我在这里使用C++的一切,但我可​​以想象有与编程语言无关的答案。

UPDATE: 这是不可能访问Enginecycle()

+0

除非引擎能够以完成处理的方式发出信号,否则我并不认为这有效。不过,非常好奇看到别人的答案。 –

回答

-1

有两种选择与您:

如果你有可以同步或使用C++ 11个期货使用的库像设备(可显示结果的readyness)然后在您的测试情况下,如果你没有以上,你可以做有最好的你可以做如下

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); 
    } 

} 
+0

第一个答案是不可能的,因为引擎没有'isResultReady()',第二个答案是坏的设计:在这种测试中引入超时和睡觉是件坏事,因为你忘记了需要睡眠的时间在每台机器上都可以不同。您的Core i7可能只需要1秒钟,但一些较旧的Pentium可能需要2次。在这两种情况下,测试用例都应该通过,但是 - 如果使用睡眠 - 则在第二种情况下将失败。 –

+1

GameEngine在调用'cycle()'后处理'Engine :: setText(..)',所以添加一个超时将与我之后直接调用'Engine :: getText()'相同,它只需要更多时间。我只能在GameEngine中处理'setText'之后得到正确的结果,这意味着在下一个'cycle()' – MOnsDaR

+0

@DanielKamilKozar - 你应该正确阅读我的评论..“(这不是一个好的选择虽然因为你可能有虚假的失败)“ – RamneekHanda

0

在你上面的例子,std::string text = Engine::getText();是你想从一个周期记住,但在接下来的执行代码。您可以保存它以供以后执行。例如 - 使用C++ 11,您可以使用lambda将测试包装为一个内联指定的简单函数。