自从我们在之前的文章中开始做单元测试,我觉得我们可以继续做这个主题,并且展示一些写得好的、可维护的单元测试的规则。这个选择很随意,而且绝不是完整的,但是我希望它能够对你有所帮助。那我们开始吧!
  1、使它们简短
  因为我们正在测试一个单独功能的一部分,通过一个单独代码单元交付,一个测试需要合理的简短是有意义的。如何简短?取决于多种因素,但是通常不会超过几行代码。
  2、不要重复自己
  好的代码实践应用于测试代码,像它们应用于生产代码一样。在我的经验里,单元测试中容易违反的规则之一是DRY(http://wiki.c2.com/?DontRepeatYourself)。一些人甚至宣称单元测试完全不需要分享任何代码。这完全是废话。当然,你希望尽可能保证你的测试可读,但是复制粘贴并不是解决问题的办法。
  3、组合好过继承
  一旦你承认之前的两点,你也许会禁不住给你的测试创建一些base class,它将包含常用的代码。如果你这么做了,现在停下!这样一个base class工作像是一个磁铁,可以用于各种不相关的共享代码,并且快速成长,直到它接管你的项目,你的公司,甚至你的狗。保护好你的狗,使用组合方法。
  4、快
  单元测试是一些你可能几乎一直运行的东西。由于这个原因,确保移除外部相关项和一些让你测试变慢的其他东西。这些东西通常像是数据库,外部系统或文件操作。同时别做过头——测试单元的完整隔离也不是一个好的解决方案。
  5、的确定
  每次我听到有些人已经完成95%的工作测试套件,足够好可以去生产了,我既想笑又想哭。为了老天(或你的狗),单元测试应该的完成。只有通过的测试,才意味着所有都ok了(有了这些单元,你还需要其他类型的测试)。如果你的单元测试看上去单薄,确保发现根本原因并且尽快修复它。
  6、不要忽视测试
  上面的第四第五点,特别重要的是,在测试中添加忽略注释并不是修复测试套件的方法(https://dzone.com/articles/open-letter-from-an-ignored-test)。这是一种让你的测试套件更加不可靠的方法,因为现在它没有从回归错误等等其他错误中保护你了。
  7、测试你的测试
  是的,你没看错,而且我也没疯。我不是说给你的测试写测试。我是说像是变异测试,测试驱动开发,或者在你的代码库中频繁的“改变随机内容”的实践来看看是否有测试失败。我也常常做一些训练,试着对代码做出一些潜在改变,而我的测试不会发现这些改变。
  8、给测试取个好名字
  ThrowException不是一个好的测试名字。尽管我不确信每个项目都应该为测试用一些花哨的命名惯例,但我完全确信你能够通过阅读失败测试用例的名字来判断代码的哪一部分被破坏了。
  9、每个测试都有个逻辑断言
  为了实现能够通过阅读失败测试的名字来判断哪错了的美好目标,需要的不仅仅是好名字,还需要更多的东西。一个测试检查的许多东西也必须是限定的。因此,一个好的单元测试应该只包含一个逻辑断言,即只检查测试方法的一个输出/副作用。
  10、设计测试
  这是一个meta-tip,在这篇文章中贯穿所有其他技巧,而且那些我在这里没有提到的技巧。对待你的测试代码要像你对待你的生产代码那样同样关心。考虑好的设计原则和指标,像是在测试代码和生产代码之间低耦合与代码异味,诸如重复、无用代码等等。记住,一个好的测试套件通过在变更和重构代码时让你感到安全,可以让你的生活更加容易,然而一个坏的测试套件让你悲惨,浪费大量时间和让你的代码几乎无法变更。