如何通过代码执行XUnit测试

时间:2015-03-25 03:21:06

标签: c# xunit xunit.net

我使用InlineData和MemberData属性在XUnit中编写了测试。我希望通过我项目中其他地方的代码运行测试,并让属性自动填充测试数据,就像通常在VS测试运行器中运行一样。

如果不是属性,我会直接调用方法,就像任何其他常规方法一样。断言仍然被检查,它运行正常。但是,如果我直接调用具有属性的方法,则忽略属性,并且必须通过代码手动提供所有测试数据。在XUnit中是否有某种类型的测试运行器类可以重用来实现这一目标?我一直试图挖掘他们的API无济于事。

为什么我要这样做会得到一些解释,但请耐心等待。我正在针对特定接口而不是具体实现编写测试(例如,考虑标准集合接口)。那里有足够的测试,我不想为每个具体的实施者复制粘贴它们(可能是几十个)。我编写测试一次,然后将接口的每个具体实现作为测试的第一个参数传递,这是一个要测试的主题。

但这留下了一个问题。 XUnit看到了测试并希望运行它,但它不能,因为在这一层没有具体的实现,只有接口。所以我想在更高层编写测试,只是新建具体实现,然后调用传递新主题的接口测试。我可以轻松地为只接受1个参数的测试做主题,但是对于我正在使用InlineData或MemberData的测试,我想重用已经提供的那些测试用例,并且只是将主题添加为第一个参数。

2 个答案:

答案 0 :(得分:6)

可供参考的是xUnit.net项目中的GitHub问题How to programmatically run XUnit tests

班级AssemblyRunnernow part of Xunit.Runner.Utility

在链接问题中,xUnit.net撰稿人Brad Wilson在sample runner中提供了samples.xunit project on GitHub。该程序演示了该问题中描述的技术。也就是说,在发现测试后负责运行测试的部分如下:

    using (var runner = AssemblyRunner.WithAppDomain(testAssembly))
    {
        runner.OnDiscoveryComplete = OnDiscoveryComplete;
        runner.OnExecutionComplete = OnExecutionComplete;
        runner.OnTestFailed = OnTestFailed;
        runner.OnTestSkipped = OnTestSkipped;

        Console.WriteLine("Discovering...");
        runner.Start(typeName);

        finished.WaitOne();  // A ManualResetEvent
        finished.Dispose();

        return result;
    }

为了更深入地了解,他描述了一种使用XunitFrontControllerTestDiscoveryVisitor来查找和运行测试的方法。这是AssemblyRunner为其实施所做的工作。

答案 1 :(得分:0)

没关系,我明白了。仔细研究一下XUnit的属性层次结构,我发现DataAttributes(InlineData,MemberData等)有一个GetData方法,你可以调用它来检索它们代表的数据集。通过一点反射,我可以很容易地在我的测试类中找到所有测试并调用测试方法,如果存在任何存在则调用data属性的get数据方法,并通过我自己的代码执行测试。如果我不得不扮演我自己的版本角色,GetData部分会更难。谢谢XUnit作者没有强迫我这样做。