當我們談論Unit Test時我們在談論什么?
發表于:2018-11-12來源:鬼畜的豬作者:鬼畜的豬點擊數:
標簽:
作為一個實際寫代碼的Coder,老代碼能不碰就不碰---我舉雙手贊成,既沒有UT,邏輯又混在一起,天知道改完以后會出什么Bug。但是對于團隊來講,如果明確知道這個模塊無法測試、無
作為一個實際寫代碼的Coder,老代碼能不碰就不碰---我舉雙手贊成,既沒有UT,邏輯又混在一起,天知道改完以后會出什么Bug。
但是對于團隊來講,如果明確知道這個模塊無法
測試、無法被很好的修改,那么是時候把這部分代碼提上重構的日程了。
一. 什么是Unit Test
直譯:面向獨立單元的
測試方法。
單單這一句話我們心里有就有了疑問:什么是獨立單元,或者什么樣的代碼才算一個獨立單元?
為了回答這個問題,這里引用一下wikipedia的解釋:
Intuitively, one can view a unit as the smallest testable part of an application.
https://en.wikipedia.org/wiki/Unit_testing
我們來抓一下重點:
單元,對于不同的
編程語言,單元的定義并不相同。在面向過程的語言中(C等),單元通常被定義為一個函數(Function);而在面向對象的
編程語言中(
Java等),單元往往指一個類(也可指代具體的方法Method)。
最小的,小到無法再拆分,這個單元只做了一件事。
可測試的,這個單元應該有明確的輸入和輸出,并且在輸入確定時,我們應該能夠預測輸出的情況。
二. Unit Test要達到的目標
從
工程師的角度來看,一些童鞋可能會覺得寫Unit Test是枯燥切無意義的。工程期就那么幾天,產品經理又不停的改功能,哪有心情和時間來寫UT?
這種想法可以說對也可以說不對。首先,面對有限的時間和變動的
需求,為所有代碼寫UT是不現實的。但是不是UT就真的是枯燥且無意義的呢---也不是。至少從我的角度來看,一個項目的UT需要起到以下三個作用。
檢查出明顯的Bug
為如何使用函數(單元)提供樣例
為了重構
可能有人會說,為了檢查Bug,這不廢話嗎。。。當然我相信在座的各位對于如何在UT中檢查Bug都有兩把刷子的,而這恰好也不是我想討論的重點,但我們還是需要注意:UT并不能檢查出所有Bug,對于無法預知的用戶輸入,UT能做的只是在我們所考慮到的情況下,避免一些明顯的錯誤。但是對我們沒有考慮到的情況-----告辭。。。
這里著重討論一下后面兩點:
提供樣例,有的童鞋習慣在函數上面寫上一大段的注釋,有時候看業務代碼搞得像在讀JDK源碼。出現這種情況,我認為可能有兩個原因:
第一,代碼沒有做好拆分工作,將過多的邏輯糅合在一個類(方法)中,需要考慮的輸入情況異常多,直觀上根本無從下手來寫UT。
針對這種情況,我們應該考慮使用一些設計手法將代碼拆分成獨立的可測試的最小單元。
第二,這個單元已經是最小的了,但是它確實有許多邏輯需要處理。首先,我認為如果真的拆分成了最小單元,那需要處理的邏輯應該并不會太多,至少不需要寫一段話來描述它要做的事情。即使需要告知后來的
開發這里做了什么,一個完整的UT也比閱讀一大段文字來的實際。
為了重構
許多工程師對重構這個詞有個錯誤的印象---提到重構,我們就需要對代碼做翻天覆地的變化,甚至覺得是把以前的代碼廢棄掉重新寫。
最近閱讀了一些重構方面的書籍,有一個讓我印象深刻的觀點:重構應該要貫穿整個產品的生命周期。有因為業務擴展與變動進行重構,也有一個Bug導致需要對代碼結構進行重構。而但凡涉及到重構,我們就需要UT為我們保駕護航。
在對代碼進行重構時,UT就像一張保護網,防止我們破壞掉原有的邏輯。對于一個規模不大的核心模塊,在上線之初我們就為它編寫了詳細的UT
用例,使其滿足我們所考慮的各種情況。但是隨著業務的增長,我們可能需要對模塊內部進行優化,使其有更高的
性能。得益于我們之前的工作,每重構完一段代碼,我們都運行一遍UT,如果通過,大概率說明我們沒有“搞破壞”。當整個部分重構完成,我們需要反過來對UT進行審視,之前沒有考慮到的情況、新的代碼都需要進行覆蓋。
這樣我們的代碼保護網就會越來越牢固??梢韵胂?,如果沒有UT,我們新來的開發人員在修改老功能時是多么的緊張,因為他不知道自己也許不經意間破壞了原有的邏輯。
三. 哪些地方需要Unit Test
正如前文所述,并不是所有地方都需要寫UT,從某種意義上講,UT應該越少越好,前提是系統拆分夠精確,關注點的測試夠詳細。
針對實際的項目,我對代碼進行了一些分類:
瑣碎的代碼,例如getter/setter,toString。除非有特殊邏輯,否則為這些代碼寫UT沒有意義。
無明確意義、承上啟下的代碼,例如一些只做透傳作用的Service等。(當然,個人認為這種只做透傳的代碼應該盡量少)
原文轉自:https://www.jianshu.com/p/8e11c8fa63af