在深入了解TDD之前希望讀者對於Clean Code 以及 Clean Architecture先有基礎的概念。
日常中一定發生過以下的情境
我們準備重構(Refactor)自己已經寫好的程式碼,因為Clean老師說你的程式碼中有壞味道(Bad Smell)。為了滿足Clean老師的要求,你把已經完成的程式碼改了又改,最後簡單做幾個功能測試便提交(Commit)了。
過一段時間負責QA的人拿著程式碼跑來告訴你,這個功能壞了。經過沒日沒夜檢查之後發現是上一次重構遺漏掉一個小地方,於是我們再度修改程式碼並簡單做了功能測試之後又提交了。
隨著系統越來越複雜,BUG可以躲藏的地方也越來越多,維護週期也越來越長,最後再也沒有人能維護這個案子了。
系統變得複雜、維護就會變難,
維護越難、開發者就越不敢更動原本的架構
於是乎系統就變得更複雜,這簡直是個死循環
突然一天,客戶要求系統加一個新功能,你看著萬般複雜的程式碼,面有難色地估了下工時。
最後告訴客戶 : 系統太複雜了,要加新功能有困難,不如我們重做一個?
於是團隊決定"導入" DDD,把程式碼放在他應在的地方,該抽介面的地方也抽介面。整個系統看起來可愛了多,至少我們在尋找某段程式碼變容易了。
講到這裡,不知道有沒有人發現,即使我們導入DDD,凌亂的程式碼依然凌亂,我們依然不得不重構這些程式碼。
於是又回到了一開始的情況,開發者不斷在重構->改壞->修復中循環。
當然我們也可以選擇不重構,但終有一天,凌亂的程式碼會影響到架構也變凌亂。於是就有人開始懷疑,為何導入DDD之後系統依然難以維護、DDD沒有用…諸如此類言論。
既然我們無論如何得重構,什麼時候重構?
開發前? 白癡嗎 連Code都沒有要重構什麼
開發中? 你確定你知道重構的定義?
提交後? 迷之聲 : 這個能跑就不要動
顯然重構必須得在開發完做,而且是在提交到生產環境前就要做。
昨天明明還好好的 By Json 2023.??.??
程式沒改就會壞了,有改更會壞,所以需要測試。
以往我們習慣完成A功能之後就簡單對A功能做一下測試,之後又完成B功能就測試B功能,假設A功能跟B功能可能共用X元件,你為了滿足B功能對X元件做了某種程度的擴充或修改。
熟門熟路的人都知道,這種情況都得做回歸測試,於是A功能五個Case加上B功能四個Case總共九個測試。每次修改都得做九次測試,第一、二次開發人員可能還會自己做,測試到第三次之後發現自己的時間越來越不夠用,這類測試就很順其自然的丟給QA人員去做了。
於是過幾天,QA人員又找上門的故事再度重演。
講了這麼多,結論就是要測試,而且要將測試自動化。
以Java為例 : 可以使用Junit工具
下圖的案例只花了15秒的時間便完成了9個Case的測試 (由於大部分時間都花在連線Spanner,一般專案花的時間會更短)
當測試只需要花15秒,測試就可以天天做,或是Ctrl+S存檔之後順手跑一個測試,QA人員也可以騰出手來去做更高階的測試,因為有測試保護,開發人員也可以更放心的重構程式碼…反正重構完之後跑個測試也不過區區15秒。
提到測試就不得不提到測試金字塔,越底層的含義是被執行的次數越多次,換言之,假使我們今天說要測試,最優先被執行的應該是單元測試,次優先則是整合測試或是功能測試,最後才是E2E的端對端測試。
前面講了這麼多廢話,終於輪到TDD登場了,顧名思義TDD開發模式是一種以測試為主體的開發模式,標榜好測就會好用。
TDD遵循著以下的流程進行開發 :
此外,測試通過的情形被稱為綠燈,沒有通過則是紅燈。
Spring Boot有內建的測試用框架,常用到的功能有 :
還有很多功能不一一贅述,有興趣的人可以自己去找文章看。
假設今天要開發一個登入功能,UseCase如下
看起來有點凌亂,等等我們會找機會再來重構這段測試
此時處於紅燈的狀態,可以開始撰寫程式碼。
如果這裡有人是綠燈…代表測試有問題
簡單編寫一下登入的業務邏輯
綠燈就Commit,然後開始重構。
把一些重覆的程式碼抽出來做成一個Method,然後取個容易懂的名字。
一樣,綠燈就Commit。
然後換重構程式碼 :
綠燈就Commit。
如此一來就完成了一個TDD的Cycle了,感謝各位的閱讀。