測試驅動的面向對象軟件開發(fā)

出版時間:2010年8月  出版社:機械工業(yè)出版社  作者:Steve Freeman,Nat Pryce  頁數(shù):253  譯者:王海鵬  
Tag標簽:無  

前言

  隨著軟件發(fā)布周期越來越短,一個困境出現(xiàn)了:如何在更少的時間里發(fā)布更多的軟件,并持續(xù)地發(fā)布下去?我們需要新的觀點來解決這個困境。只有技術的轉變是不夠的。  本書展示了這樣一個新觀點——假如軟件不是“做”出來的,不像我們做紙飛機那樣,疊好后就飛出去,情況會怎樣呢?假如我們像對待有價值、有產出的農作物那樣(培育、剪草、收割、施肥和灌溉)對待軟件,情況會怎樣呢?幾十年或幾個世紀以來,傳統(tǒng)的農夫知道如何讓農作物高產。如果我們以同樣的方式對待程序,軟件開發(fā)會有什么不同呢?  我印象最深的是,本書同時提供了這種觀點轉變的哲學思想和實現(xiàn)機制。本書的作者是善于寫代碼的實踐者,他們也善于教別人寫代碼。您從中可以學到如何保持高產,以及如何重新審視您的程序。  這里展示的測試驅動開發(fā)的方式不同于我所使用的方式。雖然我還不能清晰表達其中的區(qū)別,但我已從作者清楚、自信的技巧介紹中受益。方言的多樣化已經為我進一步優(yōu)化開發(fā)提供了思考的新源泉。本書展示了一個有條理的、一致的開發(fā)體系,其中的不同技巧相互支持?! ∥医ㄗh您閱讀本書,通過書中的例子,了解作者如何思考編程,如何實踐編程。這種體驗將豐富您的軟件開發(fā)方式,有助于您編程,而且同樣重要的是,有助于您以不同的觀點來看待您的程序。

內容概要

本書采用通俗易懂的比喻,眾所周知的編程語言,短小精悍的工作實例,深入淺出的分析處理——仿佛在和幾位世界級的編程高手一邊喝茶,一邊聊天,循序漸進地讓讀者在不知不覺中進入編程的最高境界。即使是剛剛入門的初學者,也會從中找到讀書的樂趣,因為可以從一開始就找到開啟面向對象開發(fā)大門的鑰匙;隨著經驗的積累,編程水平的提高,再來看這本書,用不同的視角重新審視程序,又會體會到更深層的編程哲學?! ”緯蔷幊虗酆谜叩膯⒚芍改?,更是系統(tǒng)分析人員、測試人員、程序設計人員、軟件開發(fā)人員以及面向對象程序研究人員等專業(yè)人士革新編程思想的必備手冊。

作者簡介

