25 測試驅動開發模式
準備兩個TODO-List一個用于當前,一個用于最近
當發現有事情要做的時候,對其優先級進行判斷,將其放到當前或者以后。
集中注意力于當前要做的事情
斷言優先
寫Case的時候,一開始就寫斷言,從測試完成時能通過的斷言開始寫。
測試數據
測試數據要使用容易讓人理解的數據,不要為了編排數據而編排數據
不要用同一個常量來表達多種一絲。另外也可以使用真實數據進行測試。
盡量讓測試的行為和數據容易理解,比如不使用常量,而是直接使用數字。在assert中加入斷言要測試的目的的文字說明
26 不可運行狀態
一步測試(One Step Test)
從計劃列表中選擇具有指導意義而且有把握實現的測試去完成它。??
啟動測試(Starter Test)
從測試某個實質上不做任何工作的操作開始,這樣的測試一般能很快工作。而一個做實際工作的功能的測試可能需要等你解決很多問題,比如:這個操作隸屬于哪里?正確的輸入是什么?對應的正確輸出是什么?等等。結果是其長期無法通過。
回歸測試(Regression Test)
對于一個錯誤情況,編寫一個針對該錯誤的,會出錯的,盡可能小的測試。
27測試模式
子測試(Child Test)如果一個測試太大以至于難以運行起來,那么可以先把該測試給分解成幾個小的測試,并注釋掉本測試。等這些小測試通過之后再繼續這個大的測試??
模擬對象(Mock Object)
如何測試一個依賴于昂貴的且復雜的資源的對象?創建一個這些資源的模擬版本。
自分流(self Shunt)
如何測試對象間是否正常交互?讓測試對象于測試用例而不是期望的對象進行交互。
需要讓測試用例類實現所要交互的類的接口。從而進行測試所實現的方法會被正確的調用。
日志字符串(Log String)
如何才能測試使消息調用順序是正確的?將日志保存在字符串中,當調用一個消息時,就向字符串尾部追加相應的信息。
清掃測試死角(Crash Test Dummy)
如何測試到不大可能被調用的錯誤代碼呢?使用一種特殊的對象調用它,這個對象拋出一個異常而不做任何實際工作。比如實現一個匿名File子類,只實現其createNewFile方法,方法中拋出一個異常,通過這種方式來測試文件系統滿了的情況。
不完整測試(Broken Test)
留下半截句子或者一個沒有通過的測試用例可以保證你離開代碼一段時間之后依然能較快的回憶起原先的想法。
提交前保證所有測試運行通過
當你在團隊中變成時如何結束一段編碼工作?讓所有測試運行起來。
注釋掉一些測試代碼使測試套件通過是要嚴格禁止的。
28可運行模式
偽實現(直到你成功)測試不能通過時首先應該執行什么?可以返回一個常量。一旦你能使測試運行起來,那個常量就會逐漸換成用變量表示的表達式。這個方法可以從心理上讓我們感到滿足,可以讓我們集中注意力于當前要解決的問題。
三角法(Triangulation)
怎樣可以更適當地利用測試推動抽象呢?只有當你有兩個或兩個以上的例子時,你才能進行抽象。使用兩個針對同一個測試目標的測試例子(或斷言),在此基礎上對該測試目標的實現進行抽象并實現。
顯明實現(Obvious Implementation)
直接實現簡單的操作。
從一到多(One to Many)
怎樣實現一個作用于對象集合體的操作呢?首先在非集合體中實現,然后使之作用于集合體。
32 掌握TDD
什么可以不必測試?應該測試:條件部分、循環部分、操作部分、多態性。除了不信任,否則不要測試其他來源的代碼。
怎樣知道自己的測試沒有疏漏呢?
一些預示著設計存在這缺陷的特征:
過長的設置代碼——如果為了一個簡單的斷言,需要花費上百行代碼創建對象,那么肯定有哪兒不對勁兒。對象太大,需要分割。
冗余的設置代碼——如果你無法為公共代碼找到一個存放它的公共場所的話,那么就表明有太多的對象過于緊密地聯系在一起了。
過長的測試運行時間——這樣測試不會被經常運行,同時也暗示著對系統的方方面面進行測試是困難的。這種測試困難是一種設計問題,并且需要在設計時就被提出來。
脆弱的測試——意外中斷的測試說明應用的某一部分出人意料地存在對另一部分的影響。你需要對系統進行設計,要么打破聯系,要么將兩部分合并,直到這種影響消失為止。
你需要多少反饋?
測試驅動的開發對測試的觀點就是注重實效。在測試驅動開發中,測試從某種意義上說是一種達到目的的手段——達到充滿自信地編寫代碼的目的。如果我們對實現有充分了解,不用測試就能擁有自信的話,那么就沒有必要編寫測試了。
什么時候應該刪除測試?
如果刪除一個測試降低了你對整個系統功能的信心,那么就不要刪除。
如果你有兩個測試,走的是同一條路,但對讀者來說講述的是不同的情形的話,那么就應該原封不動的保留。
如果有兩個測試,它們就自信和溝通而言都是冗余的,那么就刪除其中用處最小的那個。
如何中途轉向測試驅動開發?
首先限定修改的范圍。對于該范圍外的可以簡化的地方先不動手。
其次,必須打破測試與重構之間的僵局??梢韵韧ㄟ^其他方式獲取反饋,如系統測試,然后使用這些反饋進行修改。通過這種方式逐漸的讓一直在改變的部分轉向測試驅動。