可以想象,當你投入大量精力,使用Robolectric、Mockito等框架模擬出一個將數據庫數據發往后臺的單元測試并通過測試用例后,用戶卻因為切換網絡等小概率場景觸發了Bug,你會不會感嘆我要這單測有何用?類似Android這種終端環境,其邊際收益遞減的臨界點往往更容易達到,引入單元測試猶需謹慎。
結合上面的分析,哪些場景不適合做單元測試已經顯而易見了,When is unit testing inappropriate or unnecessary? [duplicate]中一個高票回答做了如下總結:
- The code has no branches is trivial. A getter that returns 0 doesn't need to be tested, and changes will be covered by tests for its consumers.
在Definition of brittle unit tests中也有詳細總結,都有一定參考價值。
此外,有了適合單元測試的場景并不代表就有適合單元測試的代碼。在TDD模式中,測試先于開發,所以開發部分的代碼接口往往需要經過良好的設計和定義,最好能解耦各個模塊,如此開發代碼將能夠完美匹配測試代碼。但這種開發模式往往對開發經驗、設計能力要求很高。能都達成此境界的已經是TDD的行家了。然而事實是對于沒有單元測試經驗的開發人員而言,往往沒有意識到自己寫的代碼“不可測試”。以下面偽代碼為例:
object processObject(Object object) {
if (object == objectA) {
log.i('error 1 ....')
return object;
}
if (object == objectB) {
log.i('error 1 ....')
return object;
}
.....
return object;
}
開發人員在Debug的時候,能根據log信息快速定位問題,但對于測試來說就十分不友好了:返回值都一樣。如果想要領會單元測試的優越性,短期的鎮痛與適應似乎是不可避免的。
本文沒有討論TDD的各種優勢,也沒有討論單元測試的最佳實踐,是個人的一些總結,討論的是單元測試的一些局限之處,或許有不足、有遺漏,又或者完全錯誤,歡迎拍磚。譬如,在stackoverflow上有一個關于是否值得做單元測試的問題就因為其爭議性而被關閉回答,而又因為有其存在的歷史意義而被一直鎖定(locked)
原文轉自:https://www.jianshu.com/p/1980c944e31c