代码改变世界

更好的单元测试准则(转载)

2009-07-26 22:43  Anders Cui  阅读(1786)  评论(0编辑  收藏  举报

文章来自InfoQ。

中文链接:http://www.infoq.com/cn/news/2009/07/Better-Unit-Tests

英文链接:http://www.infoq.com/news/2009/07/Better-Unit-Tests

Jimmy Bogard写了一篇文章:“从你的单元测试中获得价值”,在文章中他给出了三条规则:

  1. “测试名称应该从使用者的角度来描述是什么以及为什么”;核心思想是一名开发者应该能够从测试名称理解测试行为是什么样的。
  2. “测试也是代码,爱他们吧”;仅在产品代码中做重构是不够的。易于理解的测试更易于维护,而且后来的人也更容易弄清楚。 “我憎恨、憎恨长而复杂的测试。如果一个测试的setup方法有30行,请将这些代码放在一个creation方法中。一个长测试会激怒开发者并让其头昏眼花。如果在产品代码中没有长方法,为什么会允许在我们的测试代码中有长方法?”
  3. “不要设定单一fixture的模式/组织风格”;通常情况下是一个类对应一个test fixture,但有时候这样的标准并不适用。

Lior Friedman补充:“规则#0——测试外部行为而不是内部结构。” 或者,测试一个类的期望行为而不是它的目前结构。

Ravichandran Jv补充了他自己的规则:

  1. 尽可能做到每个测试一个断言。
  2. 如果在一个测试中有任何“if else”语句,将语句分支移到单独的测试方法中。
  3. 如果被测试的方法有if else分支,该方法应该被重构。
  4. 测试方法名称应该表明是某种测试。例如,TestMakeReservation与TestMakeNoReservation()是不同的。

NUnit的作者Charlie Poole再次说明:每测试一断言的说法为一个“逻辑断言”,他说:“有时,由于被测试的api缺乏表达能力,你需要写多个断言语句来获得期望的结果。在NUnit框架api的开发中,很多工作就是试图让一个断言做更多的工作。”

Bryan Cook提出了他自己的列表:

  1. 实作:Fixture命名保持一致
  2. 实作:模拟目标代码的命名空间
  3. 实作:Setup/TearDown方法命名保持一致
  4. 考虑:分离测试与产品代码
  5. 实作:按功能给测试命名
  6. 考虑:在期望异常的命名中使用“Cannot”作为前缀

Bryan有超过 一打建议

有很多人推荐Gerard Meszaros的书:“xUnit测试模式:重构测试代码

InfoQ之前与此主题的相关文章:《推荐的TDD教程》,《为可测试性设计》,《来自Google的单元测试技巧》以及《坚持TDD:TDD接受者的问题和解决方案》。

查看英文原文:Guidelines for Better Unit Tests