如何使用 ITestFilterService and/or ITestFilterBuilder 以编程方式为 NUnit 3 创建自定义过滤器

How can I create a custom filter for NUnit 3 programmatically, with ITestFilterService and/or ITestFilterBuilder

TLDR:如何根据部分测试名称、正则表达式或(部分)类别名称以编程方式过滤 NUnit 3.x 测试。

我正在转换一个项目,该项目具有自己的过滤机制,用于从 NUnit 2.6 -> NUnit 3.8 进行 运行ning 测试。

我尝试支持的过滤器是名称的部分字符串匹配、正则表达式匹配、名称匹配和类别匹配。由于这个项目有大约 30k+ 测试,其中一些很耗时,自定义 运行ner 已被证明有助于让我们保持理智。

然而,我似乎只见树木不见森林。我试图阅读 Test Engine API 上的文档,它基本上链接到接口的源代码。在我看来,我需要 ITestFilterService,然后 ITestFilterBuilder,但后来我似乎卡住了。

NUnit 2.6 附带了一堆我只需要扩展的预定义过滤器。现在,我赞同将测试 运行ner API 从 NUnit 框架中分离出来的新方法,而且我在文档中潜水没有问题,但似乎它们很少(或者我的搜索技能,缺乏)。

我得到了以下(F#代码,从C#代码翻译而来),但后来我卡住了:

let path = Assembly.GetExecutingAssembly().Location
let package = new TestPackage(path)
package.AddSetting("WorkDirectory", Environment.CurrentDirectory)
let engine = TestEngineActivator.CreateInstance()
let filterService = engine.Services.GetService<ITestFilterService>()
let filterBuilder = filterService.GetTestFilterBuilder()

我什至不知道它是否有效,因为在我重构整个项目之前我不能 运行 它...ITestFilterBuilder 有三种方法,AddTestGetFilterSelectWhere。但是这些都是带字符串的,我不知道要往里面放什么。

我似乎需要 SelectWhere,它需要一个 whereClause,但在工具提示、智能感知或任何关于使用什么语法的地方都没有帮助(SQL?XPath?) .

有人有什么想法吗?那里有一些我可以使用的预定义过滤器的项目,或者那里的示例代码?

如果像这样传递一个空过滤器,您可以了解要添加到过滤器的内容:

var filterService = nunitEngine.Services.GetService<ITestFilterService>();
ITestFilterBuilder builder = filterService.GetTestFilterBuilder();
....
var testResult = runner.Run(testListener, filter);

当你运行这个时候,假设一切正常,你会得到一个XML节点响应,其中有一些嵌套的<test-suite>节点,下面会有一些<test-case>节点:

<test-suite 
    type="TestFixture" 
    id="0-1000" 
    name="Tests" 
    fullname="SampleUnderTest.Tests.NUnit.Tests" 
    classname="SampleUnderTest.Tests.NUnit.Tests" 
    runstate="Runnable" 
    testcasecount="1" 
    result="Passed" 
    start-time="2020-08-26 15:51:23Z" 
    end-time="2020-08-26 15:51:23Z" 
    duration="0.031570" 
    total="1" 
    passed="1" 
    failed="0" 
    warnings="0" 
    inconclusive="0" 
    skipped="0" 
    asserts="1">
  <test-case 
       id="0-1001" 
       name="AddWithGivenInputsReturnsExpectedResults"
       fullname="SampleUnderTest.Tests.NUnit.Tests.AddWithGivenInputsReturnsExpectedResults"            
       methodname="AddWithGivenInputsReturnsExpectedResults" 
       classname="SampleUnderTest.Tests.NUnit.Tests" 
       runstate="Runnable" 
       seed="81337978" 
       result="Passed" 
       start-time="2020-08-26 15:51:23Z" 
       end-time="2020-08-26 15:51:23Z" duration="0.028935" asserts="1" />
</test-suite>

现在,回到我们的ITestFilterBuilder

ITestFilterBuilder builder = filterService.GetTestFilterBuilder();

public 方法之一是 ITestFilterBuilder.AddTest(string fullName)

参数 fullName 匹配返回的 XML 的 fullName 属性。如果我们从 <test-case> 节点之一传入 fullName,我们就能够 运行 测试:

builder.AddTest("SampleUnderTest.Tests.NUnit.Tests.AddWithGivenInputsReturnsExpectedResults");

当我们再次 运行 时,我们根 <test-suite> 上的结果告诉我们有多少测试 运行、通过、失败等以及各种其他统计数据它。