VB.NET和NUnit - TDD

5

我正在学习使用VB.NET和NUnit进行TDD。 我想知道最好的做法是什么:在测试方法内使用大量Assert方法还是每个方法使用一个assert?

这是我的代码。

Imports NUnit.Framework

<TestFixture()> _
Public Class CalculatorTest
<Test()> _
Public Sub TestAdd()
    Dim calculator As Calculator = New Calculator()

    Assert.AreEqual(2, calculator.sum(1, 1))
    Assert.AreNotEqual(3, calculator.sum(2, 2))
    Assert.AreEqual(-1, calculator.sum(0, -1))
        Assert.AreNotEqual(3, calculator.sum(1, 1))
    End Sub
End Class
3个回答

7
更好的方式是一次只测试一件事情。使用尽可能多的断言来测试这一件事情,但通常只需要一个。多个断言可能意味着你在同时测试多个事情,但在我看来,这不是一个硬性规定。最好的指导原则是不要在测试之间创建独立概念的依赖关系。
在你的例子中,实际上你正在测试4件事情,尽管你实际上可能只需要其中两件,因为它们涵盖了相同的内容。我建议测试当你添加两个正数、两个负数和一个正负混合时会发生什么,以及正交性和加法恒等式(零)等数学属性。最后,我会测试边界条件——正溢出和负溢出等。请注意,这可能不是全面的,即我认为我已经涵盖了基本情况,但我并没有试图详尽无遗;我只是想说明如何思考编写测试,并且,是的,我会将每个测试分开,并只有一个断言。
对于更复杂的问题,您可能需要多个断言来测试同一个“thing”——例如,您可能想检查在给定的输入下是否正确插入了一行到数据库中。我认为,在单个测试中测试所有列是否具有其正确的值,而不是逐个测试每个属性,是完全可以接受的。其他人可能会有不同的看法,但我认为,在这种情况下,通过测试所有属性是否具有其正确的值来测试插入操作并不会创建任何依赖关系,因为插入是一个原子性操作。

5
通常被认为是“最佳实践”的做法是每个测试只有一个断言。(根据Roy Osherove的说法)
然而,使用TestCases可以更简单地完成这个特定的测试,使用NUnit即可。
<Test()> _
<TestCase(1, 1, 2)> _
<TestCase(1,-1, 0)> _
<TestCase(0,-1,-1)> _
Public Sub Calculator_Add_ReturnsExpectedResult(Integer a, Integer b, Integer expected)
    Dim calculator As Calculator = New Calculator()

    Assert.AreEqual(expected, calculator.sum(a, b))
End Class

请注意我在这里使用的名称,以便准确说明测试正在测试的内容。

“每个测试仅有一个断言”实践的原则是,您希望失败的测试具有非常特定的含义。也就是说,每个测试都应该告诉您一个单独的特定事物是否正常工作。


<TestCase(1, 1, 2)> _ :这是什么意思?谢谢。 - Thomas
这意味着它将多次调用您的测试函数,每次使用不同的输入(如注释中指定)。在这种情况下,它将调用三次,首先是(1,1,2),然后是(1,-1,0),最后是(0,-1,-1)。 - Martin Wickman
1
请注意,像这样作为单独的测试用例,每个断言都会被运行和报告,无论前面的断言是否通过。因此,如果出现任何问题,您将获得更完整的失败报告。在一个方法内的断言中,如果第一个断言失败,您将不知道其他断言的结果。 - Carl Manaster

0
Osherove 的观点有点像教条主义。例如,如果一个函数返回一个结构体/类,你要么需要使用多个断言,要么制作一个自定义的结构体比较断言,这实际上只是做同样的事情。
重要的是测试功能所做的事情。也许始终要质疑“专家”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接