0%

TDD: 倫敦學派 (London TDD)

最近在讀 Uncle Bob 的書籍:Clean Craftsmanship,其中有解說到倫敦學派 TDD,覺得挺有趣想寫份筆記解說。
其中不只有倫敦學派的 TDD,還有芝加哥學派的 TDD,往後再特別寫一篇文章紀錄之。

倫敦學派 TDD 的核心原則

倫敦學派 TDD(也稱為「模擬派」或「外部-內部開發」)是由倫敦的開發者群體發展而來的 TDD 方法論。其核心原則包括:

  1. 外部-內部(Outside-In)開發:從系統的外部界面開始,逐步向內部實現。首先定義高層次的行為和介面,然後再實做底層細節。

  2. 關注交互而非狀態:倫敦學派更關注 component 之間的交互和協作,而不僅僅是單個 component 的狀態變化(如果和我一樣是後端開發者,可以想像成是關注 層級 之間的協作,而不是單個 方法 的狀態變化)。

  3. 大量使用 Mock:為了隔離被測試者,倫敦學派廣泛使用 Mock 物件來取代真實依賴。這使得測試可以專注於特定單元的行為,而不受其依賴項的影響。

  4. 行為驗證:通過驗證被測試者與其依賴之間的交互行為來確保系統正確性,而不僅僅是驗證最終結果。

  5. 設計優先:倫敦學派強調在實現之前先設計良好的介面和使用方式,測試驅動設計(TDD)同時也是設計的過程。

總結倫敦學派 TDD 的特性

倫敦學派 TDD 的特點如下:

特性 倫敦學派
開發方向 外部-內部(Outside-In)
測試焦點 行為和交互
模擬使用 廣泛使用
設計影響 強調接口設計
測試隔離 高度隔離
適用場景 複雜系統,多依賴

優點

倫敦學派 TDD 具有以下優點:

  1. 高度隔離的單元測試:通過模擬依賴,可以創建真正隔離的單元測試,使測試更加專注和快速。

  2. 介面驅動設計:促使開發者先思考介面跟使用的方式,有助於創建更好的系統設計。

  3. 快速反饋:由於測試是隔離的,執行速度通常很快,提供即時反饋。

  4. 適合複雜系統:對於具有多個層級和複雜依賴關係的系統,倫敦學派提供了更好的測試策略。

  5. 並行開發:一旦介面確定,不同層級可以由不同團隊並行開發,只需遵循已定義好的介面。

缺點或挑戰

倫敦學派 TDD 也面臨一些挑戰:

  1. 模擬可能與實現耦合:過度依賴模擬可能導致測試與實現細節耦合,使得改動一小部分會影響到多個測試。

  2. 測試脆弱性:當介面變化或是實作流程改變時,可能需要更新大量模擬和測試,增加維護成本。

  3. 學習曲線:正確使用模擬和掌握倫敦學派方法需要一定的學習和實踐。

  4. 模擬框架依賴:通常需要依賴模擬框架,增加了項目的依賴複雜性。

實踐建議

要有效實踐倫敦學派 TDD,可以考慮以下建議:

  1. 明智選擇模擬對象:不是所有依賴都需要模擬,對於無狀態的物件的依賴(例如:static class),可以使用真實對象。

  2. 關注 public interface:模擬應該基於 public interface 而非實現細節,這樣可以減少測試與實現的耦合。

  3. 避免過度規範:模擬不應該過度規範被測單元的行為,應該給予實現一定的靈活性。

  4. 共識的重要性:對於需要被公開且共用的 interface,應該共識其行為,待共識一致後再進行測試。

總結

倫敦學派 TDD 提供一個注重流程大於結果的 TDD 方法,是個非常有紀律的一種測試規範。但繼續伴隨而來的是測試的彈性較小,當開發者變動 production code 的流程或是介面即可能造成測試全壞,需要花費大量時間去修改測試。這卻是倫敦學派 TDD 的特點,他們認為用測試的彈性來換取系統的穩定性是值得的,因為他們認為測試的彈性較小可以確保測試的穩定性,進而確保系統的穩定性。

最後我自己看下來的想法: 沒有一定要選擇哪種學派來做 TDD 才是正確的,而是要視開發情境決定使用哪種 TDD 方法才對。