天天看點

TDD的了解與疑問

 Definition of TDD

測試驅動開發的定義

All production code is written in order to make a failing unit test pass. First, we write a unit test that fails because the functionality it is testing for doesn't exist. Then we write the code that makes that test pass.

This iteration between writing test cases and code is very rapid, on the order of a minute or so. The test cases and code evolve together, with the test cases leading the code by a very small fraction. -- <<Agile Principle, Patterns, and Practices>>

所有要寫的産品代碼都是為了通過單元測試。首先我們寫一個單元測試,由于功能尚未實作是以測試會失敗。然後我們寫産品代碼即實作其功能,能使測試通過

在測試用例和代碼之間跌代是很快速的.測試用例和産品代碼之間共同演進,每次一小部分并且總是測試用例先行

Suppose that we followed three simple rules.

三條規則

Don't write any production code until you have written a failing unit test.

沒有測試用例就别寫産品代碼

Don't write more of a unit test than is sufficient to fail or fail to compile.

隻允許編寫剛好能夠導緻失敗的單元測試 (編譯失敗也屬于一種失敗)

Don't write any more production code than is sufficient to pass the failing test.

隻允許編寫剛好能夠導緻一個失敗的單元測試通過的産品代碼

簡言之,先寫測試用例再寫代碼,每次新增測試用例剛好夠用能導緻編譯或運作失敗,每次新增代碼剛好夠能讓測試通過,别多也别少.

Benefit of TDD

采用測試驅動開發的好處有哪些呢?

顯然,第一個好處就是程式的每個單獨功能都會被測試.以免程式員沒時間測試,導緻問題發生在後續的系統內建測試中. 問題解決在系統內建測試中的成本遠遠大于單元測試中.

第二,每個寫下并通過的單元測試會成為回歸測試的基礎.即當新功能增加時,通過這些測試用例來檢測原有功能沒有被破壞

第三,先寫測試會迫使功能實作者從另一個角度來看待功能.實際上,就是從使用者的角度來看待功能,體會對函數功能的需求.

第四,如果有這些測試用例,也有助與函數調用者與實作者之間的交流. 在編碼的過程中,有的項目缺少在函數功能一級上的需求描述,或在函數功能上的需求表述不明确,不完整.而測試用例代碼則是一個比較好的描述手段.即能看(用于交流),有能用(測試)..:-)

第五,先寫測試用例也會迫使我們讓寫出的代碼時單獨可測的.從某種意義上說,也可以讓我們的軟體時松耦合的.

說了好處一堆,難要就沒什麼問題嗎?

如何能保證讓所有的函數的功能整合起來形成一個完整的大的功能?

譬如說,一個需求導緻你的子產品有多個類的方法要改動也許還要新加幾個類。當你改到最後一個方法function時,所有的改動應當是一緻的,即整體上是一個完整的解決方案。按照第一條規則,我們可以先寫一個/多個測試用例用于測試整體方案。作為設計的規範/契約。然後一個個實作我們的改動,對每個改動采用标準的TDD方法.

實際上這是一個預先設計的問題,關鍵在于我們該容忍多大限度的預先設計?怎麼知道應該何時停止預先設計?

個人觀點,技術方案的設計應能滿足在一次疊代或釋出的所有需求. 在靈活開發的疊代計劃制定上是1~2周.

而在代碼/子產品開發上,其預先設計至少應能滿足1~2天開發工作量.