很多書上和網路的文章都提到了很 TDD 的做法,不過老實說我並沒有實際參與這些大師的 TDD 過程,其實很難把他們的方法百分之分地應用到自己的專案裡。

因此,凡事還是要自己動手做過才會明白,所以我就趁著在開發新的 Library 時,真正地去落實測試與重構。

以下就是我大致的心得,供大家參考。

我的測試驅動開發流程

第一步:準備好工具

之前提過的 NetBeans 所提供的 PHPUnit 整合,就是個很不錯的自動化測試工具。

在寫類別時,按下 Ctrl + F6 就會自動執行這個類別的測試 (當然前提是要已經先建立好測試類別) ;而如果是在撰寫測試類別時,可以按下 Shift + F6 ,這樣 NetBeans 就會自動執行測試類別了。這兩個快速鍵如果記住的話,會有助於我們加快做測試的動作。

第二步:草圖階段

和設計階段的 UML 圖不一樣,這個階段算是撰寫程式碼了,所以要先想好你的程式要怎麼動,然後用畫個簡單的流程圖將它記下來。然後在圖塊上標明你會用到什麼資料,越詳細越好。

而流程圖不一定要是圖,也可以是步驟的表列,總之能表現出程式的意圖即可。至於畫在哪裡都可以,像我就習慣使用最單純的紙和筆。而草圖也不需要畫得多好看,除非你想向正妹展示你的繪圖天份。

第三步:撰寫測試

在草圖畫好後,就可以用測試去呈現它。測試的寫法先不用寫得太好,把概念呈現出來就可以了。這個動作主要的目的是讓我們對要測試的類別有個大致的輪廓,讓寫出來的程式碼不致於發散到我們無法掌控的地步。

第四步:撰寫程式

寫好第一個測試後,就可以開始寫程式去符合測試了。在這個過程中,最好能找個人一起討論,也就是所謂的 Pair Programming 。找正妹一起 Pair Programming 是會增加興奮度,但不會讓你的程式寫得更好。

另外,程式碼以快速產出為主,除了遵守 Coding Style 外,邏輯上並不用寫得多漂亮;因為如果有正妹在旁邊一起寫程式時,你的腦袋一定不會百分之百運轉,所以等等再重構就好。

第五步:停下思考

當程式碼在可以符合測試後,就停下來想想這樣的設計是不是符合原先的想法。

不符合的話,就再重來,因為我們只前進了一小步,所以不必擔心花太多時間,畢竟找出不良的設計也是一種進展。符合的話,就再往下走;也就是撰寫下一個測試,然後再撰寫程式符合它。

第六步:重構

完成一小階段後,就馬上回頭重構我們的程式碼,這時有測試當靠山,就不用怕出問題。

而當程式碼重構完後,看就再回頭看看測試碼,如果有需要的話就重構它;因為測試本身也是程式,一定也會有壞味道。例如我們可以用 PHPUnit 的 @dataProvider 機制,去重構要驗證不同資料集但流程卻重複的測試;或是用 Template Method 去重構大部份流程相同,只有少部份流程有差異的測試。

而重構測試碼的時候,我們的程式碼就可以做為測試的測試,用來驗證重構後的測試。

完成這個步驟後,就可以繼續進行下一個小階段了。

心得

真正將 TDD 落實到平常的開發後,我發現這樣的方式會幫助我的思考清晰,考試都一百分 (因為我沒正妹在旁邊一起 Pair Programming …) 。而且另一個好處就是不論是一開始的撰寫或是事後的重構,我都可以精簡我的程式碼。

不過我並無法保證 TDD 一定適合你,因為每個人的開發習慣不一定相同,不過還是推薦大家試試吧。