TDD 測試驅動開發的一般原則

2021-08-22 05:12:45 字數 2171 閱讀 5819

這些年來,我喜歡下面三條簡單的規則來描述測試驅動開發:

除非這能讓失敗的單元測試通過,否則不允許去編寫任何的產品**。

只允許編寫剛好能夠導致失敗的單元測試。 (編譯失敗也屬於一種失敗)

只允許編寫剛好能夠導致乙個單元測試失敗的產品**。

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

目前有很多程式設計師,每當他們頭一次聽到這種技術的時候,會想:「這種做法太愚蠢了!」「這會讓我慢下來,這是時間和精力的浪費,讓我無法思考,無法設計,它會打亂我的思路。」然而,試想當你走進乙個房間,裡面都是用這種方式工作的人們,會發生怎樣情況。隨便乙個時間隨意找個人,一分鐘以前,他們所有的**都跑通了。

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

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

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

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

好處還不只如此。如果你想要知道如何去呼叫乙個特定的api,就會有乙個測試能夠告訴你;如果你想要知道如何建立乙個特定的物件,就會有個測試能告訴你。你想知道的任何有關這個系統的,都有乙個測試能夠去示意。這些測試就像是小型的設計文件,小型的**示例,描述了系統的工作和使用方式。

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

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

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

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

譯註:1,tdd,測試驅動開發。

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

先生親自校正,並給予了很多中肯而深刻的建議,譯者在此給予感謝!

robert c. martin

的英文blog

**: 

譯者注:

robert c. martin

TDD 測試驅動開發的一般原則

這些年來,我喜歡下面三條簡單的規則來描述測試驅動開發 除非這能讓失敗的單元測試通過,否則不允許去編寫任何的產品 只允許編寫剛好能夠導致失敗的單元測試。編譯失敗也屬於一種失敗 只允許編寫剛好能夠導致乙個單元測試失敗的產品 仔細想想,就會發現如果不是去讓一些東西編譯或是執行,你就根本沒辦法去寫 確實,這...

TDD 測試驅動開發

test driven development 測試驅動開發是敏捷開發中的一項核心實踐和技術,也是一種設計方 tdd的原理是在開發功能 之前,先編寫單元測試用例 測試 確定需要編 寫什麼產品 tdd雖是敏捷方法的核心實踐,但不只適用於xp extreme programming 同樣可以適用於其他開...

測試驅動開發TDD

測試驅動開發 testdriven development,tdd 的基本思路是通過測試推進整個的開發工作,並不只是單純的測試工作。利用這種測試方法時,若要完成某個功能,某個類,首先不是編譯正式的 而是先編寫測試 考慮其如何使用 如何測試。然後在對其進行設計 正式編碼。t dd具有很強的目的性,是在...