每个案例 NUnit 的参数化测试与测试方法

Parameterized tests vs Test method for each case NUnit

我正在看 NUnit 的课程,我来参加这个练习是为了为下面的函数编写一个测试方法

public static string GetOutput(int number)
    {
        if ((number % 3 == 0) && (number % 5 == 0))
            return "FizzBuzz";

        if (number % 3 == 0)
            return "Fizz";

        if (number % 5 == 0)
            return "Buzz";

        return number.ToString(); 
    }

我所做的是创建了一个参数化测试来涵盖如下所有情况

 [Test]
    [TestCase(15 , "FizzBuzz")]
    [TestCase(3, "Fizz")]
    [TestCase(5, "Buzz")]
    public void GetOutput_WhenCalled_ReturnString(int number , string word)
    {
        var result = FizzBuzz.GetOutput(number);
        Assert.That(result, Is.EqualTo(word));
    }

但是导师用单独的方法写了每个案例,例如

public void GetOutput_NumberDivisiableNy3And5_ReturnFizzBuzz()
{
    var result = FizzBuzz.GetOutput(15);
    Assert.That(result, Is.EqualTo("FizzBuzz"));
}

public void GetOutput_NumberDivisiableBy3_ReturnFizz()
{
    var result = FizzBuzz.GetOutput(3);
    Assert.That(result, Is.EqualTo("FizzBuzz"));
}

我的问题是他为什么要这样写?像这样分开它有一些优势吗? 还是仅仅是个人喜好。我对单元测试和 Nunit

很陌生

归根结底,这是个人喜好。但是,当您正在测试的方法接受参数时,使用参数化测试似乎很自然。 OTOH,不要使用参数化测试来为两个或多个完全不同的事物编写测试......事实上,一次不要为多个目的编写测试!

我的猜测是您的讲师正在尝试从基本方法开始,并且只会在以后的课程中介绍参数化测试。当然这只是猜测。

这是个人喜好。

测试时的一个重要准则是,您为测试选择的名称应该描述针对给定输入测试的方法的期望行为。将测试名称视为类似于可执行文档:“在情况 X 下,该方法应表现出行为 Y。”

使用参数化测试意味着测试名称本质上缺乏描述性,这使得一眼就更难准确地识别失败的原因——您必须查看测试参数才能确定失败的情况,因为测试名称没有为您提供该信息。

这甚至在您的实现中也很明显:您的测试名称表示“returns string”“调用时 ”。这在技术上是正确的,但不是 描述性的 。当使用 给定值调用时,应该什么字符串return?

另一方面,各个测试用例使所需的行为非常清楚:可被 3 和 5 整除的数字应该 return“FizzBu​​zz”,等等。

此外,请这样想:如果要求您返回此方法并将其展开以在数字可被 7 整除时打印 Fuzz,会发生什么情况? Biz 能被 9 整除吗?等等。您的单一测试方法 可以 完成所有这些繁重的工作,但是您的要求越多,单个测试用例的负担就越大,并且越难清楚地识别哪些场景失败了,为什么。

您的方法没有错,但是如果我编写这些测试,我会为每个场景编写一个测试用例:Fizz、Buzz、FizzBu​​zz,并且不能被任何东西整除。

每个测试用例仍然可以参数化,因此您可以测试更多满足每个测试用例的值。