Steve Freeman是一名獨立咨詢師,擅長領域是敏捷軟件開發(fā)(http://www.m3p.co.uk)。他與Nat Pryce一同贏得了2006年敏捷聯(lián)盟的Gordon Pask獎。他是倫敦極限星期二俱樂部(London Extreme Tuesday Club)的創(chuàng)建成員,也是第一任倫敦XP日(London XP Day)的主席,還經常在國際

書籍目錄

對本書的贊譽 譯者序 序 前言 作者簡介 致謝 第一部分 簡介  第1章 測試驅動開發(fā)的要點  第2章 測試驅動開發(fā)與對象  第3章 工具介紹 第二部分 測試驅動開發(fā)過程  第4章 啟動測試驅動循環(huán)  第5章 保持測試驅動循環(huán)  第6章 面向對象風格  第7章 實現(xiàn)面向對象設計  第8章 基于第三方代碼構建 第三部分 工作的例子  第9章 委托開發(fā)一個拍賣狙擊者  第10章 可行走的骨架  第11章 通過第一個測試  第12章 準備競拍  第13章 狙擊者發(fā)出競拍出價  第14章 狙擊者贏得拍賣  第15章 邁向真正的用戶界面  第16章 狙擊多項物品  第17章 分解Main  第18章 填充細節(jié)  第19章 處理失敗 第四部分 可持續(xù)的測試驅動開發(fā)  第20章 聆聽測試  第21章 測試可讀性  第22章 構造復雜的測試數(shù)據(jù)  第23章 測試診斷  第24章 測試的靈活性 第五部分 高 級 主 題  第25章 測試持久性  第26章 單元測試與線程  第27章 測試異步代碼 后記 模擬對象簡史 附錄A jMock2速查手冊 附錄B 編寫Hamcrest Matcher 參考文獻

章節(jié)摘錄

  這意味著在實踐中我們可以把系統(tǒng)分成兩個“世界”:值和對象。值以函數(shù)式的方式對待,對象則實現(xiàn)了系統(tǒng)有狀態(tài)的行為。在第三部分,您會看到書中的編碼風格是如何根據(jù)我們面對的世界而變化的。  在本書中,我們將使用術語“對象”來指具有標識符、狀態(tài)和處理過程的實例,而不用于指值。似乎沒有其他可以接受的術語同時包含這兩種含義(如實體或過程)?! ?.3 對象通信  只有當對象設計容易組合時,我們才能從這種高層次的、聲明式的方式中獲益。在實踐中,這意味著它們遵循相同的通信模式,也意味著它們之間的依賴關系是顯式的。通信模式是一組規(guī)則,決定了一組對象相互交談的方式。這些規(guī)則包括它們扮演的角色、它們可以發(fā)送什么消息、何時可以發(fā)送等。在Java這樣的語言中,我們可以利用(抽象的)接口來標識對象的角色,而不是利用(具體的)類——雖然接口不能定義任何我們想說的內容?! 「鶕?jù)我們的觀點,領域模型就在這些通信模型之中,因為正是它們?yōu)閷ο箝g可能的關系賦予了意義。以動態(tài)的、互相通信的結構來思考一個系統(tǒng),這對于靜態(tài)的分類來說是思考方式的巨大轉變,而我們中的大多數(shù)人在剛接觸對象時學到的都是靜態(tài)的分類。領域模型甚至都不是明顯可見的,因為在我們使用的編程語言中,通信模式沒有明確表達出來。本書希望展示測試和模擬對象如何幫助我們更清楚地看到對象之間的通信?! ∵@里有一個小例子,說明關注對象間的通信是怎樣指導設計的?! ≡谝粋€視頻游戲中,對象可能包括:參與者(如玩家和敵人)、場景(玩家飛過的環(huán)境)、障礙(玩家遇上就會撞毀)、效果(如爆炸和煙霧)。還有一些腳本,它們在游戲過程中在后臺大量生成對象?! 耐婕业囊暯莵碚f,這是一種很好的分類,因為它支持我們在玩游戲時需要做出的決定,也就是從外界與游戲進行交互時做決定。但是,對于實現(xiàn)這個游戲來說,這不是很有用的分類。游戲引擎必須顯示可見的對象,告訴對象隨時間產生動畫效果,檢測實體對象間的碰撞,并在實體對象發(fā)生碰撞時,把決定代理給碰撞處理器,如圖2-2所示?! ≌缒趫D2-2中看到的,這兩種視角是不同的,一個是從游戲引擎的角度來看,另一個是從參與對象實現(xiàn)的角度來看。例如,障礙是可見的、實體的,而腳本是碰撞處理器和動畫的,但不是可見的。游戲中的對象扮演了不同角色,取決于引擎當時對它們的需要。這種靜態(tài)分類與動態(tài)通信之間的不匹配意味著,我們不太可能對游戲對象得到一個整齊的類層次結構,同時又能適合引擎的需要?! ≡谧詈玫臅r候,類層次結構代表了應用的一個維度,它提供了一種機制,讓對象之間能共享實現(xiàn)細節(jié)。例如,我們可能有一個基類來實現(xiàn)基于幀的動畫的共同特征。在最壞的時候,我們曾看到許多代碼庫(包括我們自己的),充滿了復雜性和重復,因為使用一種機制來表達多個概念。

