程式設計師升級必練內功:TDD Kata
測試驅動開發(Test-Driven Development,簡稱 TDD)是一種程式開發的技巧,簡單來說就是先寫測試程式,然後才實作功能。具體的流程則是透過 Red–Green–Refactor cycle 的循環:
- Red – 先寫測試程式,此時因為還沒有實作功能,所以這個測試是會失敗
- Green – 快速實作出功能,讓上述的測試通過
- Refactor – 重構程式碼,去除多餘重複的代碼,提高程式碼品質,同時維持測試通過
對於開發軟體需要撰寫自動化測試,已經廣泛獲得專業軟體開發者的認同。軟體產品想要走的長遠,就必須為其撰寫自動化的測試程序來確保軟體品質。但是對於是否全然實行 TDD 的爭議則層出不窮,特別是對於 TDD 被當作一種教條的反感。
但無論是否百分之百實行 TDD,筆者都認為學習 TDD 會是一個專業軟體開發者升級的必經過程。透過練習 TDD,軟體開發者可以學習到如何撰寫好的自動化測試,怎樣設計軟體可以更模組化、更容易擴充,以及設計出好用的 API 介面。
那要如何上手學習 TDD 呢?光看理論是不行的,唯一的辦法就是動手做來獲得經驗。要直接利用公司專案練習 TDD 可能會比較困難,一來在不熟悉的情況下會大大拖慢開發速度,二來在有 GUI 和 Multilayered 軟體架構的環境中,導入 TDD 會一次面對太多問題和挑戰。
利用 Code Kata 學習 TDD
因此學習 TDD 最好的方式(沒有之一),筆者認為就是 Code Kata 形式了。「Kata」是日本字「形」的意思,中文的意思是「套路」。而 Code Kata 就是透過一些小型的程式題目進行重複鍛鍊,就像學功夫套拳。不需要 GUI 或複雜的軟體框架,只需要程式語言本身和一個單元測試函式庫,透過全然遵守 TDD 的規範來練習這些題目,內化及提升程式設計能力。
搜尋 Code Kata (或 Coding Dojo: 用 Kata 一起練功的 coding 活動)可以在網路上找到很多 Kata 題目。這裡茲舉一例:Potter Kata:
有一家書店在賣哈利波特書籍系列,每一本書定價 $100 元。買兩本不同的書可以打5% 的折扣、買三本不同的書可以打 10% 的折扣、買四本不同的書可以打 20%。如果買到五本可以打到 25% 的折扣。請寫出一個函式可以計算價格。
我們練習寫下第一個測試案例,一開始這個測試案例應該是失敗的,因為還沒有開始實作這個函式:
- 第一集買 1 本
- 總價應為 100 元
然後我們就可以開始實作這個函式通過這個測試案例。根據 TDD 規則,你只需要通過這個測試案例即可,不多也不少。例如這個實作只要將數量乘上100元就可以通過了。
接著,我們可以寫第二個測試案例,一開始這個測試案例也是不通過的:
- 第一集買 1 本、第二集買 1 本
- 總價應為 190 元
接著撰寫實作通過以上兩個測試案例。接著繼續撰寫下一個測試案例,事情開始變得有趣:
- 第一集買 1 本、第二集買 2 本
- 總價應為 290 元 (要不同集數才有折扣,所以第二集第二本沒有折扣)
重複這個 Baby Steps 循環過程,直到完成為止。注意,過程中你必須完全遵守 TDD 規則:
- 一定是先寫一個不通過的單元測試,才開始實作功能
- 每次只新加一個單元測試,只需要剛剛好不通過即可,不要一次加多個測試情境
- 每次實作功能時,只需要剛剛好通過測試即可,不多也不少
聽起來很簡單吧,但是在這個過程中,你將不知不覺面對以下的問題:
- 測試案例要怎麼寫?如何建構測試資料? 要舉多少例子才算完成可以涵蓋規格和所有 edge case?
- 每一次的開發循環,程式都會變得越來越複雜,是不是要停下來重構一下? 讓程式可以更簡潔容易擴充
- 如何確保每個測試案例都有效益? 不會發生砍掉實作卻沒有造成任何測試失敗
- 如何安全地重構不會改壞之前寫好的程式?
- 測試案例會越加越多 edge case,那麼實作要如何因應來越改越通用呢?
- API 要如何設計,才會好測試和呼叫?
- Test code 的品質、可讀性和擴充性也和 production code 也相等重要嗎? 這些問題都會在練習的過程中逐步學習和思考,讓你升級成為更好的程式設計師。