我们正在开发一个使用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