2012-12-07 199 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將測試包裝爲一個內聯指定的簡單函數。