TDD的三條軍規

來源:互聯網
上載者:User
這些年來,我喜歡用下面這三條簡單的規則來描述測試驅動開發:
  1. 除非這能讓失敗的單元測試通過,否則不允許去編寫任何的產品代碼。
  2. 只允許編寫剛好能夠導致失敗的單元測試。 (編譯失敗也屬於一種失敗)
  3. 只允許編寫剛好能夠導致一個失敗的單元測試通過的產品代碼。

對於任何功能,一定要從編寫它的單元測試開始;但是到了原則2,你就不能再為那個單元測試寫更多內容。只要一出現該單元測試代碼編譯失敗,或是宣告失敗,你就必須停下來開始編寫產品代碼;但是到了原則3,你就只能編寫產品代碼,直到讓測試編譯成功或通過斷言為準。

仔細想想,就會發現如果不是去讓一些東西編譯或是執行,你就根本沒辦法去寫代碼。確實,這也正是關鍵所在。我們所做的任何事情(無論是寫測試,寫產品代碼,或是重構),都要保持系統能夠一直運行。跑通測試的時間間隔應該是以秒或是分鐘級的,即使那隻有10分鐘,也都太長了。

想瞭解實際的操作過程,可以看看“保齡球遊戲中的Kata”(譯註2)一文。

現今有很多程式員,每當他們頭一次聽到這種技術的時候,會想:“這種做法太愚蠢了!”“這會讓我慢下來,這是時間和精力的浪費,讓我無法思考,無法設計,還會打亂我的思路。”然而,試想,當你走進一個房間,裡面都是用這種方式工作的人們,會發生什麼情況?你隨便選個時間,隨意找個人,一分鐘以前,他們所有的代碼都跑通過。

讓我再重複一遍:一分鐘以前每個人的代碼都能跑通!不管你找誰,也不管你何時去找,一分鐘以前他們所有的代碼都跑通了!

如果你所有的代碼自始至終都能跑通,那麼你會多長時間用一次調試器?答案是,不會太經常。只要敲幾下^Z就能很容易的恢複這些代碼到跑通時的狀態,然後再試著把前幾分鐘的代碼寫一遍即可。而如果你不經常調試,那麼會省去多少時間呢?而現在你花在調試上的時間又有多少呢?一旦你有調試過,你又要花上多少時間來修複這些bug呢?如果你能夠大大減少這些時間的話,又會如何呢?

好處還不只這些。如果你採用這種方法,那麼每小時你都會產生好幾個測試;每天就有十幾個;每個月就幾百個;一年下來,你所編寫的測試就會有數千個。你可以保留著這些測試而且在任何你希望的時候去運行它們!什麼時候運行它們呢?隨時!只要你做了改動,就去運行它們!

有些代碼已經混亂不堪了,可是我們為何不去清理它們呢?我們擔心會破壞它們。但如果我們擁有測試,我們就有理由確信這些代碼不會被破壞,或是說我們可以很快的就找到被破壞的地方。如果我們有了這些測試,我們就對代碼發生改變無所忌憚。如果我們看到混亂的代碼,或是一個不清晰的結構,可以毫無顧慮地清理它。因為有了測試,代碼重新變得易修改了;因為有了測試,軟體重新變“軟”了。

好處還不只這些。如果你想要知道如何去調用一個特定的API,就會有一個測試能夠告訴你;如果你想要知道如何建立一個特定的對象,就會有個測試能告訴你。你想知道的任何有關這個系統的,都有一個測試能夠去示意。這些測試就像是小型的設計文檔,小型的程式碼範例,描述了系統的工作和使用方式。

你是否曾經整合過一個第三方庫到你的項目中呢?你拿到一本厚厚的精緻的協助文檔,在結尾處,有一遝薄薄的樣本附錄。你會選擇哪個去閱讀呢?當然是樣本了!那就是單元測試啊!它們是這份文檔中最有用的部分;它們是如何使用代碼的鮮活的例子;它們是極其詳細、完全沒有歧義的設計文檔,相當的正規甚至可以執行,而且不會與產品代碼相脫離。

好處還不只這些。如果你曾有過增加單元測試到一個可以工作的系統中的經曆,你會發現那一點兒都不好玩。你很可能會發現想跑通測試,你一定是要麼去改變系統中的部分設計,要麼就在測試上作假。這是因為你試圖去測試的系統並不是基於可測試設計的。例如,你想要測試某個函數f。然而,f調用了另外一個從資料庫中刪除記錄的函數。在你的測試中,你不希望這條記錄被刪掉,但卻沒有辦法來阻止它。這樣的系統就不是基於可測試設計的系統。

當你遵循TDD的三條規則的時候,你的所有代碼天生就可測試!而且另一個能形容“可測試”的詞彙就是“可解耦”。為了單獨的測試一個模組,你就必須把它解耦。所以TDD強制你去解耦這些模組。確實,如果你遵循這三條規則的話,你會發現你可能比起從前來能做出更多的解藕。這就強制了你去創造更好的,低耦合的設計。

收穫了所有的這些好處,這些愚蠢的小規則實際上好像就沒那麼愚蠢了吧。他們實際上很可能是一些基本而又深刻的原則。確實,在我接觸TDD之前我曾做過將近30年的程式員,我不認為曾有過什麼人教過我什麼非常奏效但又基本的編程實踐。畢竟三十年意味著很多的經驗。但當我開始了使用TDD,我就被這項技術的有效性所震撼,也沉迷其中。我不會再考慮去敲一大堆代碼然後平白指望它們能運行成功。對於那種先將一組模組打散,然後希望能夠再將它們整合起來,並且讓它們在能下個禮拜五前運行起來的做法,我也不再能忍受。在我寫程式的時候,每一個決定都由這種讓現在開始寫的代碼能在一分鐘後再次執行這樣的基本需求所驅使著。

 

譯註:

1,TDD,測試驅動開發。

2,Kata,可理解為武功招式,詳細解釋可參見譯者的上篇譯文。

小註:本篇文章由鄧輝先生親自校正,並給予了很多中肯而深刻的建議,譯者在此給予感謝!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.