作為敏捷宣言的共同作者,我們熟知的鮑勃大叔Bob Martin,在最近發表的一篇文章中對TDD是否會損害架構進行了評估。文中大部分討論圍繞著遵循測試驅動方法對高層設計和實現代碼的總體可維護性是否會產生消極影響。Martin認為,雖然TDD是重要的守則,但良好的設計來源于解耦、分離和隔離等原則。
Ruby on Rails的作者David Heinemeier Hansson曾發表過一篇有關測試破壞了設計的文章。Martin對此觀點作了進一步探索。這篇文章基本上是對以下兩種設計進行比較,其一是Hansson所倡導的設計,另一個則是Ruby的貢獻者和布道者Jim Weirich所倡導的更易于測試的設計。Martin鼓勵讀者選擇更適合自己的設計,并寫道:
爭論的焦點在于隔離性和間接性。 DHH的優秀設計理念最小化了上述兩點,而Weirichdd 設計則將這兩點最大化。Martin還撰寫了一篇測試脆弱性的問題。文章中提到對實現代碼的細微改動都可能會對數以百計的相關測試用例造成影響,從而不得不把它們全部更新。
Martin在闡釋他的觀點時首先指出,不論是否遵循了TDD,測試代碼都需要像產品代碼那樣精心設計:
應用在測試上的設計原則應當和普通代碼一樣多。測試是系統的一部分,必須和系統中的其他部分那樣維持相同的標準。Martin還解釋道,對TDD的一個常見誤區就是測試和實現是一一對應的。這可能意味著一個實現類對應一個測試類,一個實現方法對應一個測試方法。這種做法的不足之處主要在于,它將測試和實現緊緊綁在了一起,導致很難進行重構和梳理。
Martin認為高層架構和設計不會從TDD中浮現:
坦白講,系統的高層設計和架構會從TDD中浮現這一說法聽起來很荒謬。在動手編碼之前,你就應當對軟件項目具備一定的架構視野。而這是TDD無法帶給你的。另一方面,Martin認為那些實現代碼級別的低層設計確實來源于TDD的實踐過程。換句話說,在測試代碼保持不變的同時,實現代碼可以進行重構和結構化,使得代碼更具有可維護性。Martin認為這會導致事物向兩個方向發展:“一方面測試變得越來越具體,另一方面產品代碼則越來越通用。”
除了這些差別之外,Martin堅信TDD是一條守則。不管是否實踐TDD,開發者本身才能決定良好的設計:
TDD不會導致壞的設計,也不會導致好的設計。開發者才是設計好壞的決定因素。TDD只是一條守則,是組織工作的方法,是確保測試覆蓋率的途徑,是在應對特殊性的同時確保適當通用性的手段。Martin的觀點總結起來就是,TDD產出的設計事實上就是開發者的設計。TDD的主要優勢在于測試覆蓋率和應用程序的可靠性。真正良好的設計來源于解耦、分離和隔離等原則。
查看英文原文:Does TDD Harm Architecture?