媒體關注與評論

  “終于有一本書用豐富的代碼揭示TDD和OOD之間的共生關系。本書值得保存?!薄  猂obert C.Martin  “如果您想成為當前TDD領域的一名專家,就需要理解本書中的思想。”  ——Michael Feathers

編輯推薦

  《測試驅動的面向對象軟件開發(fā)》對于更快交付更好的軟件,測試驅動開發(fā)(TDD)現(xiàn)在是一種已經確立的技術。TDD基于一個簡單的思想:在寫產品代碼之前先寫它的測試代碼。但是,這個“簡單”的思想需要一些技能和判斷才能做得好?,F(xiàn)在有了一本TDD實踐指南。讓您深入理解那些基本概念,并向您展示了如何讓測試來引導開發(fā),“培育”出一致的、可靠的。可維護的軟件。  作者描述了他們使用的過程,努力實現(xiàn)的設計原則。以及完成工作的一些工具。通過一個詳細實現(xiàn)的例子,您可以看到TDD如何在各個層次上工作,如何利用測試來驅動特征開發(fā)和代碼的面向對象結構,如何利用模擬對象來發(fā)現(xiàn)并描述對象之間的關系。在這個過程中。《測試驅動的面向對象軟件開發(fā)》系統(tǒng)地討論了開發(fā)團隊在使用TDD時遇到的挑戰(zhàn)——從過程中集成TDD到測試最難的特征?! ∨f代碼帶來的新思維,Robert C.Martin高度評價,Kent Berk作序推薦?!  稖y試驅動的面向對象軟件開發(fā)》包括以下內容:  ●如何有效實現(xiàn)TDD:啟動,然后在整個項目中保持你們的沖勁?!  袢绾蝿?chuàng)建更干凈的、更有表現(xiàn)力的、更可維護的代碼?!  袢绾卫脺y試。對可持續(xù)的品質保持最嚴格的關注。  ●理解在真實軟件開發(fā)的環(huán)境中,TDD、模擬對象、面向對象設計如何交織在一起?!  袢绾卫媚M對象來指導面向對象設計?!  袢绾卧赥DD困難的地方取得成功:管理復雜的測試數(shù)據(jù)。測試持久層和并發(fā)。

圖書封面

圖書標簽Tags

評論、評分、閱讀與下載


    測試驅動的面向對象軟件開發(fā) PDF格式下載


