NUnit 3:第一次测试超出超时

时间:2017-02-27 13:34:16

标签: multithreading nunit-3.0

我最近编写了一个测试夹具,用于在单线程或多线程模式下构建测试代码。

但其中一个测试(A)在构建代理上始终失败,但仅适用于多线程模式。 通过(B)的测试和测试之间几乎没有区别 测试失败(B)。

因此,使用两个夹具属性,两个测试成为四个测试,并且3个测试中只有一个失败。

在本地运行时,所有四个测试都会在不到20毫秒的时间内执行并传递,因此在20毫秒和超过5秒的超时之间存在巨大差异。

[TestFixture(MyCodeMode.SingleThreaded)]
[TestFixture(MyCodeMode.MultiThreaded)]
[Timeout(5000)]
public class MyCodeTests {
   private MyCodeMode _mode;
   public MyCodeTests(MyCodeMode mode) {
      _mode = mode;
   }
   private MyCode GetSystemUnderTest() {
      return new MyCode(_mode);
   }

   [Test]
   // this test fails when multi-threaded, passes in single-threaded
   public void MyTest_A_ThrowsInvalidOperationException() {
       Assert.Throws<InvalidOperationException>(() => GetSystemUnderTest().Execute(2));
   }

   [Test]
   // this test passes regardless of mode
   public void MyTest_B_ThrowsInvalidOperationException() {
      Assert.Throws<InvalidOperationException>(() => GetSystemUnderTest().Execute(3));
   }
}

1 个答案:

答案 0 :(得分:0)

MyTest_A_ThrowsInvalidOperationException按字母顺序排序MyTest_B_ThrowsInvalidOperationException之前。 MultiThreaded按字母顺序排序SingleThreaded

因此测试超过了超时,因为它是第一个要执行的代码,因此会将所需的程序集/类型加载到CLR中产生所有影响。后续测试会重新使用已加载到内存中的类型。

使用引用所需代码的某些代码添加OneTimeSetup方法将强制在分叉和测量各个测试之前加载类型。

[OneTimeSetup]
public void EnsureDependenciesHaveBeenLoadedIntoMemoryBeforeStartingTimeout() {
    new MyCode();
}

构建代理可能具有非常差的I / O性能(为了测试可以,但在加载其他依赖项时会增加开销)。