布置单元测试 - 嵌套类还是完全隔离?

时间:2011-11-02 13:57:47

标签: unit-testing

我有一个课程,我已经抽象出来,变得可测试并开始陷入一个有趣的困境。这些测试类是否应该嵌套?例如......

public class ValidateCompanyTests
{
     public virtual Setup()
     {
          //setup stuff
     }

     [TestClass]
     public class AndCompanyDoesNotExist : ValidateCompanyTests
     {
          public override Setup()
          {
               base.Setup();
               //setup specific condition
          }

          [TestMethod]
          public void ShouldReturnFalse()
          {

          }

          [TestMethod]
          public void ShouldCreateError()
          {

          }

          [TestMethod]
          public void ShouldSaveError()
          {

          }
     }
}

AndCompanyDoesExist的设置几乎相同,但条件更多。

我的问题是,除了明显的方法只是在MSTest打印出来之外,我不确定这是否是“更正确”的做法,或者我应该让每个测试完全隔离。会有很多重复的代码(设置,配置),这就是我做出这个决定的原因,但我想要一些社区意见,想法,想法。

所以把它放在我身上! (这也应该是社区维基吗?)

3 个答案:

答案 0 :(得分:4)

我过去在这种方法中遇到的问题是,起初看起来很简单。嵌套上下文很棒,直到达到你的第二级继承。突然之间,你会失去对你的测试生活世界的追踪,除非你潜入3层次的等级,并拍摄大量笔记,绘制地图,施放符文等。

我赞成一种方法,其中设置上下文的机制由测试本身明确指示。每个测试类表示一个上下文,它可以单独设置,也可以通过利用外部帮助程序集来创建所需的对象。这样,我总是能够查看测试初始化​​方法,并至少看到对该类测试的“世界”的高级描述。

让“帮助者”尽可能地相互利用,但测试设置本身应该像这样的伪代码: Given_a_valid_Customer()   .WithValidOrders(2)   .WithInvalidOrders(1);

Given_a_valid_Customer应设置客户以及任何所需的子对象,如地址。 .WithValidOrders(2)添加两个有效的命令,包括所需的任何子对象,如LineItems。 最后,.WithInvalidOrders增加了一个订单,但有一些致命缺陷。

重点是设置不会陷入细节之中。什么使订单有效或无效?谁在乎,这不是这个测试的内容。此测试仅关注在几个有效的订单中存在无效订单,这是唯一重要的细节。无效顺序的定义可以在别处定义,然后由多个测试上下文使用。如果关于该定义的某些内容稍后会发生变化,那么它可以在一个辅助方法中“修整”,而不是在数百个单独的测试中。

当我看这个测试时,我知道它的世界在我关心的细节水平上是什么样的。

答案 1 :(得分:1)

如果您的目标是最小化重复的设置代码量,我将使用内部类的继承。 Inhertiance还将为您提供更多的重用灵活性,并使您的测试更容易重构。

答案 2 :(得分:1)

我的个人偏好;我会将共享设置内容分解为实用程序类,并将实际测试完全分开。

这里有很多关于这个主题的讨论; Unit Testing: Self-contained tests vs code duplication (DRY)