2017-02-27 63 views
1

我最近写了一个测试夹具,它构建了单线程或多线程模式下的测试代码。NUnit 3:第一次测试超时

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

因此,具有两个夹具属性的两个测试变成四个测试,并且只有三个测试中的一个失败。

在本地运行时,所有四个测试都会执行并在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)); 
    } 
} 

回答

0

MyTest_A_ThrowsInvalidOperationExceptionMyTest_B_ThrowsInvalidOperationException之前按字母顺序排序。 和MultiThreadedSingleThreaded之前按字母顺序排序。

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

添加OneTimeSetup方法与一些引用所需代码的代码将强制加载类型,然后单个测试分叉和测量。

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

生成代理可能有很差的I/O性能(这对于测试的目的是确定的,但增加了一个点球的开销加载额外的依赖时)。