本文匯總了一個大學教授放棄使用測試驅動開發(TDD)的經過以及鮑勃大叔對其論點的反駁。
Ian Sommerville是一名退休的大學軟件工程教授,他已經寫了好幾本書,包括《軟件工程(第10版)》。該書第8章專門介紹了軟件測試,其中8.2小節特別介紹了TDD。他在個別章節中多次重申了其中的部分觀點。在最近的一篇博文中,Sommerville寫道,“TDD是軟件工程的一次重要進步。顯然,TDD適合某些類型的系統”,他列出了下面這些“TDD友好”的系統:
分層架構;
成功標準一致的系統,測試圍繞這些標準構建;
操作環境可控,不必同超出控制的系統交互。
Sommerville補充說,對于這樣的系統,TDD很有效,但他發現TDD很難用于其他類型的系統:
我在一類符合這些標準的系統上開始使用TDD,我喜歡它。對我而言,它很有效。后來,我轉到了一個涉及可視化復雜鏈接結構的系統?,F在,關于可視化,(a)往往很難有一個明顯分隔的層——UI就是程序,(b)很難預定義成功標準——基本上必須通過試驗看看什么有效什么無效來編程。TDD就不合用了。
Sommerville還寫了一篇博文“放棄測試優先的開發”,分享了他最近在一個私人項目中使用TDD的經歷。他發現,TDD在開始時很有幫助,但后來,當開始GUI研發的時候,他發現編寫測試越來越難,而且他認為編寫測試花費的時間不值得。因此,他有時候會在編寫測試之前編寫實現代碼,并在稍后增加一些測試。最終,他放棄了TDD,他的解釋是:
我放棄TDD,不是因為編寫GUI自動化測試時(眾所周知的)的困難。我放棄是因為我認為TDD鼓勵保守編程,它會促使你制定可以測試的設計決策,而不是對程序用戶而言正確的決策,它讓你關注細節而不是結構,而且,對于一大類程序問題——那些由異常數據導致的問題——它不是很有效。
Sommerville繼續說明了一些細節:
TDD鼓勵保守:人們不愿意對應用程序做重大修改,因為他們知道許多測試會被破壞,他們必須重寫。
“有時候,最好的設計是最難測試的那一種”。
TDD將注意力放在了細節上而不是整體。“使用TDD,你會陷入到程序不同部分的細節中去,很少回過頭來看看全局。”
很難為異常數據編寫測試。
因此,他決定首先編寫代碼,然后再測試。但是,有人注意到了他的博文。Robert C. Martin(又名鮑勃大叔)對Sommerville放棄使用TDD的觀點提出了反對意見。鮑勃大叔認為,Sommerville遇到的是初學者的麻煩,他放棄得太快了。修改系統的一個組件又會破壞另一個組件,這是因為系統的兩個部分是緊緊耦合在一起的。當一個人因為害怕破壞所有的測試而不敢重構代碼,那就意味著測試同生產代碼綁定的太緊。我們應該將系統組織成獨立的層,每個層應該通過接口提供訪問,測試也會使用這些接口。
鮑勃大叔反駁了“最好的設計是最難測試的那一種”的觀點,認為那是胡說。一個無法測試的設計很可能在需要它的時候不能發揮作用。在困難的情況下,比如測試GUI或設備驅動,他提到使用The Humble Dialog Box模式這個選項。
鮑勃大叔不同意TDD太過關注細節的觀點。他認為,一名開發人員應該總是設計:
不管編寫什么;單元測試,或者驗收測試,或者生產代碼,或者“模擬(mock)”,或者“樁(stub)”,都必須設計……
我們是程序員!我們設計!我們創建高內聚低耦合的結構。我們管理依賴。我們隔離模塊。我們,設計。
鮑勃大叔繼續寫到,程序員有時會忘記設計。尤其是某個領域的新手往往關注特定底層的細節,因為他們在學習過程中。他強調了心中有全局的重要性,讓我們想起了Ron Jeffries(XP合著者及敏捷宣言簽署者)的建議:“全局思維,局部行動。”
最后,鮑勃大叔也同意,很難考慮異常情況,但那不是TDD的錯:
阿波羅1號導致了火災。阿波羅13號在去往月球的途中爆炸了。挑戰者號剛發射就爆炸了。哥倫比亞號返回過程中解體。為什么?因為盡管成千上萬的大腦試圖考慮到一切情況,但還是有一些未能預見到的情況出現了……
面對現實吧??倳酗L險。不要責怪TDD,也不要放棄。
Israel Fermin Montilla是一名軟件工程師,他的立場比較溫和,他對Sommerville的博文作了這樣的評論:
原文轉自:http://www.infoq.com/cn/news/2016/03/tdd