單元測試



我們寫它是為了確保程式能夠「順利運作」。




TDD 的三大法則

  • 在撰寫一個單元測試 (測試失敗的單元測試)前,不可以撰寫任何產品程式。
  • 只撰寫剛好無法通過的單元測試,不能編譯也算無法通過。
  • 只撰寫剛好能通過當前測試失敗的產品程式。

讓測試程式整潔

醜陋的測試程式,如果沒有更糟的話,其實頂多是等同於沒有測試程式。問題在於,這些測試程式必須隨著產品程式的演進而改變。越混亂的測試程式就越難修改。
沒有測試套件會有什麼問題 ?
  • 喪失確保『程式修改後是否能按照預期般工作』的能力
  • 沒辦法保證『對系統某部分的修改不會搞爛系統其它部分的程式』
當非計畫中的缺陷增加時,他們的產品維護整理他們的產品程式,因為害怕改變程式,所以導致了更嚴重的缺陷。
大部分開發團隊都因為能保持單元測試的整潔,而獲得成功。
測試程式和產品程式一樣重要。它需要花時間思考、設計和照料,它一定得和產品測試一樣保持整潔。

測試帶來更多好處

有了測試程式,你就不會害怕修改你的程式 ! 無論你的程式架構多有擴充彈性,無論你分割設計做的多好,沒有了測試,你將不願意做改變,因為你害怕會導致其它尚未察覺的錯誤。

單元測試好處:
  • 保持擴充彈性
  • 可維護性
  • 可再利用性
事實上,你可以毫無畏懼地改善系統架構和設計 ! 涵蓋產品程式的一套自動化單元測試,是讓你盡可能維護產品設計和架構整潔的唯一關鍵。因為測試讓修改變為可行。

整潔的測試

整潔的關鍵:
  • 可讀性
  • 可讀性
  • 還是可讀性
在單元測試裡可能比產品程式還重要,盡可能地用最少的表達式來產生最具豐富的說明。
可讀性應具備:
  • 闡明性 ( clarity )
  • 簡明性 ( simplicity )
  • 言簡易駭的表達力 ( density of expression )

下面的範例,呈現了建造-操作-檢查 ( BUILD-OPERATE-CHECK ) 模式:
  1. 建立測試資料
  2. 操作這些測試資料
  3. 檢查『操作這些測試資料以後,是否產生預期的結果』

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

  • Share:

You Might Also Like

0 意見