作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/
1. 書籍資訊
作者: Kent Beck
譯者: 張平平
出版社: 中國電力出版社
出版年: 2004-4-1
頁數: 184
定價: 28.0
裝幀: 平裝(無盤)
ISBN: 9787508321738
2. 讀書筆記
上學的時候常常接觸實作性很強的書籍,少有接觸帶有方法論的書籍,看這本書算是個好的起點。Test Driven Development,簡稱TDD,翻譯為測試驅動開發,在極限編程(XP)中佔有核心的地位。
這本書實質上分為三個部分,第一部分是TDD的一個執行個體,第二部分介紹測試架構的構建原理,第三部分介紹TDD的流程和常用方法。前兩部分完全可以跟著動手做,後一部分理論和經驗居多,有些看的不是非常懂,還需要回頭返回來在實踐中反覆揣摩。
這本書在開篇前言中就提出了TDD的目標,即“Clean code that works ”,在這個目標的指引下,整個過程要經過不可運行->可運行->重構:
- 快速新增一個測試。
- 運行所有的測試,發現最新的測試無法通過。
- 做一些小小的改動。
- 運行所有的測試,並且全部都通過。
- 重構重複代碼,以消除重複設計,最佳化設計結構。
雖然,當採用TDD時,最終要編寫的代碼和測試代碼幾乎相同。但這種程式編寫流程的具備如下優點:
- 不是從構建對象開始,而是從一個個實際的業務測試案例開發,使得開發人員能夠更加專註於業務需求。
- 採用將一個問題以測試案例是否通過的方式來一步步分解,這樣不斷的逼近進行問題的求解,使得程式的設計和實現得到最大的簡化。
- TDD是對付完美主義分子進度緩慢的良藥,因為強調速度,所以允許在構建測試案例時喪失掉一切優秀的軟體設計原則。(不過作者提到“給自己下保證要是不消除重複設計絕不回家”,這種完美主義太坑爹,多少程式員就是這麼加班的啊~其實“不完整的測試案例有時對工作進度是一個記憶的標識~”)
- TDD並不能使我們靈光乍現,但是TDD有時會在心理上形成良性迴圈,協助人更加自信,不斷的測試除了可以使我們逐步自信之外還可以協助我們在認真重構中尋找洞察力。
上述這個逼近目標進行重構的過程中,在代碼層次上可以使用以下技巧:
- 建立Stub。
- 用變數逐步替代常量。
- 利用數值對象:某一種需求中要求一旦執行個體變數的值在建構函式中指定好了,那麼以後再不允許發生變化,這就是說所有的操作都必須返回一個新的對象,這就是數值對象,像書中寫美元等對象一樣,採用值對象,注意在Java 中這意味著你必須重寫equals和hashcode方法。
- 通過將子類由父類或介面代替而隱藏了介面,並引入能進一步完成解耦,此時測試代碼可能有所冗餘,可以暫時不管他們。並且利用逐步重構->產生相同的重複代碼->Pull up代碼這個步驟完成結構上的重構。
- 逐漸掏空子類的功能,然後將其刪除。
- 無論何時,當我們需要顯式的判定是哪種類時才進行下一步工作,都要用多態來替代。
- Java中使用匿名內部類對方法進行重載是製造Mock Object、實現對象部分邏輯與錯誤測試的一個有效方法。
- 在測試的時候通過運算式代替魔數,來表現所測試的功能流程。
- 通過Factory 方法可以消除不必要存在的子類,另外當建立對象時需要一定靈活性時,Factory 方法是個不錯的主意。
- 模板方法的最佳實務:當發現兩個子類中存在某一順序步驟的兩個變體時,你需要一點一點地縮小他們的差異,一旦從某個方法中提取出相異的部分後剩下的就是模板方法了,這時就可以將這個模板方法提到父類中去。
- 在檢查條件等時可以採用Null 物件的方式,返回一個帶有與後續相關操作同名但空實現方法的類的執行個體,這樣就不用檢查某些特殊條件了。
- 當一個子類的有太多的子類,而且每個子類僅僅實現一個方法,那麼可以使用反射來進行一個統一類的構建。
- 重構時的思路:從最簡化的結果形式上倒著推。
在過程式控制制上,可以使用以下技巧:
- 三角形法則:只有當測試案例多於2個時才對代碼進行一般化,顯然這是一個帶有偷懶性質的東西,但確實是一個工作進行推進的方式。在推動抽象進程時採用三角法 ,即通過兩個或兩個以上的例子進行舉例,進而得到抽象的靈感。
- 請使用TO-DO清單來記錄整個過程,遇到一個潛在的問題時,沒有立即著手解決的把它們記錄在計劃清單上,以防有遺漏。
- 引入大規模的測試前,先使得小規模測試獲得通過。
- 選擇那些具有指導意義,並且有把握實現的測試來進行測試案例的編寫,並且在測試的剛開始要選擇實質上不做任何工作開展測試。
作者在描述一些情境時採用了比喻的手法,有時,比喻的作用非常的顯著,能指導開發。另外,通過這本書的第二部分還對Junit測試架構的設計理念和基本設計方法有了初步的認識,例如Junit之所有setUP等方法,目的有兩個一個是為了測試的效能,一個是為了隔離各個測試案例。
3. 書中代碼實作
http://gnuhpc.googlecode.com/svn/trunk/Wycash/
http://gnuhpc.googlecode.com/svn/trunk/TestFrame/
4. 有關後續閱讀材料貯備
http://css.dzone.com/category/tags/tdd