用戶評論 (總計13條)

 
 

  •   這本書有兩大看點,一是如何執(zhí)行測試驅動的開發(fā),二是面向對象的軟件設計,都融合實例演繹的非常透徹,十分推薦。
  •   早就聽說過TDD在程序開發(fā)中的重要性,限于時間,一直未能好好的學習一下該項技術。現(xiàn)在終于到了學習TDD的時候了,就從本書開始我的TDD之旅吧!
  •   搞活動時買的超值
  •   剛看了幾眼 感覺還行吧~
  •   比較泛,感覺不好
  •   少有的面向對象的測試驅動書籍
  •   書還湊合,紙張有點弱,不影響閱讀,還行
  •   看了一點點,書中用的講解的例子挺高深的
  •     例子有些過于復雜,再加上代碼沒有有效組織,很容易迷路。書中甚至沒有提到代碼的下載。
      
      
      建議學習《單元測試的藝術》,更為清晰。
      
      建議學習《單元測試的藝術》,更為清晰。
      
      建議學習《單元測試的藝術》,更為清晰。
      
      建議學習《單元測試的藝術》,更為清晰。
      
      建議學習《單元測試的藝術》,更為清晰。
      
  •       這本書2009年10月就出來了,當時沒來得及細看,只是把它放入了我的待讀列表中。后來查到2010年8月也出了中文版,書名叫《測試驅動的面向對象軟件開發(fā)》??赐耆珪?,我發(fā)現(xiàn)本書重點談的還是軟件培養(yǎng)問題。Growing這個詞出現(xiàn)在書的標題中,非常吸引我的思路。
      
        在前言中,作者開宗明義,講了本書要強調的五個問題:1.如何讓測試驅動開發(fā)適應我的工程;2.從那里開始做TDD;3.如何寫單元測試與端對端測試;4.測試驅動開發(fā)的“驅動”是何意;5.如何測試某一個困難的功能。
      
        第一部分是簡介。導言部分說了,TDD不僅是XP(極限編程)的核心實踐,而且也被Crystal Clear,Scrum等敏捷開發(fā)方法才用。敏捷和非敏捷項目都可應用TDD,甚至是純研究項目都可以。
      
        第一章重申TDD的紀律——“在沒有一個失敗的用例之前,不要寫任何功能”。其后提出,將傳統(tǒng)的“測試-實現(xiàn)-重構”小迭代外面,包上一個驗收測試(Acceptance Test)。驗收測試是測試整個系統(tǒng)是否能工作的。與之區(qū)別的是用于測試現(xiàn)有代碼與我們不能改變其代碼的模塊是否能配合工作的集成測試(Integration Test),以及測試對象本身功能的單元測試(Unit Test)。最后強調了單元測試能夠給我們一個發(fā)現(xiàn)不良設計以及重構代碼的機會。
      
        接下來第二章講述了“值類”和“對象類”的區(qū)別。針對不變的數(shù)量和度量進行建模,就是“值類”,它有些類似“不可變類”(Immutable Class)或者無狀態(tài)(Stateless)類。如果針對行為進行建模,則是“對象類”了。最后講述了要使用單一的“告知型”調用代替請求式的一連串調用,例如用“master.allowSavingOfCustomisations();”來代替“((EditSaveCustomizer)master.getModelisable().getDockablePanel().getCustomizer()).getSaveItem().setEnabled(Boolean.FALSE.booleanValue());"。第三章介紹了一些TDD的基本工具。
      
        第二部分講述了TDD的具體過程。第四章講了如何確定測試驅動開發(fā)的第一個迭代周期。提出先實現(xiàn)最少量的真實功能以便可以自動地構建、部署、端對端測試。這叫做“行走骨架”(Walking Skeleton),具體的說,是通過“理解問題->設計草圖->自動化構建,部署,端對端測試->普通迭代”這個流程來做的。其后說道,測試先行的工程早起會引入混亂,但是迅速降低,因為找到了發(fā)展的方向,預見了可能發(fā)生的錯誤。相反,測試后行(或到發(fā)布期限前才集成)的工程在最后會出現(xiàn)大量的混亂。這可以作為是否選取TDD的一個參考標準。而“行走骨架”的好處就是,能讓我們在仍有時間、預算和解決問題的意愿時,去解決問題,而不至于到了發(fā)布前才發(fā)現(xiàn)工程已經失控。
      
        第五章講了如何維護測試驅動周期。作者提出,將衡量進度的測試(針對新功能的驗收測試)和用以捕捉“功能破壞”(Regression)的測試(已有的驗收測試、整合測試、單元測試)分隔開來。“筆者注:廣義的回歸測試即為了保證正在開發(fā)的新功能不破壞既有功能而寫的測試,狹義的回歸測試專指前述的驗收測試?!贝撕筇岬絻蓚€問題,一是不要著急寫單元測試,以免整合時發(fā)現(xiàn)功能不符合需要,二是要學會“傾聽測試”——難于測試的功能往往意味著設計需要改進。如不改進,如果功能增多,則該有問題的設計會更難于修改。
      
        第六章講述了如何在TDD中使用面向對象的風格。作者講述了Cockburn的“端口與適配器”架構,業(yè)務領域的代碼應該同技術設施,例如數(shù)據(jù)庫,UI等,分離開來。不要讓技術概念泄漏入應用程序模型。所以要通過接口將應用程序核心業(yè)務與每個技術領域橋接起來。這就是Eric Evans在《領域驅動設計》中所說的防腐層(Anticorruption Layer)。其后又講了封裝和信息遮掩的區(qū)別。封裝主要是相對于“對端”(Peer)來說的,強調訪問只能通過API進行。而信息遮掩主要是針對上層業(yè)務來說的,意在使得高層邏輯不需關注低層細節(jié)。封裝和信息遮掩中的兩個常見問題即是通過API返回內部實現(xiàn)而產生的“別名”效果。以及沒能提供直接的API調用,導致客戶代碼通過自己組合API來完成任務,就像前述的一連串調用那樣,暴露了過多細節(jié)。接下來講了達成“單一責任原則”的一個口訣:不用任何連詞(和,或,但)去描述對象。如果有從句,那么應該按照從句,把大對象拆分成一個個互相合作的小對象。這對于我們檢視自己的設計很有幫助。作者將設計中一個對象的協(xié)作者,分為三種角色模板。即依賴其服務方能運轉的“依賴物”(Dependencies),用于通知事件而不關注其具體身份的“被通知物”(Notifications),以及利用其調整自身行為以符合系統(tǒng)需求之“調整物”(Adjustments)。其后作者講了“組合體對象”(筆者注:即組合各種對象來完成自身任務的功能模組,不同于設計模式中的組合體模式)所提供的API要比其各自部分的API總和簡單。它封裝了組件的存在及其內部互動,為其對端展示出一個更簡單的抽象接口。本章的最后講述了“環(huán)境獨立性”的重要。“環(huán)境獨立性”規(guī)則幫我們判斷一個對象是否隱藏的太多或者隱藏了錯誤的信息。當執(zhí)行環(huán)境變化時,環(huán)境獨立的對象是易于改變的。其運行大環(huán)境可以通過構造器(如果對于該對象是貫穿生命期的)或需要環(huán)境的方法(如果是瞬態(tài)的)傳入。
      
        第七章繼續(xù)講述如何達成面向對象的設計。首先講述TDD對OO設計的幫助:1.我們必須先描述我們要做什么,而后才是怎么做;2.為了使得單元測試易懂(由此變得可維護),我們必須限定它們的范圍(筆者注:如果單元測試過長或者setup階段太繁復,則意味著受測的那個大對象需要拆解);3.我們必須將其依賴物傳給它,這意味著我們必須知道它依賴的都是些什么東西。再說了接口和協(xié)議的作用:接口描述了兩個組件是否互相適配,而協(xié)議則描述了他們是否能一起運轉。又講了測試可以幫助我們發(fā)現(xiàn)設計中的問題:一個雜亂或不清晰的測試暗示著我們暴露了太多實現(xiàn),而且我們應該重新考量該對象及其臨接物件的責任分配。在講到值類和對象類的設計時,作者提出了三個技巧:打散(將一個大對象分割成一組互相協(xié)作的小對象)、剝離(定義一個對象所需的新服務,增加一個提供該服務的新對象)、捆綁(將相關對象藏入一個容器對象中)。最后在談到接口問題時,作者提出了兩個觀點。一個說道:針對某一個接口的實現(xiàn)而寫的Impl類是沒有意義的。如果實現(xiàn)類真的沒有一個好名字,那可能意味著接口的命名或者設計很糟。可能它因為有太多的責任而喪失了重點;也可能它是以實現(xiàn)的角度命名,而非以其在客戶代碼的角度上;又或者它是一個值而非一個實體對象——這種不協(xié)調有時會在寫單元測試時呈現(xiàn)出來。(例如MyInteger和MyIntegerImpl這種接口分離就是很糟糕的)另一個說:應該根據(jù)需要合并或者拆分接口。在發(fā)現(xiàn)實現(xiàn)類的結構不清晰時,應考慮接口是否沒有側重點,需要拆解。
      
        第八章講如何在第三方代碼之上構建自己的工程。作者建議寫一個適配器對象層,其使用第三方API實現(xiàn)它們的接口。我們用有重點的集成測試去測試這些適配器,以確認我們理解了第三方API是如何工作的。
      
        第三部分講了一個例子,用開發(fā)一個捕捉拍賣行情而自動出價的競拍器,來說明如何以測試為指導,去培養(yǎng)OO軟件開發(fā)。本部分跨越了十一章。在這個過程中,穿插著對前兩章所講原則的實例化運用。第十一章演示了如何用最少的代碼搭建起來可以執(zhí)行的端對端測試。在本例中,僅有一個測試用空殼服務器,一個Swing窗口(最少的代碼),主程序向“服務器”發(fā)送加入消息,核實服務器確實收到消息;服務器關閉競拍,窗口顯示失敗消息,核實窗口確實顯示了失敗消息(可執(zhí)行的端對端測試)。第十二章對如何組織測試提出了小建議:將測試放在一個不同的包中。防止通過包級別的后門去測試,同時方便在IDE中瀏覽。第十五章講述了修改命名的重要性:重命名代碼中的若干功能,這是開發(fā)進程的一個重要部分,就像我們可以用已經寫出的代碼來更好地理解結構應該如何發(fā)展一樣,我們也通過用已經修改過的名字去編程以更好地理解這些名字的意義。我們可以理解類型和方法名是如何互相配合起來工作的,以及概念是否清晰,這都會激發(fā)我們發(fā)現(xiàn)新的想法。如果一個功能的名字不對,唯一能做的明智事情就是改變它,以免過后閱讀代碼的人花了數(shù)不清的時間也弄不清代碼在干什么。第十七章說到靜態(tài)設計和動態(tài)設計的問題:重構非常關注于靜態(tài)結構(類與接口),以至于很容易忽略應用程序動態(tài)結構(實例與線程)。有時我們需要退一步考慮,去畫一個類似互動圖那樣的東西。其后的第十八章說道TDD應該和其它的建模手段結合起來使用,并且不要把其它的建模技巧當作一種目的,而是要理解它們,并且把它們當作支持與指導開發(fā)的一種手段。最后第十九章說我們必須知道如何漸進式的改變代碼,尤其是使得代碼結構良好,以至于我們可以根據(jù)需求的改變把代碼帶我們想去的地方。
      
        第四部分標題“可持續(xù)的測試驅動開發(fā)”,意為教大家如何提高測試的質量,以便讓測試能夠更及時、更好地提供關于設計缺陷的反饋。第二十章講了幾個知識點。當我們在測試驅動開發(fā)的過程中提取一個接口,我們就必須想出一個名字來描述剛剛發(fā)現(xiàn)的關系。我們覺得這使我們深入思考領域問題,并梳理出可能會錯過的概念。只覆寫可見的方法(即保護的和公有的)。這個規(guī)則防止了僅僅為了測試能覆寫而暴露了內部方法。在談到模仿對象(Mock Object)時,作者說有兩個試探法可以決定一個類是不是像值類從而不值得去仿造它。第一,它的值是不可變的;第二,我們想不出來一個有意義的名字來描述把這個類當作接口之后,實現(xiàn)它的那個類。在對付膨脹的(參數(shù)過多的,過于復雜的)構造器時,作者提出可以提取出隱含的組件。其要尋找兩個條件:經常在類里一起使用的參數(shù);擁有相同生命期的參數(shù)。當我們剛好找到了這種情況時,就得努力想出一個好名字來解釋這個概念。一個做得好的設計,其標志之一即是這種改變可以很容易集成進來。我們堅持依賴物應該通過構造器傳入,但是被通知物和調整物可以設置為缺省值,稍后再行配置。當一個構造器太大了,并且我們不認為參數(shù)中隱含有一個新的類型時,我們可以用更多的缺省值,僅在有特殊的測試用例時才覆蓋掉它們。在談到期望陳述時,作者說要避免太多的期望。如果我們有很多期望,要么就是視圖測試一個過于龐大的單位,要么就是鎖定了太多的對象交流行為。作者還談到了傾聽測試給我們帶來的四個好處:使領域知識局部化;將對象間的關系抽象并命名成類;通過定義類型和角色而帶來更多的名字,就意味著帶來更多的領域信息;與其提供數(shù)據(jù),不如提供行為。本章最后總結說:測試驅動開發(fā)是低容忍度的。低質量的測試會使得開發(fā)速度變得非常慢,而且受測系統(tǒng)內部代碼質量低的話,會導致測試的質量也跟著變低。
      
        第二十一章講了測試的可讀性問題。以下五種情況應當改進:1.測試名稱沒有清晰的描述出每個測試用例的重點,以及它和其余測試用例的差別;單一的測試用例執(zhí)行了多個功能;測試用例間的結構差異很大,以至于讀者不能通過速讀來理解它們的意圖;過多的設置和異常處理代碼,將業(yè)務邏輯淹沒其中;測試使用了不明其意的字面值(魔法數(shù)字)。在講到如何命名測試時,作者介紹了TestDox約定法,即使每一個名字讀起來像一個句子,其隱含主語即為測試目標,例如:A List holds items in the order they were added. A List can hold multiple references to the same item. A List throws an exception when removing an item it doesn’t hold.即可翻譯成三個測試方法的名稱:holdsItemsInTheOrderTheyWereAdded(),canHoldMultipleReferencesToTheSameItem(),throwsAnExceptionWhenRemovingAnItemItDoesntHold()。在變量的命名上,作者強調我們應該用能夠顯示這些值或者對象在測試中所扮演的角色以及他們同目標對象的關系的名字來命名。
      
        第二十二章講了如何構建復雜的測試數(shù)據(jù)。測試數(shù)據(jù)構建器的一個好處是,我們可以寫出易于閱讀且便于發(fā)現(xiàn)錯誤的測試代碼,因為每個構建器方法都指明了它的參數(shù)的意圖。
      
        第二十三章講述了如何從測試失敗信息中演進工程代碼。作者說,就算是發(fā)生在和我們現(xiàn)在所做無關的領域里面,未預期的測試失敗,也可能是有價值的。因為它們揭示了代碼中我們所未注意到的隱含關系。如果一個失敗的測試清楚的解釋了失敗的東西和原因,我們就可以快速的排查并修正代碼。同時作者建議,“經常同源代碼庫同步——可以到隔幾分鐘就一次的頻度——以便一旦一個測試突然失敗了,你不需要花費多長時間就能撤銷最近的修改,并去嘗試另一個方法。……比起一直查錯,有時候回滾代碼并以一個清晰的頭腦重新思考“如何去寫”,可能會更快。”
      
        第二十四章講了測試的靈活性。如果一個對象因為有太多的依賴物或者其依賴物是隱藏的,從而很難從它的環(huán)境中解耦,那么當系統(tǒng)的某個偏遠角落改變了,測試就會失敗。
      
        最后的第五部分講述了一些高級話題,第二十五章講述了持久化。作者提出將影響持久化狀態(tài)的測試孤立開來。將執(zhí)行持久話操作的測試和針對被持久話對象進行的測試分開來做。并且提及一個小技巧:不要以模式來命名類或者接口,它們與系統(tǒng)其它類之間的關系才是重要的。當它們的工作方式改變時,這樣做會使得名稱具有誤導性。第二十六章講述了單元測試和線程。作者提出,并發(fā)是一個系統(tǒng)級別的關注點,我們應該在需要執(zhí)行并發(fā)任務的對象“功能對象”之外來操控它。最后第二十七章講述了測試異步代碼的問題。作者指出,一個測試可以有兩種方式觀察系統(tǒng):采樣可被觀測的狀態(tài)或者監(jiān)聽它發(fā)出的事件。同時還指出了異步測試的一個注意點:測試可能會在系統(tǒng)之前運行以至于沒有測試任何有用的東西。這會造成貌似正確的結果:錯誤的代碼看起來好像能正常運行。還提出,采樣測試與監(jiān)聽事件測試的一個明顯區(qū)別是,輪詢可能會錯過被新近狀態(tài)所覆蓋掉的狀態(tài)更新。解決辦法是,可以查找記錄。觸發(fā)一個刺激事件,并等系統(tǒng)狀態(tài)穩(wěn)定再查詢。作者又提出,我們經常采用一個命名方案去區(qū)分同步與斷言。例如waitUntil()是等待某一個受測系統(tǒng)穩(wěn)定(同步代碼),而assertEventually()則是斷言某個事件最終會發(fā)生。本章最后作者講述了測試排期事件的問題。通過將事件排期機制從系統(tǒng)中解耦,可以使得系統(tǒng)的行為具有確定性從而更易測試事件。我們可以將事件的生成抽取成一個由外部驅動的共享服務。
      
        本書的跋很值得一讀。寫了整個jMock從構想,初創(chuàng),演進到鞏固的過程。起初是為了方便測試某一個對象內部的功能機制是否如我們預期,后來逐漸把關注點從參數(shù)的值轉移到了對象之間的信息溝通上?,F(xiàn)在jMock已經成為一個單元測試和驗收測試中進行期望陳述與斷言的常用庫了。讀者有必要熟悉并掌握它。最后的兩個附錄講了jMock2庫和Hamcrest匹配器的使用方法,如果對書前面的范例代碼中的用法不太熟悉,可以參考。
      
        總的說來,在讀此書的過程中我非常驚喜,發(fā)現(xiàn)盡管TDD有很多令人詬病的缺點,但是仍然有人和我想像一樣,用不瘟不火的穩(wěn)健心態(tài)來創(chuàng)造性的加入“培養(yǎng)”要素,以使得TDD對工程開發(fā)有更大的促進作用。測試是一個良好的反饋來源,可以真實的反映出我們在設計中考慮不周到之處,以及時督促我們改進產品代碼的設計。要想讓測試能夠如此培養(yǎng)軟件的開發(fā),就必須著力于測試代碼的先行性、正確性、可讀性與靈活性。同時要注意用驗收測試來催生新的迭代周期,在修改代碼時不僅要運行單元測試,更要及時運行驗收測試以獲得更多回饋。我想信,用心于測試的努力,必能在產品代碼的研發(fā)中產生加倍的回報。
      
      本文為原創(chuàng),如需轉載請聯(lián)系作者(Email eastarstormlee@gmail.com 微博 http://weibo.com/eastarlee)
  •     有很多書說過要寫好的代碼,代碼要高內聚,低耦合。代碼要符合SOLID原則。我們都知道這些說教,這些原則;但是,我們如何才能知道我寫的一段代碼不好呢,原則往往漂浮在理論層次,理論來源于實踐,但是高于實踐。我們必須需要一些“硬指標”來衡量我的代碼,為什么說這段代碼是不好的呢?所以我們必須找到一些信號。
      這些信號可以來自哪里,測試就是其中一個信號源。
      1、一段代碼難以測試?需要構建很多其他對象,然后才能實例化這個對象?請你務必檢查一下這個對象的職責是否單一。
      2、一段代碼難以測試?需要構建一些很難構建的對象,而這些對象由不受我們的控制。請你務必檢查一下我們是否需要對這些我們沒法控制的難以創(chuàng)建的對象進行抽象,進行適配。
      3、很難給一個測試方法起名字?是否意味著被測試的方法功能不明確或者職責太多。
      
      我已經讀完了本書的第一、二以及四部分,我就覺得收獲良多,如果你想實行測試驅動開發(fā),那么這本書絕對是你的良師益友。
      唯獨有點缺陷的是,本書翻譯不是很通順,有些地方稍顯生硬,不過絕對不影響閱讀,我是這么覺得~~~
  •     書很薄,思想很豐富,結合了TDD思想與OOD思想的融合,還介紹了JMOCK2、HAMCREEST、JUnit4三個最有價值的工具。作者10余年的TDD經驗指導性很強,堪稱神作。
      
      我相信它可以提升你至少一個檔次!
  •     本書作者是Mock技術的早期創(chuàng)始人,對OO理論和TDD的理解很深。讀本書不僅是學習TDD,更是學習OO思想和方法。相比Kent Beck的《TDD by Example》本書要好一個檔次。
 

250萬本中文圖書簡介、評論、評分,PDF格式免費下載。 第一圖書網(wǎng) 手機版

京ICP備13047387號-7