單元測試
我們寫它是為了確保程式能夠「順利運作」。
TDD 的三大法則
- 在撰寫一個單元測試 (測試失敗的單元測試)前,不可以撰寫任何產品程式。
- 只撰寫剛好無法通過的單元測試,不能編譯也算無法通過。
- 只撰寫剛好能通過當前測試失敗的產品程式。
讓測試程式整潔
醜陋的測試程式,如果沒有更糟的話,其實頂多是等同於沒有測試程式。問題在於,這些測試程式必須隨著產品程式的演進而改變。越混亂的測試程式就越難修改。沒有測試套件會有什麼問題 ?
- 喪失確保『程式修改後是否能按照預期般工作』的能力
- 沒辦法保證『對系統某部分的修改不會搞爛系統其它部分的程式』
大部分開發團隊都因為能保持單元測試的整潔,而獲得成功。
測試程式和產品程式一樣重要。它需要花時間思考、設計和照料,它一定得和產品測試一樣保持整潔。
測試帶來更多好處
有了測試程式,你就不會害怕修改你的程式 ! 無論你的程式架構多有擴充彈性,無論你分割設計做的多好,沒有了測試,你將不願意做改變,因為你害怕會導致其它尚未察覺的錯誤。單元測試好處:
- 保持擴充彈性
- 可維護性
- 可再利用性
整潔的測試
整潔的關鍵:- 可讀性
- 可讀性
- 還是可讀性
可讀性應具備:
- 闡明性 ( clarity )
- 簡明性 ( simplicity )
- 言簡易駭的表達力 ( density of expression )
下面的範例,呈現了建造-操作-檢查 ( BUILD-OPERATE-CHECK ) 模式:
- 建立測試資料
- 操作這些測試資料
- 檢查『操作這些測試資料以後,是否產生預期的結果』
public void testGetPageHierarchyAsXml() throws Exception {
makePages("PageOne", "PageOne.ChildOne", "PageTwo" );
submitRequest("root", "type:pages");
assertResponseIsXML();
assertResponseContains("PageOne ", "PageTwo ","ChildOne ");
}
特定領域的測試語言
建立一連串的函式和公用程式,來間接使用這些『原先程式設計師用來操作系統的 API 』,讓我們的測試程式更容易撰寫和閱讀。這種測試 API 並不是從一開始就特別設計的;是被從細節困惑的測試程式進行持續重構的過程中,演化得來的。雙重標準
測試程式碼必須足夠簡明、簡潔、和具表達力,但它不需要和產品程式碼一樣有效率。有些事,你可能永遠不會在產品環境下做,但在測試環境裡卻相當適合。這通常關係到記憶體大小或中央處理器的效能限制,但整潔的程度永遠不會被列入這個議題的討論當中。一個測試一次斷言 ( Assert )
單一的斷言原則是個不錯的指導方針,但有時更多的斷言反而更為適合,所以最好的目標應該是,測試裡的斷言數量應該盡可能地減少。一個測試一個概念
最好的法則是,在一個概念裡最小化斷言的數量,一個測試函式只測試一個概念。F.I.R.S.T.
整潔的測試,遵循由以上五個字母縮寫所構成的法則:- Fast (快速) - 測試應該要夠快。因為執行緩慢,就不會想執行,不想執行就無法及早發現問題。
- Independent (獨立) - 測試程式不應該相互依賴。
- Repeatable (可重複性) - 測試程式須可以在任何環境中重複執行。即使是在無網路的情況下。
- Self-Validating (自我驗證) - 測試程式應該輸出布林值。不應該透過查看記錄檔,來分辨。
- Timely (及時) -撰寫測試程式要及時。單元測試要恰好在使其通過的產品程式之前不久撰寫。
總結
測試程式對於一個專案的健康程度,就跟產品程式一樣重要。或許,測試程式可能更重要,因為它保存和加強了產品的可擴充彈性、可維護性、可再利用性。所以保持你的測試整潔。參考來源: Clean Code – A Handbook of Agile Software Craftsmanship by Robert C. Martin
0 意見