【问题标题】:Is it possible to use combination of TestCase and TestCaseSource/ValueSource in NUnit?是否可以在 NUnit 中使用 TestCase 和 TestCaseSource/ValueSource 的组合?
【发布时间】:2021-12-28 14:36:36
【问题描述】:

正如标题所说,我想使用TestCaseTestCaseSource/ValueSource 的组合。

这是一个例子:

public static string[] Source1 = new string[]
{
    "One", "Two", "Three"
};

public static string[] Source2 = new string[]
{
    "Four", "Five", "Six"
};

[TestCase("A"), TestCaseSource(nameof(Source1))]
[TestCase("B"), TestCaseSource(nameof(Source2))]
[TestCase("C"), TestCaseSource(nameof(Source1))]
[TestCase("C"), TestCaseSource(nameof(Source2))]
public void MyTest(string x, string y)
{
    // ...
}

这当然行不通,但我想做的是:

  • 针对 Source1 运行测试用例 A
  • 针对 Source2 运行测试用例 B
  • 针对 Source1 和 Source2 运行测试用例 C

有没有可能实现这样的目标?

【问题讨论】:

  • TestCaseSource 可以引用一个方法。该方法当然可以返回您需要的所有组合。文档中有一堆示例:docs.nunit.org/articles/nunit/writing-tests/attributes/…
  • 是的,当然,但是这个解决方案会在我的TestCaseSource 方法中创建很多重复记录,我必须记住,当我想在 Source 中添加新参数时,我必须将其添加到每个TestCase。我正在努力避免这些问题。

标签: c# unit-testing nunit


【解决方案1】:

回答很长,因为我想澄清所涉及的权衡...

我会按照你第一次提出的问题来回答:是否可以在 NUnit 中使用 TestCase 和 TestCaseSource/ValueSource 的组合?

是的,是的。 NUnit 允许您在方法上组合任何测试用例数据源。

  • TestCase 为您提供一个测试用例
  • TestCase 源为您提供多个测试用例
  • ValueSource 为您提供一个参数的数据(即测试用例的一部分)

在您的示例中,您总共为 MyTest 方法提供了 16 个测试用例。当然,所有这些都是无效的,因为 MyTest 接受两个参数,而您的每个测试用例只提供一个值。

从示例中可以看出,您希望放置在相同括号内的属性以某种方式分组。这不是 C# 解释它们的方式。你写的和写的完全一样:

[TestCase("A")]
[TestCase("B")]
[TestCase("C")]
[TestCaseSource(nameof(Source1))]
[TestCaseSource(nameof(Source2))]
[TestCaseSource(nameof(Source1))]
[TestCaseSource(nameof(Source2))]

这不是 NUnit 问题。这就是 C# 属性的工作原理。

因此,虽然可以在同一个方法中组合属性,但不可能以您想要的方式将这些属性的值组合到测试用例中。

NUnit 确实有一种方法可以使用ValuesValueSource 属性组合值,这适用于单个参数而不是方法。

使用ValuesAttribute,您可以像这样重写您的示例...

public void MyTest(
    [Values("A", "B", "C")] string x,
    [Values("One", "Two", "Three")] string y )
{
    // ...
}

几乎对你有用,但并不完全。创建了九个案例,("A", "B", "C")("One", "Two", "Three") 的所有可能组合。但是,您希望“B”与“四”、“五”和“六”结合,而“C”与第二个参数的所有六个值结合。 ValuesValueSource 都不允许你控制到那种程度。

这让我们回到了TestCaseSource。正如评论中所建议的,您可以使用一种方法通过TestCaseSourceAttribute 提供测试用例。这是您编写此类方法的一种方式...

static IEnumerable<TestCaseData> MySource()
{
    var source1 = new [] { "One", "Two", "Three" };
    var source2 = new [] { "Four", "Five", "Six" };
    var source3 = source1.Concat(source2);

    foreach (var y in source1)
        yield return new TestCaseData("A", y);

    foreach (var y in source2)
        yield return new TestCaseData("B", y);

    foreach (var y in source1)
        yield return new TestCaseData("C", y);
}

也就是说,上面需要 12 行,不包括空白行,并生成 12 个测试用例。我自己的方法是为了清晰而避免复杂性,并使用一组 TestCaseData 项专门枚举您想要的情况,例如...

var MySource = new [] {
    new TestCaseData("A", "One"),
    new TestCaseData("A", "Two"),
        etc...
};

这样做的好处是以后查看代码的任何人都易于理解,包括几个月后的您自己。 :-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多