首页 » Java程序员修炼之道 » Java程序员修炼之道全文在线阅读

《Java程序员修炼之道》第11章 测试驱动开发

关灯直达底部

本章内容

  • 实行测试驱动开发(TDD)的好处
  • TDD的核心:红—绿—重构循环周期
  • JUnit,公认的Java测试框架
  • 四种测试替身:虚设、伪装、存根和模拟
  • 用内存数据库测试DAO代码
  • 用Mockito模拟子系统
  • 使用Scala测试框架ScalaTest

测试驱动开发(TDD)进入软件开发行业已经有相当长的时间了。它的基本前提是在编写真正的功能实现代码之前先写测试代码,然后根据需要重构实现代码。比如要写一段拼接两个String对象("foo""bar")的实现代码,应该先写测试代码(测试结果必须等于"foobar"),以确保你能判断实现是否正确。

很多开发人员都知道JUnit,也会在开发时不定期用到它。但他们一般是写完实现代码之后才编写测试代码,因此体会不到TDD的益处。

尽管TDD的概念看起来非常普及,但实际上很多开发人员并不清楚为什么要采用TDD。对于很多开发人员来说,“为什么要写测试驱动代码以及有什么好处”一直是个问题。

我们认为消除恐惧和不确定性是编写测试驱动代码的重要原因。Kent Beck(JUnit测试框架的发明人之一)在Test-Driven Development: by Example1(Addison-Wesley Professional,2002)一书中对此总结得很好:

  • 恐惧会让你小心试探;
  • 恐惧会让你尽量减少沟通;
  • 恐惧会让你羞于得到反馈;
  • 恐惧会让你脾气暴躁。

1 中文版《测试驱动开发》已由中国电力出版社于2004年出版。——编者注

TDD可以祛除恐惧,让优秀的Java开发者变得更加自信、善于沟通、乐于接受并更加快乐。换句话说,TDD能帮你摆脱下面这种心态:

  • 在开始新工作时,“我不知道从哪里开始,所以只好将就着做一些修改”;
  • 在修改已有代码时,“我不知道现有代码怎么运行,所以我私下认为不能碰它们”。

TDD带来的很多好处并不会马上显现:

  • 更清晰的代码——只写需要的代码;

  • 更好的设计——有些开发人员管TDD叫测试驱动的设计;

  • 更出色的灵活性——TDD鼓励按接口编码;

  • 更快速的反馈——不会直到系统上线才知道bug的存在。

刚入门的开发人员有时认为TDD不是“普通”开发人员用的技术,这是他们采用TDD的一个障碍。他们的感觉是只有那些想象中的“敏捷派”或其他神秘组织的成员才会用TDD。这种认识完全错误,我们会在后面解释。TDD是给所有开发人员使用的技术。

另外,敏捷和软件工艺运动都是为了让开发人员活得更轻松。它们肯定不会拒绝别人使用TDD或其他任何技术。

本章首先解释TDD背后的基本思想红—绿—重构循环,然后介绍Java测试框架中的主力JUnit,并用一个简单的例子来阐明其原则。

敏捷宣言和软件工艺运动

敏捷运动(http://agilemanifesto.org/)已经开展很长时间了,可以说部分改善了软件开发行业。很多伟大的技术,比如TDD,都是这项运动所倡导的。软件工艺是一项新运动,鼓励参与者编写清晰的代码(http://manifesto.softwarecraftsmanship.org/)。

我们喜欢取笑实行敏捷和软件工艺运动的弟兄们。可是,我们自己甚至也拥护它(大多数时候都是如此)。但优秀的Java开发人员,请不要忽视那些对你有用的东西。TDD是一项软件开发技术,仅此而已。

接下来,我们会介绍TDD使用的四大类伪装对象。它们能简化受试代码和第三方类库中代码的隔离,或隔离数据库之类的子系统行为,所以它们很重要。随着依赖项变得越来越复杂,伪装对象也要变得越来越聪明。最终我们会介绍模拟和Mockito类库,它是一个流行的模拟工具,可以让开发人员在不受外部系统影响的环境下进行测试。

开发人员非常熟悉Java测试框架(特别是JUnit),并且一般都有用它们编写测试代码的经验。但对于如何用测试驱动Scala、Clojure等新语言,你可能毫无头绪。因此我们会介绍Scala测试框架ScalaTest,以确保你能在开发Scala代码时应用TDD。

让我们开始了解这个有点奇怪的TDD吧。