单元测试指南

时间:2008-09-20 02:19:12

标签: unit-testing tdd

有谁知道在哪里可以找到单元测试指南和建议?我想要解决以下类型的主题(例如):

  • 测试应该与应用程序逻辑在同一个项目中吗?
  • 我应该有测试类来镜像我的逻辑类,还是应该只有我认为需要的测试类?
  • 我应该如何命名我的测试类,方法和项目(如果他们进入不同的项目)
  • 应该测试私有,受保护和内部方法,还是只测试可公开访问的方法?
  • 单元和集成测试应该分开吗?
  • 是否有良好理由没有100%的测试覆盖率?

我不应该问我应该做什么?

在线资源最好。

7 个答案:

答案 0 :(得分:21)

我建议在TDD上预订Kent Beck's

此外,您需要访问Martin Fowler's网站。他也有很多关于测试的好信息。

我们在TDD方面非常重要,所以我将以此为基础回答这些问题。

  

测试应该与应用程序逻辑在同一个项目中吗?

通常我们将测试保持在同一个解决方案中,但是我们将测试分解为单独的DLL /项目,这些DLL /项目镜像他们正在测试的DLL /项目,但是维护名称空间并且测试位于子命名空间中。示例:Common / Common.Tests

  

我是否应该有测试类来镜像我的逻辑类,或者我应该只有我认为需要的测试类?

是的,您应该在创建任何类之前创建测试,并且根据定义,您应该仅隔离测试单个单元。因此,您应该为解决方案中的每个类设置一个测试类。

  

我应该如何命名我的测试类,方法和项目(如果他们进入不同的项目)

我想强调行为是正在测试的,所以我通常在SUT之后命名测试类。例如,如果我有一个User类,我会像这样命名测试类:

public class UserBehavior

应该命名方法来描述您期望的行为。

public void ShouldBeAbleToSetUserFirstName()

项目可以根据需要进行命名,但通常您希望它正在测试哪个项目相当明显。请参阅有关项目组织的先前答案。

  

应该测试私有,受保护和内部方法,还是只测试可公开访问的方法?

同样,您希望测试断言预期的行为,就像您是被测对象的第三方使用者一样。如果您测试内部实现细节,那么您的测试将是脆弱的。您希望测试为您提供重构的自由,而不必担心破坏现有功能。如果您的测试了解实施细节,那么如果这些细节发生变化,您将不得不更改测试。

  

单元和集成测试应该分开吗?

是的,单元测试需要与验收和集成测试分开。关注点的分离也适用于测试。

  

是否有充分理由不进行100%的测试覆盖?

我不会挂掉100%的代码覆盖率。 100%的代码覆盖率往往意味着测试中的某种程度的质量,但这是一个神话。你可以进行可怕的测试,但仍能获得100%的覆盖率。我宁愿依靠良好的Test First心态。如果您在编写一行代码之前总是编写测试,那么您将确保100%的覆盖率,因此它变得没有实际意义。

一般情况下,如果您专注于描述课程的完整行为范围,那么您将无需担心。如果你将代码覆盖率作为度量标准,那么懒惰的程序员只会做足够的事情来满足那个标记,你仍然会有糟糕的测试。相反,在很大程度上依赖同行评审,同时也会审查测试。

答案 1 :(得分:3)

这是一个很好的问题。我们有机地发展了自己,我怀疑最好的方法就是这样。那里有一点“它取决于......”。

我们在同一个项目中,在名为“UnitTes”的子命名空间中放置测试

我们的测试类镜像逻辑类,以简化跟踪测试与测试内容的关系

类的命名类似于他们正在测试的逻辑类,方法是根据他们正在测试的场景命名的。

我们只为公共和内部方法编写测试(测试在同一个项目中),目标是覆盖95%的课程。

我不想区分“单位”和“整合”。要花很多时间来弄清楚哪个是哪个......包包那个!测试是一项测试。

100%难以一直难以实现。我们的目标是95%。获得最终5%所花费的时间以及它实际捕获的内容的回报也在递减。

这就是我们以及适合环境和节奏的因素。你的milage可能会有所不同。想想你的环境和所涉及的个性。

我期待看到其他人对此问题的看法!

