在unit testing中多重声明是不好的? 即使链接?

在unit testing中检查如此之多的东西有什么不对吗?

ActualModel = ActualResult.AssertViewRendered() // check 1 .ForView("Index") // check 2 .WithViewData<List<Page>>(); // check 3 CollectionAssert.AreEqual(Expected, ActualModel); // check 4 

这个testing的主要目标是validation返回的正确的视图(检查2),它包含正确的数据(检查4)。

我可以通过将其分成多个testing来获得任何东西吗? 我所做的一切都是正确的,但是如果它没有实际价值,我不会分裂它。

我对unit testing很新,所以要温和。

正如其他人所指出的那样,最好在每个testing中坚持一个断言,以避免丢失信息 – 如果第一个断言失败,则不知道后面的错误是否也会失败。 你必须用更less的信息来解决问题 – 这可能(可能会更困难)。

Roy Osherove的unit testing艺术非常好的参考 – 如果你想unit testing开始,你可能会比从这里开始更糟糕。

注意未来的读者,这个问题及其重复在unit testing中有多个断言是不好的做法? 有相反的多数意见,所以阅读它们并自己决定。

我的经验是,最有用的testing量不是断言,而是场景 – 也就是说,对于一组给定的初始条件和方法调用,应该有一个unit testing,并且要有足够的断言来断言预期的最终条件。 每个断言有一个unit testing会导致重复的设置或曲折的解决方法,以避免重复(例如,我最近看到越来越多的深层嵌套的rspec上下文)。 它也增加了testing,大大减慢你的套件。

只要每个断言都有一个唯一的识别失败信息,你应该是好的,并且会回避任何断言轮盘问题,因为不会很难说出哪个testing失败。 使用常识。

我发现这个问题有一个不同的观点(至less对我自己来说):

如果他们正在testing相同的东西,使用多个断言是可以的。

例如,可以这样做:

 Assert.IsNotNull(value); Assert.AreEqual(0, value.Count); 

为什么? – 因为这两个断言不隐藏testing的意图。 如果第一个断言失败,则意味着第二个失败。 事实上,如果我们删除第一个断言,那么第二个断言失败(空引用exception – !!!),无论如何value null。 如果情况并非如此,那么我们不应该把这两个断言放在一起。

所以,这是错误的:

 Assert.IsNotNull(value1); Assert.IsNotNull(value2); 

正如我在上面提到的,如果第一个断言失败了,第二个断言没有明确的指示 – 我们仍然想知道第二个断言发生了什么( 即使第一个失败 )。 因此,这两个断言属于两个不同的unit testing。

结论: 如果正确地完成一个或多个断言,就会成为偏好的问题 – 无论我们希望在testing结果中看到断言例外,还是在特定情况下也想看到其他例外情况。

在每个testing中最好只保留一个断言来避免断言轮盘 。

如果您需要设置相同的场景以根据相同的前提条件testing多个条件,最好将设置代码提取到共享的帮助程序方法,然后编写几个调用此帮助程序方法的testing。

这确保了每个testing用例只testing一件事情。

和往常一样,这个规则也有例外,但由于你是unit testing新手 ,所以我build议你坚持每个unit testing规则的一个断言,直到你知道何时可以偏离为止。

我知道这是一个古老的问题,但我想我会补充一点。

一般来说,在每个testing用例中,尽可能less的断言。 通常可以写testing来保存许多不同的断言。

假设我有一个从名字的组成部分创造称呼的方法(例如史密斯先生)的unit testing。 我想用大量不同的场景来检查这一点,不必为每个场景单独进行testing。

鉴于下面的代码,有许多不同的断言。 当它们失败时,可以一次一个地修复它们,直到断言停止。

 Assert.AreEqual("Mr Smith", GetSalutation("Mr", "J", "Smith")); Assert.AreEqual("Mr Smith", GetSalutation("Mr", "John", "Smith")); Assert.AreEqual("Sir/Madam", GetSalutation("", "John", "Smith")); Assert.AreEqual("Sir/Madam", GetSalutation("", "J", "Smith")); 

另外一个办法是保留一些问题并在最后声明这一点。

 int errorCount = 0; string result; result = GetSalutation("Mr", "J", "Smith"); if (result == "Mr Smith") errorCount++; result = GetSalutation("Mr", "John", "Smith"); if (result == "Mr Smith") errorCount++; Assert.AreEqual(0, errorCount); 

在现实世界的情况下,我可能会添加一些跟踪命令,将单个testing的细节写入输出窗口