依靠NUnit单元测试的顺序是不好的形式

时间:2009-01-30 23:33:31

标签: unit-testing nunit

我一直在疯狂地创建单元测试,发现我经常需要在一次测试中设置一些我刚刚在之前的测试中被删除的测试。在一次测试(例如插入测试)中创建某些东西(例如数据库记录)然后用它来进行后续测试(例如删除测试)是否合理?或者每个测试是否应该完全独立?

您甚至可以确定NUnit中的测试顺序,还是按字母顺序完成?

注意:我特别询问一个测试文件中的测试顺序。 跨测试文件或以任何方式更全局。

更新:感谢所有回答的人 - 有一个很多的好答案,而且团队的感觉非常一致。我选择了John Nolan的答案,因为他提供了最全面的解释和很多链接。正如你可能已经猜到的那样,尽管我认为像约翰所说的那样可能有点“臭”,但我一直非常想要打破这个规则。还要感谢Fortyrunner添加单元测试标签。

8 个答案:

答案 0 :(得分:11)

查看test fixture setups,允许您指定在灯具中的任何测试之前执行的功能。这允许您进行一次常规设置,无论您运行一个测试还是套件中的所有测试,它都将始终运行。

答案 1 :(得分:10)

依赖于测试的顺序表明您在测试中保持状态。这是 smelly

更简洁的测试方式是您只依赖于要检查其行为的单一功能。通常是mock您需要的其他对象,以使您的测试方法正常运行。

考虑接近单元测试的好方法是Arrange, Act, Assert模式。

以下是Karl Seguin优秀免费eBook的摘录。我已经注释了安排,行动和断言。

[TestFixture] public class CarTest 
{ 
    [Test] public void SaveCarCallsUpdateWhenAlreadyExistingCar()   
    {
         //Arrange
         MockRepository mocks = new MockRepository();
         IDataAccess dataAccess = mocks.CreateMock<IDataAccess>();   
         ObjectFactory.InjectStub(typeof(IDataAccess), dataAccess); 
         //Act
         Car car = new Car(); 
         Expect.Call(dataAccess.Save(car)).Return(389); 
         mocks.ReplayAll(); 
         car.Save(); 
         mocks.VerifyAll(); 
         // Assert
         Assert.AreEqual(389, car.Id); 
         ObjectFactory.ResetDefaults();
    } 
}

答案 2 :(得分:8)

单元测试旨在独立运行,而不是作为顺序脚本运行。如果您确实需要它们按顺序运行,请将它们收集到一个测试函数中。

如果您的单元测试受expensive set-up影响,当您认为自己正在进行单元测试时,可能正在进行集成测试。如果您在大多数单元测试中遇到SQL数据库,那么您实际上是在与数据访问层进行集成测试。

答案 3 :(得分:6)

我认为每个测试完全独立于任何其他测试。即使你可以强制执行测试的顺序,当测试必须改变时,这将是一个维护噩梦。

答案 4 :(得分:3)

我真的不会依赖于测试的排序。相反,我将公共设置代码拉入一个单独的方法,并从简单测试和更复杂的测试中调用它。或者,只需在删除测试开始时调用插入测试。

答案 5 :(得分:3)

我强烈建议让所有单元测试独立。

您的业务逻辑/数据库结构等可能会随着时间的推移而发生变化,因此您最终必须更换或重写(甚至丢弃)现有的单元测试 - 如果您还有其他几项测试,则取决于您的测试重新替换,这可能会导致不必要的麻烦,因为您还必须完成所有其他测试,并检查这些测试是否仍然按预期工作。

此外,一个失败的单元测试不应该拖累许多其他(可能完全可以自行工作)。

答案 6 :(得分:2)

不幸的是,单元测试的运行顺序是不可预测的,或者至少可以在将来进行更改。例如。单元测试框架将被更改,因此每个测试将在单独的线程中执行。 所以从我的观点来看,使用测试顺序是不合理的。 另一方面,您可以创建一组小的独立测试来测试代码的小部分,然后创建一个或多个大型测试,以便按特定顺序运行小型测试。

答案 7 :(得分:2)

如果你有状态测试(数据库工作的一个常见问题 - 这就是我不在的时候做的事情),那么在我看来,避免测试文件中的顺序并非绝对必要。但是,您必须认识到,如果您有2个测试,测试2取决于测试1的传递,那么如果测试1失败,您将获得“灾难性”双重故障,因为测试2没有预期的设置(并且,更重要的是,如果您认为测试2取决于测试1通过,那么如果测试2在测试1失败后通过测试2,您会担心。

这就是为什么你希望测试独立 - 无论是文件内还是文件间。

依赖不同文件中的(组)测试之间的顺序是非常不明智的。