答案 2 :(得分:3)

Josh的回答是正确的 - 只有一点澄清:

我将单元测试与集成和验收测试分开的原因是速度。我使用TDD。我需要接近关于我刚创建/修改的代码行的即时反馈。如果我正在运行完整的集成和/或验收测试套件,那么我就无法做到这一点 - 这些测试可以触及真正的磁盘,真正的网络以及真正缓慢且不可预测的外部系统。

不要穿过横梁。如果你这样做会发生坏事。

答案 3 :(得分:1)

我坚持建议您阅读Test Driven Development: By ExampleTest-Driven Development: A Practical Guide单个主题的问题太多了

答案 4 :(得分:1)

按顺序:

  • 不,通常最好将它们包含在一个单独的项目中;除非您希望能够在运行时运行诊断程序。
  • 理想的是100%的代码覆盖率,这意味着每个类中每个例程的每行代码。
  • 我使用ClassnameTest,ClassnameTest.MethodNameTestnumber
  • 一切。
  • 我会说是的,因为如果单元测试失败,则不需要运行集成测试。
  • 不需要测试只设置和获取字段的简单属性。

答案 5 :(得分:1)

关于你的上一个问题,根据我的经验,不坚持100%测试覆盖率的“好”理由是,需要花费不成比例的努力来获得最后几个百分点,特别是在更大的代码库中。因此,一旦达到收益递减点,就决定是否值得花时间。

答案 6 :(得分:1)

测试应该与应用程序逻辑在同一个项目中吗?

这取决于。无论如何都有权衡。

将其保留在一个项目中需要额外的带宽来分配您的项目,额外的构建时间并增加安装空间,并且更容易犯下依赖于测试代码的生产逻辑的错误。

另一方面,保持单独的项目可能会使编写涉及私有方法/类(取决于编程语言)的测试变得更加困难,并导致轻微的管理麻烦,例如建立新的开发环境(例如,当一个新的开发人员更加努力地加入该项目。

这些不同成本的重要程度因项目而异,因此没有普遍的答案。

我应该有测试类来镜像我的逻辑类,还是应该只有我认为需要的测试类?

没有

您应该拥有允许考虑周全的测试代码的测试类(即最小重复,明确意图等)。

直接镜像测试类中的逻辑类的明显优势在于,它可以轻松找到与特定代码段相对应的测试。在不限制测试代码的灵活性的情况下,还有其他方法可以解决此问题。测试模块和类的简单命名约定通常就足够了。

我应该如何命名我的测试类,方法和项目(如果他们进入不同的项目)

您应该将它们命名为:

  • 每个测试类和测试方法都有明确的目的,并且
  • 以便有人能够轻松找到特定测试(或测试某个特定单元)。

应该测试私有,受保护和内部方法,还是只能公开访问?

通常应该测试非公开方法。这取决于您是否从仅测试公共界面获得足够的信心,或者您真正想要测试的单元是否可以公开访问。

单元和集成测试应该分开吗?

这取决于您选择的测试框架。做任何最适合您的测试框架的方法,并使其成为:

  • 与一段代码相关的单元测试和集成测试都很容易找到,
  • 只运行单元测试很容易,
  • 很容易只运行集成测试,
  • 很容易运行所有测试。

是否有充分的理由不进行100%的测试覆盖?

是的,有充分的理由。严格来说,“100%测试覆盖率”意味着您的代码中的每种可能情况都会得到锻炼和测试。这几乎对任何项目来说都是不切实际的。

如果您只是采用“100%测试覆盖率”来表示测试套件在某些时候执行了每行源代码,那么这是一个很好的目标,但有时在尴尬的地方只有几行自动化测试很难达到。如果定期手动验证该功能的成本低于通过扭曲达到最后五行的成本,那么这是不能实现100%线路覆盖的一个很好的理由。

而不是一个简单的规则,你应该有100%的线覆盖率,鼓励你的开发人员发现你的测试中的任何缺口,并找到解决这些差距的方法,无论是行数还是行数“覆盖“改善。换句话说,如果你测量覆盖的线条,那么你将改善你的线覆盖 - 但你真正想要的是提高质量。因此,不要忘记线条覆盖率只是质量的粗略近似值。