第 9 章 單元測試
本章介紹一些保持軟件邊界整潔的實踐手段和技巧。程序員
9.1 TDD 三定律
TDD 要求咱們在編寫生產代碼前先編寫單元測試。
三定律:
定律一 在編寫不能經過的單元測試前,不可編寫生產代碼。
定律二 只可編寫恰好沒法經過的單元測試,不能編譯也算不經過。
定律三 只可編寫恰好足以經過當前失敗測試的生產代碼。web
9.2 保持測試整潔
測試代碼和生產代碼同樣重要。髒測試會讓測試越變越糟,維護代價增大。故測試代碼和生產代碼同樣重要。
測試帶來一切好處
覆蓋了生產代碼的自動化單元測試程序組能儘量地保持設計和架構的整潔。測試代碼了一切好處,由於測試使改動變得可能。有了覆蓋率高的測試,能夠毫無顧慮地改進架構和設計。網絡
9.3 整潔的測試
整潔的測試有什麼要素?有三個要素:可讀性,可讀性和可讀性。在單元測試中,可讀性甚至比在生產代碼中還重要。測試如何才能作到可讀?和其餘代碼中同樣:明確,簡潔,還有足夠的表達力。在測試中,你要儘量少的文字表達大量內容。架構
9.3.1 面向特定領域的測試語言
不直接使用程序員用來對系統進行操做的 API,而是打造了一套包括這些 API 的函數的工具代碼,這樣就能更方便地編寫測試,寫出來的測試也更便於測試。
面向特定領域(我理解爲測試)的語言的技巧是:測試代碼呈現構造-操做-檢驗(BUILD-OPERATE-CHECK)模式。每一個測試都清晰地拆分爲三個環節。第一個環節構造測試數據,第二環節操做測試數據,第三部分檢驗操做是否獲得強的結果。函數
9.3.2 雙重標準
測試 API 中的代碼與生產代碼相比,的確有一套不一樣的工程標準。測試代碼應當簡單、精悍、足具表達力,但它該和生產代碼通常有效。畢竟它是在測試環境而非生產環境中運行,這兩種環境有着大相徑庭的需求。
有些事你大概永遠不會在生產環境中作,而在測試環境中作卻徹底沒有問題。一般這關乎內存或 CPU 效率(在生產環境不會作,但在測試環境中作卻沒有問題,由於不會影響測試環境的整潔)的問題,不過卻永遠不會與整潔有關。工具
9.4 每一個測試一個斷言
單個斷言是個好準則,可是當一個以上斷言的前提條件相同,非要遵照單個斷言的準則,就會有重讀的代碼,因此單個測試中的斷言數量應該最小化。
每一個測試一個概念
每一個測試函數中只測試一個概念。
最佳規則是儘量減小每一個概念的斷言數量,每一個測試函數只測試一個概念。單元測試
9.5 F.I.R.S.T.
整潔的測試還遵循如下 5 條規則:
快速(Fast) 測試應該夠快。測試應該能快速運行。測試運行緩慢,你就不會想要頻繁地運行它。若是你不頻繁運行測試,就不能儘早發現問題,也沒法輕易修正,從而也不能垂手可得地清理代碼。最終,代碼就會腐壞。
獨立(Independent) 測試應該相互獨立。某個測試不該爲下一個測試設定條件。你應該能夠獨立運行每一個測試,及以任何順序運行測試。當測試互相依賴時,頭一個沒經過就會致使一連串的測試失敗,使問題診斷變得困難,隱藏了下級錯誤。
可重複(Repeatable) 測試應當可在任何環境中重複經過。你應該可以在生產環境、質檢環境中運行測試,也可以在無網絡的列車上用筆記本電腦運行測試。若是測試不能在任何環境中重複,你就總會有個解釋其失敗的藉口。當環境條件不具有時,你就會沒法運行測試。
自足驗證(Self-Validating) 測試應該由布爾值輸出。不管是經過或失敗,你不該該查看日誌文件來肯定測試是否經過。你不該該手工對比兩個不一樣文本文件來確認測試是否經過。若是測試不能自足驗證,對失敗的判斷就會變得依賴主觀,而運行測試也須要更長的手工操做時間。
及時(Timely) 測試應及時編寫。單元測試應該剛好在使其經過的生產代碼以前編寫。若是在編寫生產代碼以後編寫測試,你就會發現生產代碼難以測試。你可能會認爲某些生產代碼自己難以測試。你可能不會去設計可測試的代碼。測試
9.6 小結
測試保證和加強了生產代碼的可擴展性、可維護性和可複用性。保持測試的整潔,讓測試具備表達力並短小精悍。設計
9.7 文獻