如何禁用XUnit.Net中标有自定义事实的所有测试的测试并行执行

时间:2016-06-10 08:41:35

标签: c# .net multithreading xunit

我们有一个用于运行远程XUnit.Net测试的开源项目。该功能是测试的主体设计为在远程进程上运行,结果被序列化回Visual Studio。该项目可以在这里找到。

https://github.com/Weingartner/XUnitRemote

例如,测试可能类似于

    [SampleProcessFact]
    public void OutOfProcess()
    {
        _Output.WriteLine("Process name: " + Process.GetCurrentProcess().ProcessName);
        Assert.Equal(1,1);
    }

SampleProcessFact 是一个声明的自定义属性。

[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.SampleProcessFactDiscoverer", "XUnitRemote.Test")]
public class SampleProcessFactAttribute : FactAttribute { }


[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.ScheduledSampleProcessFactDiscoverer", "XUnitRemote.Test")]
public class ScheduledSampleProcessFactAttribute : FactAttribute { }

[AttributeUsage(AttributeTargets.Method)]
[XunitTestCaseDiscoverer("XUnitRemote.Test.SampleProcessTheoryDiscoverer", "XUnitRemote.Test")]
public class SampleProcessTheoryAttribute : TheoryAttribute { }

有关源代码,请参阅https://github.com/Weingartner/XUnitRemote/blob/master/XUnitRemote.Test/XUnit.cs#L26

但是我们想要一个选项,这样如果我将我的测试用例标记为 SampleProcessFact ,那么测试运行器将只按顺序运行测试。

我知道我可以使用 TestCollection(字符串ID)标记我的所有测试用例,并且它应该阻止顺序运行,但是如果应该将其封装在 SampleProcessFact 标记中可能。这应适用于所有程序集中的所有测试用例。

我的问题只涉及从视觉工作室开始测试。远程部分工作正常,但visual studio正在为所有测试并行调用我们的远程测试用例引擎。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我们签入了解决问题的项目。

https://github.com/Weingartner/XUnitRemote/commit/565e1dfb55f65ff0612afa40bc5d076c69bb739c

一般解决方案是拦截XUnitRemoteTestCaseDiscoverer :: Discover中的 ITestMethod 实例,并重写其测试集合的UniqueId。

    public IEnumerable<IXunitTestCase> Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
    {
        if(CollectionId.HasValue)
            testMethod = WrapTestMethod(testMethod, CollectionId.Value);

        if (!Process.GetCurrentProcess().ProcessName.Equals(Path.GetFileNameWithoutExtension(_ExePath), StringComparison.OrdinalIgnoreCase))
        {
            yield return new XUnitRemoteTestCase(_DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, _Id, _ExePath);
        }
        else
        {
            foreach (var testCase in _DefaultTestCaseDiscoverer.Discover(discoveryOptions, testMethod, factAttribute))
            {
                yield return _TestCaseConverter(testCase);
            }
        }
    }

    private ITestMethod WrapTestMethod(ITestMethod testMethod, Guid uniqueId)
    {
        var testClass = testMethod.TestClass;
        var testCollection = testClass.TestCollection;
        testCollection = new TestCollection
            (testCollection.TestAssembly, testCollection.CollectionDefinition, testCollection.DisplayName)
        {
            UniqueID = uniqueId
        };
        testClass = new TestClass(testCollection, testClass.Class);
        testMethod = new TestMethod(testClass, testMethod.Method);
        return testMethod;
    }