在不同节点下有多个同名测试

have multiple tests with same name under different node

我有两个共享相同数据的不同测试:

[TestCaseSource(nameof(ProvideTestCases))]
public void SubtractSegmentsTests(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected)
{
    GeometryTools.SubtractSegments(polyline, toRemove, tol, null);
    AssertEqualPoints((IPointCollection) expected, (IPointCollection) polyline);
}
[TestCaseSource(nameof(ProvideTestCases))]
public void SubtractSegmentsTests_With_Esri(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected)
{
    var actual = ((ITopologicalOperator)polyline).Difference(toRemove);
    AssertEqualPoints((IPointCollection)expected, (IPointCollection)actual);
}

所以我想要实现的是测试两种不同的方法,如果两者 return 完全相同的结果。因此,两种测试方法都引用完全相同的测试用例:

public IEnumerable<TestCaseData> ProvideTestCases()
{
    yield return new TestCaseData(...).SetName("Test1");
}

当我使用 ReSharper 在 VS 中执行我的测试时,这非常有效。 test-运行ner 能够将属于 SubtractSegmentsTests 的测试与属于 SubtractSegmentsTests_With_Esri 的测试分开。

现在我 运行 来自我的 Jenkins-Server 的那些测试:

call "C:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe" MySuT.dll --result:testresults/result.xml;format=nunit2

这里 NUnit 将所有测试排序在同一节点下 - 测试类 - 使得无法区分从 SubtractSegmentsTests 调用的 Test1 和从 SubtractSegmentsTests_With_Esri 调用的 Test1

有什么方法可以在我的 CI 服务器上也获得这种聚合级别吗?

一种快速而肮脏的方法是在 TestCaseSource 中引用两种不同的方法。

[TestCaseSource(nameof(ProvideTestCases1))]
public void SubtractSegmentsTests(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected)
{
    GeometryTools.SubtractSegments(polyline, toRemove, tol, null);
    AssertEqualPoints((IPointCollection) expected, (IPointCollection) polyline);
}
[TestCaseSource(nameof(ProvideTestCases2))]
public void SubtractSegmentsTests_With_Esri(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected)
{
    var actual = ((ITopologicalOperator)polyline).Difference(toRemove);
    AssertEqualPoints((IPointCollection)expected, (IPointCollection)actual);
}

现在创建第三个方法,ProvideTestCases1ProvideTestCases2 都使用一个参数调用,该参数指示调用来源:

public IEnumerable<TestCaseData> ProvideTestCases1()
{
    return ProvideTestCases("Prefix1.");
}

public IEnumerable<TestCaseData> ProvideTestCases2()
{
    return ProvideTestCases("Prefix2.");
}

private IEnumerable<TestCaseData> ProvideTestCases(string prefix)
{
    yield return new TestCaseData(...).SetName(prefix + "Test1");
}

现在测试的名称是串联的,例如Prefix1.Test1.

这不会像在 VS 中那样基于 test-method 聚合您的测试,但至少您可以区分它们。

编辑:您甚至不需要三种方法。您还可以使用单个参数化的参数并选择 the overload of TestCaseSource 为源提供参数:

[TestCaseSource(nameof(ProvideTestCases), new object[] { "Prefix1" })]
public void SubtractSegmentsTests(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected) { ... }

[TestCaseSource(nameof(ProvideTestCases), new object[] { "Prefix2" })]
public void SubtractSegmentsTests(IPolyline polyline, IPolyline toRemove, double tol, IGeometry expected) { ... }

好吧,重申一下您可能已经很明显的内容,您的两个测试只有相同的名称,因为您为它们指定了相同的名称。 :-)

一些跑步者认为名字是唯一的。为了应对不做那种假设的NUnit,他们通常会添加一些前缀。 NUnit 控制台运行器对所有具有相同名称的测试感到满意,因为它们实际上是由一个(隐藏的)id 标识的。所以 NUnit 控制台不会费心以不同的方式显示它们,尽管如果有足够多的人问,它可以。

但是,NUnit 还使您能够在设置自己的名称时使其独一无二。在这种情况下,您只需在设置名称的字符串中包含“{m}”,测试方法的名称将被用在它的位置。

有关设置名称的详细信息,请参阅 https://github.com/nunit/docs/wiki/Template-Based-Test-Naming

上的文档