讀古今文學網 > Java程序員修煉之道 > 第11章 測試驅動開發 >

第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吧。