介紹怎么做單元測試的書很多,這里主要解答:為什么單元測試。
客觀來說,單元測試和使用版本控制系統(GIT,SVN)是一樣重要的。
為什么單元測試如此重要,但你卻感受不到。首先要知道,代碼的終極目標有兩個,第一個是實現需求,第二個是提高代碼質量和可維護性。
單元測試是為了提高代碼質量和可維護性,是實現代碼的第二個目標的一種方法。(注:代碼的可維護性是指增加一個新功能,或改變現有功能的成本,成本越低,可維護性即越高。)
01、Hello word
任何一個偉大的程序員都是從最簡單的代碼開始寫起的,假設你的第一個程序是Hello World,任何一個語言實現這個程序都只需要不到5行代碼。這個程序需要單元測試嗎?
我們看看這個程序是否實現了軟件的兩個目標:
1.需求很簡單,輸出Hello World,這個程序完全滿足需求。
2.只有5行代碼的“軟件”無論是代碼質量,還是可維護性,都相當高,你想要把Hello改成Hi真的很輕松。
既然我們已經實現了代碼的目標,要不要使用單元測試是無所謂的,同樣這么簡單的代碼也沒人會使用GIT或SVN。
代碼量:5行
02、立簡單計算器
接下來你寫了一個相對更復雜的程序,一個簡單計算器。這個程序實現了數字的加減乘除,整個程序共寫了大概50行代碼。這個程序需要單元測試嗎?
1.需求是對數字進行加減乘除,這個程序滿足了需求。
2.你的代碼風格很好(你已經了解到代碼風格很重要),你使用了縮進,良好的變量命名,邏輯也清晰,代碼的質量和可維護性仍然相當高,如果你想增加一個“求x的平方”功能,你輕而易舉就可以做到。
這個時候讓你去寫單元測試,你仍然會覺得那純粹是浪費時間。
代碼量:50行
03、圖書管理系統
你想要做一個真正的實用系統,給學校開發一個圖書管理系統。 你相信這個系統的代碼量比起計算器會很多(可能會有1000行)。你從書上看到有這樣一些方法可以簡化你的開發工作:
1.工具庫(類似你家里的工具箱),使用工具庫帶來的好處是非常明顯的,假如你要實現“返回一個數字數組中的最大值”,你只需要使用某個工具庫的Max()函數,只需要1行代碼,而不是10行代碼自己實現。
2.MVC框架,雖然比起工具庫更復雜,需要花更多時間學習,但MVC框架帶來的好處也非常明顯,輕而易舉調用數據庫(Model),實現簡單的UI界面(View),實現了類似“書名為空的書不允許添加到數據庫”的一些邏輯(Controller)。
你最終很好的實現了這個系統,基于MVC模型,你的代碼被很好的分割成了很多小的獨立的模塊:4個Controller,2個Model,4個View。并且在工具庫的幫助下,代碼量得到了縮減,每個模塊大概只有50行代碼(等同于一個簡單計算器的代碼量)。這個系統需要單元測試嗎?
1.你實現了對圖書的添加、刪除、修改、借閱,你很好的滿足了需求(校長表揚了你)。 2.得益于框架與庫的使用,你的代碼被很好的模塊化了,每個模塊都像一個“簡單計算器”那樣簡單,增加新功能,或修改現有功能似乎也沒有什么大麻煩,雖然會出現一些小bug,但很快就修復了,代碼質量和可維護性都比較高。
既然你又實現了代碼的目標——“完成需求,高代碼質量和可維護性”,那好像也沒“單元測試”什么事,畢竟寫它要浪費額外的功夫,而且也沒感覺到有多少好處。
代碼量:500行
04、大型庫存管理系統
你被一家IT公司雇傭了,你通過了面試,進入了一個即將開啟的項目——為一家大的電商公司做一個庫存管理系統。
項目初期一切都很順利,技術上和你做過的圖書管理系統差不多。首先你了解了客戶的需求,然后根據他們的需求,使用你已經掌握的MVC框架和一些庫,實現了他們的需求。
你寫了30個Controller, 50個Model,50個View,每個模塊的代碼都達到了大概150行,總代碼達到了驚人的20000行!
你覺得自己很了不起,能hold住這么多代碼,這完全是得益于你的高智商,以及工作努力。客戶很滿意,老板也很滿意,你的自我感覺也很不錯。
并且你發現了比單元測試更好的東西,面向對象編程(OOP),或函數式編程(FP),無論是哪一種,你發現你可以把一個模塊里的150行堆砌在一起的代碼再提取成1個對象的15種方法,或者15個獨立的函數(具體怎么提取,你得看相關的書籍),OOP或FP像MVC模型一樣,成功的把你的代碼分割成了更小的組成部分,每個方法或函數里代碼都只有10行左右,你幾乎回到了“Hello World”時代。
你需要單元測試嗎?(你能保證你的系統沒有BUG嗎?)這個復雜系統是由1950個函數和方法組成,如果想要確定系統整體沒有BUG,就等同于確定組成這個系統的1950個函數和方法沒有BUG。
而單元測試就是做這個事情的,顯而易見,如果你寫了單元測試,并且每個函數都通過了,你就可以驕傲的說:這個系統沒有BUG!(當然這是代碼的角度,而非功能和產品的角度)
05、結論
雖然,從絕對的角度說,單元測試很重要,但是,從相對的角度來講,小的代碼量,簡單固定的需求,個人開發,一錘子買賣等等都會讓單元測試顯得不那么重要,并且你一直開發的很舒服,這就是為什么有的人感受不到單元測試的重要性(這種情況下的確也許不用寫單元測試)。
記住,單元測試的威力更多不是體現在新代碼的編寫上,而是對已有代碼的更改。但程序員的智慧是有限的,系統的復雜度卻是無限的,隨著更大挑戰的到來,當系統的復雜度超過了你的邏輯,記憶能力,你必須依靠別的工具來幫助你減少問題。
如果你現在在做一個較大的項目,這個項目的需求很多,所以你一直在開發,你遇到了這樣的痛苦狀況:
1.客戶總能在使用中找出BUG;
2.每次代碼的改動,都會導致一些意想不到的BUG出現。這個時候,單元測試可以挽救你。