2016-01-08 58 views
2

我目前正在嘗試評估不同的測試框架。當我使用模擬框架(我傾向於FakeIt,但Google模擬也不錯)時,我知道在調用函數來驗證函數的性能之前和之後,您可以通過使用操作系統的定時器調用來進行自己的「性能」測試。這不是我所追求的。我如何測試使用嘲諷框架在谷歌測試中延遲後發出的呼叫

我所做的是在給定某些輸入的情況下實現輸出延遲的類。例如:

  • 輸入1變爲從低到高
  • 輸出1在1.5秒後,從低變爲高

我希望能夠做一些事情,我指定的邊界:

myMock.theInput(); 
EXPECT_CALL(myMock, theDelayedOutput()) 
    .Times(1) 
    .Before(1.6sec) 
    .After(1.4sec); 

爲了澄清,BeforeAfter線不被支持。這只是我喜歡的簡單語法的一個例子。

是否有可能只實現使輸入電話之間和檢查EXPECT_CALL之前窗口內的「延遲」功能?

這是部分原因 - 我仍然必須啓動專有計時器。像這樣?

myMock.theInput(); 
windowSleep(1.4); 
startTimer(); 
EXPECT_CALL(myMock, theDelayedOutput()) 
    .Times(1) 
endTimer(); 
ASSERT_TRUE(elapsedTime() <= 0.2); 

回答

1

我敢肯定,這個解決方案將任何框架的工作,而無需修改的框架:

myMock.theInput(); 
startTimer(); 
EXPECT_CALL(myMock, theDelayedOutput()); 
endTimer(); 
ASSERT_TRUE(elapsedTime() >= 1.4); 
ASSERT_TRUE(elapsedTime() <= 1.6); 

這可以被包裹在一個宏:

#define EXPECT_CALL_DELAYED(theMock, expectCall, lowerBound, upperBound) {\ 
    startTimer();\ 
    EXPECT_CALL(theMock, expectCall);\ 
    endTimer();\ 
    ASSERT_TRUE(elapsedTime() >= lowerBound);\ 
    ASSERT_TRUE(elapsedTime() <= upperBound);\ 
} 

最後的測試代碼則是:

myMock.theInput(); 
EXPECT_CALL_DELAYED(myMock, theDelayedOutput(), 1.4, 1.6); 

或者,您可以遵循DRY原則並預先指定時間的「窗口」。這允許您測試,指定確切的時間,但是不必重複每次都必須上下添加0.1秒的緩衝區。

EXPECT_CALL_DELAYED_SET_WINDOW(0.1); 
myMock.theInput(); 
EXPECT_CALL_DELAYED(myMock, theDelayedOutput(), 1.5); 
myMock.theSecondInput(); 
EXPECT_CALL_DELAYED(myMock, theSecondDelayedOutput(), 3.1); 

雖然,我還沒有測試過任何這個。稍後我會進行更新,並接受此功能。

0

由於您使用單元測試標記了該問題:在單元測試中,測試不應該依賴物理時間的傳遞。這有多種原因:一個是你希望你的測試儘可能快地運行,所以你不想延遲。另一個原因是,在開發環境(在您的單元測試運行)的時機可能是因爲不同的硬件,操作系統,系統負載,從目標環境完全不同,...

也就是說,涉及測試物理時間的消逝確實是有道理的,但它們是對目標系統(或其某些模擬)的集成測試。在單元測試,你會採取不同的方法:

你會嘲笑的功能/方法,代表你的時鐘。例如,當時間已經過去,如果你的函數FuncA的設置通過SetTimer的定時器,提供了一個回調被稱爲:

  • 在你的一些測試中,你嘲笑SetTimer函數的,叫FuncA的,正如部分測試「通過標準,檢查模擬setTimer是否與您所期望的參數一起被調用。
  • 在其他一些測試中,您可以直接從測試中調用回調函數,以查看該函數的行爲是否正確。

在這兩個單元測試案例中,您都不會等待物理時間過去。也就是說,您當然可以使用與單元測試同樣用於集成測試的測試框架(即使它們的名稱,如JUnit,似乎表明它們僅用於單元測試)。而且,如果集成測試實際上是您正在瞄準的那種測試,那麼來自Jeff Lamb的建議肯定會有所幫助。