單元測試里的5個錯誤
當我***次聽說可以使用框架比如JUnit來進行單元測試的時候,我驚嘆這真是一個簡單而強大的概念。它取代了隨機測試,使你可以保存你的測試代碼,并按照需要隨時運行它們。按照我的理解,關于單元測試并沒有多少產生誤解的可能。但是過去的幾年中,我確實見過幾種或多或少不太正確的單元測試使用方式。這里按照重要程度,列出5條:
1. 跟協作邏輯一起來測試算法。如果跟協作邏輯代碼分離開來,那么算法邏輯是最容易測試的(參見選擇性單元測試 – 代價和好處)。否則在你的邏輯被測試之前,你就不得不先進行諸如通過任務隊列提交一個任務之類的工作。 任務隊列部分只會使事情變得復雜。除非你想測試任務隊列本身,否則你就應當把調用run方法時所執行的邏輯剝離開來,并對它進行單獨測試。那樣,不論是編碼還是測試都會更易于編寫和管理。
2. Mock測試太多。也許單元測試的***好處就是它迫使你編寫能夠獨立測試的代碼。也就是說,你的代碼會變得模塊化。當你把你要處理的對象的周圍的一切都模擬了,就沒有什么能迫使你去把各部分分離開來。你會發現這樣寫出的代碼,你很難在外圍添加獨立的部分 – 因為所有東西都糾纏在一起。Bill Wake最近發推說: ”真是諷刺 – 模擬測試框架越強大,你在改進設計時所感受到的壓力就會越小。”
3. 不使用斷言。有時我會看到一些測試,里面創建了一個對象,調用了一些方法,然后,就沒有然后了。也許它是在循環里這樣做的,而且在創建和調用上會有些差異。但是,卻沒有用斷言來做任何檢查。這就完全失去了意義 – 沒有檢查你的代碼是否按照預期進行工作的。當然,代碼是運行了,但是僅此而已。如果拋出了一個異常,我們會注意到它,但是卻不會驗證其它任何事情。
4. 在測試代碼中遺留print語句。我把這視為手工測試的后遺癥 – 你希望看到對象的值來判斷它們是否正確。但是所有的檢查都應當使用斷言來完成。如果單元失敗了,你也能看到它,因為這個測試也會失敗。當測試通過時,什么也不應當打印出來。在編寫測試代碼時,使用print語句有時是有用的。但是在需要用print的地方應當設置一個標志位,用來在進行測試的時候屏蔽它。
5. 查看日志信息,而不是運行結果。 還好這并不普遍,但是我卻見過一個非常有能力的開發人員這么干過。要知道,真正重要的是方法的運行結果,而不是日志中都打印了什么,因為即使代碼中有錯誤,測試也可能會通過。好了,說的很明白了。
后面3個問題都很容易規避。頭2個問題則需要付出更多努力,但是會得到良好分離的代碼。祝測試愉快!
譯文鏈接:http://www.oschina.net/translate/5-unit-testing-mistakes