单元测试指南
有谁知道在哪里可以找到单元测试指南和建议?我想要一些可以解决以下类型的主题的东西(例如):
- 测试应该和应用程序逻辑在同一个项目中吗?
- 我应该具有反映逻辑类的测试类,还是应该拥有我需要的数量的测试类?
- 我应该如何命名测试类,方法和项目(如果它们属于不同的项目)
- 应该测试私有方法,受保护方法和内部方法,还是仅测试公开可用的方法?
- 单元测试和集成测试应该分开吗?
- 是否有充分的理由不具有100%的测试覆盖率?
我不是在问我应该做什么?
在线资源将是最好的。
解决方案
我坚持建议我们阅读"测试驱动开发:示例"和"测试驱动开发:实用指南"。对于单个主题,问题太多了
我会推荐肯特·贝克(Kent Beck)关于TDD的书。
另外,我们需要转到Martin Fowler的网站。他也有很多关于测试的好信息。
我们在TDD方面相当重要,因此我将就此回答问题。
Should tests be in the same project as application logic?
通常,我们将测试保持在相同的解决方案中,但是我们将测试分为单独的DLL /项目,这些DLL /项目反映了它们正在测试的DLL /项目,但是维护了名称空间,而测试位于子名称空间中。示例:Common / Common.Tests
Should I have test classes to mirror my logic classes or should I have only as many test classes as I feel I need to have?
是的,应该在创建任何类之前创建测试,并且根据定义,我们应该仅单独测试一个单元。因此,解决方案中的每个类都应该有一个测试类。
How should I name my test classes, methods, and projects (if they go in different projects)
我想强调一下行为是要测试的东西,因此我通常以SUT命名测试类。例如,如果我有一个User类,我将这样命名测试类:
public class UserBehavior
应命名方法以描述我们期望的行为。
public void ShouldBeAbleToSetUserFirstName()
可以根据需要命名项目,但是通常我们希望它很明显地表明它正在测试哪个项目。请参阅有关项目组织的先前答案。
Should private, protected, and internal methods be tested, or just those that are publicly accessible?
同样,我们希望测试断言预期的行为,就像我们是被测试对象的第三方使用者一样。如果我们测试内部实施细节,那么测试将很脆弱。我们希望测试为我们提供重构的自由,而不必担心破坏现有功能。如果测试了解实施细节,那么如果这些细节发生变化,则必须更改测试。
Should unit and integration tests be separated?
是的,单元测试需要与验收和集成测试隔离开来。关注点分离也适用于测试。
Is there a good reason not to have 100% test coverage?
我不会挂断100%代码覆盖率的事情。 100%的代码覆盖率往往意味着测试中的质量达到一定水平,但这是一个神话。我们可能会进行可怕的测试,但仍然获得100%的覆盖率。相反,我将依靠良好的测试优先心态。如果我们总是在编写代码行之前编写测试,那么我们将确保100%的覆盖率,这将成为一个争论点。
通常,如果我们专注于描述类的整个行为范围,则无需担心。如果我们将代码覆盖率作为度量标准,那么懒惰的程序员将只是做足以满足该要求的事情,而我们仍然会有糟糕的测试。取而代之的是在很大程度上依赖于同行评审,在同行评审中还要对测试进行审查。
这是一个好问题。我们有机地发展了自己,我怀疑最好的方法就是这样。那里有些"取决于..."。
我们在同一项目的子命名空间" UnitTes"中发布了测试
我们的测试类反映了逻辑类,以便简化跟踪测试相对于测试对象的位置
类的名称与它们正在测试的逻辑类相似,方法的名称与它们正在测试的场景相同。
我们仅针对公共方法和内部方法编写测试(测试在同一项目中),目标是覆盖全班级的95%。
我宁愿不区分"单位"和"整合"。将花费大量时间来试图找出哪个是那个。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。测试就是测试。
100%一直都很难实现。我们的目标是95%。获得最终的5%所需的时间以及实际获得的收益也将减少。
那就是我们,适合环境和步调的东西。里程可能会有所不同。考虑一下生存环境和所涉及的人物。
我期待看到其他人对此有何评论!
为了:
- 不,通常最好将它们包含在一个单独的项目中。除非我们希望能够在运行时运行诊断。
- 理想的情况是100%的代码覆盖率,这意味着每个类的每个例程中的每一行代码。
- 我去了ClassnameTest,ClassnameTest.MethodNameTestnumber
- 一切。
- 我会说是的,因为如果单元测试失败,则不需要运行集成测试。
- 只需设置并获取字段的简单属性就不需要进行测试。
关于最后一个问题,根据我的经验,不坚持100%测试覆盖率的"良好"理由是,要花费最后几个百分点需要花费不成比例的精力,尤其是在较大的代码库中。因此,一旦到达收益递减点,就需要决定是否值得我们花时间。
Josh的回答仅在澄清一点上是正确的:
我将单元测试与集成测试和验收测试分开的原因是速度。我使用TDD。我需要有关我刚刚创建/修改的代码行的即时反馈。如果我正在运行完整的集成和/或者验收测试套件,而这些测试会冲击真实的磁盘,真实的网络以及非常缓慢且不可预测的外部系统,那么我就无法理解。
不要越过横梁。如果我们这样做,将会发生坏事。
测试应该和应用程序逻辑在同一个项目中吗?
这取决于。都有权衡取舍。
将其保存在一个项目中需要额外的带宽来分配项目,额外的构建时间并增加安装空间,并且更容易犯下依赖于测试代码的生产逻辑的错误。
另一方面,保持单独的项目会使编写涉及私有方法/类的测试变得更加困难(取决于编程语言),并且会带来一些管理上的麻烦,例如建立新的开发环境(例如,当新的开发人员加入开发环境时)。项目)。
这些不同成本的影响程度因项目而异,因此没有统一的答案。
我应该具有反映逻辑类的测试类,还是应该拥有我需要的数量的测试类?
不。
我们应该具有允许良好构造测试代码的测试类(例如,最少的重复,明确的意图等)。
直接在测试类中镜像逻辑类的明显优势是,它使查找与特定代码段相对应的测试变得容易。还有其他方法可以解决此问题,而不会限制测试代码的灵活性。测试模块和类的简单命名约定通常就足够了。
我应该如何命名测试类,方法和项目(如果它们属于不同的项目)
我们应该命名它们,以便:
- 每个测试类别和测试方法都有明确的目的,并且
- 这样,寻找特定测试(或者有关特定单元的测试)的人就可以轻松找到它。
应该测试私有方法,受保护方法和内部方法,还是仅测试公开可用的方法?
通常,应该测试非公开方法。这取决于我们是否仅通过测试公共接口就获得了足够的信心,还是我们真正想测试的单元不能公开访问。
单元测试和集成测试应该分开吗?
这取决于我们选择的测试框架。进行最适合测试框架的工作,并做到:
- 与一段代码相关的单元测试和集成测试都很容易找到,
- 仅进行单元测试就很容易,
- 仅运行集成测试很容易,
- 运行所有测试很容易。
是否有充分的理由不具有100%的测试覆盖率?
是的,有充分的理由。严格说来,100%的测试覆盖率意味着对代码中的每种可能情况都进行了测试。对于几乎所有项目而言,这都是不切实际的。
如果我们只是采用100%的测试覆盖率来表示测试套件在某一时刻使用了每一行源代码,那么这是一个很好的目标,但是有时在尴尬的地方只有几行很难到达进行自动化测试。如果定期手动验证该功能的成本少于达到最后五行的扭曲成本,那么这就是没有100%线路覆盖率的一个很好的理由。
而不是一个简单的规则,即我们应该拥有100%的行覆盖率,而是鼓励开发人员发现测试中的任何差距,并找到解决这些差距的方法,无论覆盖的行数是否有所改善。换句话说,如果我们测量覆盖的线,则可以提高线的覆盖率,但是实际需要的是质量的提高。因此,请不要忘记,线覆盖率只是质量的非常粗略的近似值。