March 09 09:35~10:55
圖片來源wikipedia。
介紹完五個測試的Code Smells,接下來輪到Behavior Smells,今天先介紹Assertion Roulette。Roulette是輪盤的意思,Assertion Roulette是指一個test method有好幾個assertion,當測試失敗的時候,不容易知道是由哪一個assertion所引起的,就好像輪盤上的球一樣,不知道會轉到什麼號碼上面。
有寫過自動化測試案例的鄉民們看到這裡一定會覺得很奇怪:「就算一個test method有好幾個assertion,當測試錯誤的時候只要看程式碼就知道錯在哪一個assertion上面啊,怎麼會有不容易知道是哪一個assertion引起測試錯誤的問題?」
如果測試案例都只跑在開發人員的IDE上面,當然可以直接點選xUnit工具就跳到發生錯誤的哪一個assertion上面。但是,在一個test method有多個assertion的情況,你通常需要把整個test method都讀過一遍,至少也要從頭讀到發生錯誤的哪一行,才可以試著判斷錯誤發生的原因。如果測試案例是跑在持續整合系統上,這種Assertion Roulette壞味道所造成的問題就會更大,更不容易找出測試錯誤發生的原因。
***
《xUnit Test Patterns: Refactoring Test Code》書中提到導致這個壞味道的情況有:
- Eager Test:單一測試案例試圖驗證太多功能,這種情況很有可能是開發人員想要減少測試案例的心態作祟,或是想要共用測試環境,所以幹脆把一堆assertion全都寫在同一個test method裡面。因此有人建議一個test method應該只有一個assertion,不過這樣似乎又過於極端,矯枉過正。
Teddy覺得《Clean Code》書中的建議,「一個test method測試一種概念」應該是比較好的方法,鄉民們可以參考一下。
- Missing Assertion Message:就算是已經遵循「一個test method測試一種概念」,有時候多個assertion的內容都很類似,當測試失敗時還是不容易快速得知哪一個assertion錯誤。 例如,假設test method有三個assertTrue(),如果沒有幫每一個assertTrue()加上assertion message,當測試失敗時不容易馬上看出是哪一個assertion發生錯誤。
***
Teddy以前開發軟體的時候經常犯Assertion Roulette這個毛病,為了貪快、減少寫測試案例的時間,不知不覺中就在一個test method裡面寫了一大串assertion。這種測試案例有時候反而比較像整合測試,或是state-based testing,用來驗證一個物件的一連串狀態轉換。當其中一個assertion失敗的時候,也只能乖乖慢慢地檢察,看錯誤發生的原因啊。
***
友藏內心獨白:有沒有越看越覺得測試案例需要重構啊?
沒有留言:
張貼留言