我們正在開發一個使用TDD的WPF應用程序。由於我們已經在這個解決方案上工作了將近兩年,我們已經寫了大量的測試(現在幾乎有2000個Unittests)。如何優化驗證異步代碼的測試?
有一些類需要實現多線程和異步功能。例如可以發送和接收消息並解析它們的通信組件。依賴關係總是使用RhinoMocks來模擬。
參加測試方法針對這些類看起來非常相似,如下:
[TestMethod]
public void Method_Description_ExpectedResult(){
// Arrange
var myStub = MockRepository.GenerateStub<IMyStub>();
var target = new MyAsynchronousClass(myStub);
// Act
var target.Send("Foo");
Thread.Sleep(200);
//Assert
myStub.AssertWasCalled(x => x.Bar("Foo"));
}
正如你所看到的,這個測試運行,由於Thread.sleep代碼()至少爲200毫秒。我們優化了測試,使用活動輪詢方法s.th替換AssertWasCalled。像這樣:
public static bool True(Func<bool> condition, int times, int waitTime)
{
for (var i = 0; i < times; i++)
{
if (condition())
return true;
Thread.Sleep(waitTime);
}
return condition();
}
現在我們可以使用這個WaitFor.True(...)通過改變AssertWasCalled的方法:
var fooTriggered = false;
myStub.Stub(x => x.Bar("Foo")).Do((Action)(() => fooTriggered = true)));
WaitFor.True(() => fooTriggered, 20, 20);
Assert.IsTrue(fooTriggered);
此結構將終止早,如果條件滿足,但無論如何 - 這對我們來說需要很長時間。運行我們所有的2000年測試需要大約5分鐘(構建和運行它們)。
有沒有什麼聰明的技巧我們可以如何優化代碼?
非常感謝,我喜歡這種測試方式!將嘗試這一個。 – Guffel
哦,看,我沒有Monitor.Wait(waitingRoom,) - 所以不需要做怪異的定時器gubbins。尼斯。 –
Lunivore