【單元測試的藝術】Chap 11: 設計與可測試性


目錄

  • PART I: 入門
    • Chap 1: 單元測試基礎
    • Chap 2: 第一個單元測試
  • PART II: 核心技術
    • Chap 3: 透過虛設常式解決依賴問題
    • Chap 4: 使用模擬物件驗證互動
    • Chap 5: 隔離(模擬)框架
    • Chap 6: 深入了解隔離框架
  • PART III: 測試程式碼
    • Chap 7: 測試階層和組織
    • Chap 8: 好的單元測試的支柱
    • Chap 9: 在組織中導入單元測試
    • Chap 10: 遺留程式碼
    • Chap 11: 設計與可測試性

一、為什麼在設計的時候要關心可測試性

你可能現在正想著:「廢話!」不過真正的原因好像又不是那麼明確,因為此時你的目的似乎是要完成一些功能,而不是取悅似有似無、似是而非的「測試」,但其實你可以將「測試當成另一種使用者」。

在可測試性的設計中,單元測試具有以下特色:

  • 執行速度快
  • 相互隔離
  • 不需要額外進行外部設定
  • 穩定可靠的結果

如果撰寫這樣的測試很困難,或是需要很長的時間,那麼這個系統就不是一個可測試的系統。


二、可測試系統的目標

Uncle Bob 總結了可測試(OOD)的目標:SOLID

  • Single responsibility principle(單一職責原則):指一個類模組包甚至系統都應該有單一的原則。
  • Open-closed principle(開閉原則):你應該能夠擴充套件類的行為,而不需要修改它。
  • Liskov substitution principle(里氏替換原則):簡答理解就是如果想要可替換的元件來構建軟體系統,那麼這些元件就必須遵守共同一個約定,以便讓這些元件可以相互替換。
  • Interface segregation principle(介面隔離原則):使細粒度介面特定於客戶端,主要告誡設計師應該在設計中避免不必要的依賴。
  • Dependency Inversion Principle(依賴倒置原則):依賴抽象,而非具體實現。此原則指出高層策略性程式碼不應該依賴實現的程式碼,相反,那些底層實現應該依賴於高層策略程式碼。

測試設計指南:

  1. 預設情況下將方法設定為虛擬方法
  2. 使用介面導向設計
  3. 預設情況,將類別設計成可繼承
  4. 避免在包含邏輯的方法內直接初始化類別執行個體使用,而是使用輔助方法、工廠模式、控制反轉容器
  5. 避免直接呼叫靜態方法
  6. 避免在建構式和靜態建構式中包含邏輯程式碼
  7. 把單例和單例的擁有者分開

三、可測試性設計的缺點

  1. 工作量:大多情況,會增加工作量,以 Bob 大叔為例,他會先使用簡單的設計,完成簡單的功能,然後只有在需要的時候進行重構。
  2. 複雜度:可測試性有時讓人覺得把事情複雜化了,有些介面讓人覺得彆扭,或抽象後的實作讓人覺得困難。
  3. 洩漏敏感的智慧財產權:可測試性會將一些方法強制公開,這種情況下,要嘛作出妥協,要嘛換工作。
  4. 有時無法進行:有時因應政策限制或其他原因,你不得不使用某種設計,因環境不允許,可測試性需要作出讓步。

小結

這一章,介紹了可測試性設計的概念。事實上,在現實世界中,可測試性設計的討論沒有簡單的答案。可測試性設計與 SOLID 設計原則息息相關,但是具備可測試性的設計不見得就是好設計。

也許,我們不該將可測試性設計當成最終目標,而是追求好的設計即可。

單元測試的藝術,到這兒就告個段落了,怎麼有種嘎然而止的感覺!
外面的世界還很精彩,攜著這些珍貴的知識,一起打天下吧!


番外篇:

其他推薦書籍

  • Steve Freeman, Nat Pryce 的《Growing Object-Oriented Software, Guided by Tests》:設計方面的輔助內容
  • Gerard Meszaros 的《xUnit Test Pattern: Refactoring Test》:單元測試模式和反模式
  • Michael Feathers 的《Working Effectiverly with Legacy Code》:解決遺留程式碼
#Unit Test #單元測試的藝術







你可能感興趣的文章

Javascript 非同步

Javascript 非同步

Fibonacci sequence

Fibonacci sequence

物件導向的基礎範例

物件導向的基礎範例






留言討論