無單測、不編碼——寫單元測試的重要性
作為一個開發(fā)人員,很多人很少寫單元測試,甚至不寫單元測試。
總結(jié)一下開發(fā)人員不寫單測的原因無非有以下幾種:
- 認為寫單測浪費時間。
- 認為測試不應該是開發(fā)人員來做的。
- 自信我寫的代碼沒有問題,不需要單測。
- 不知道單測的重要性。
- 不知道單測的好處。
那么針對以上這幾種觀點,今天就逐個分析一下。到底單元測試有沒有那么重要。
一、單元測試真的浪費時間嗎?
在業(yè)務(wù)高速發(fā)展的今天,很多時候項目來的時候要的都很急。好像要是我不把這個功能在幾天之內(nèi)搞完整個公司都要倒閉了一樣。所以,很多開發(fā)人員都把主要的時間用在寫業(yè)務(wù)邏輯代碼上。很多人都是有時間的時候才會寫一些簡單的單元測試代碼,如果項目比較忙的話就不寫單元測試。
很多程序員的項目都是這樣完成的:
寫代碼---->集成測試---->改bug---->集成測試---->預發(fā)布測試---->改bug---->正式發(fā)布---->發(fā)生故障---->改bug---->發(fā)布---->改bug---->....
可以看到,改bug過程貫穿著整個軟件的生命周期。改bug很多人都知道怎么改,就是要先定位問題,然后再解決問題。往往定位問題都是比較復雜的,一般都需要很長的時間。
如果有了單元測試可能就會節(jié)省很多時間,通過單測可以減少很多bug的發(fā)生,也能幫助我們快速的定位問題。只要在集成測試之前做好單元測試。在通過單元測試之后,我們就可以認為這部分代碼是可靠的,那么就可以放心的進行項目集成。
當然,有了單元測試,并不能保證代碼不出現(xiàn)bug。但是,單元測試可以在軟件開發(fā)過程的早期就能發(fā)現(xiàn)問題。只要單測的測試用例足夠好,那么就可以避免很多低級錯誤。
那么,為什么還是很多人認為單元測試浪費時間呢,個人分析原因可能是這樣的。開發(fā)人員認為我的時間就應該用來寫業(yè)務(wù)邏輯代碼。項目出現(xiàn)了bug,我也應該用我的時間來解決這個bug。他們認為我的時間花費在這件事上我是認可的,所以我的時間就不叫浪費。歸根結(jié)底,他們就是沒有意識到單元測試所帶來的好處。一旦他們發(fā)現(xiàn),通過單元測試可以讓我更早的發(fā)現(xiàn)問題等等好處,那么他們也會認可把時間花費在寫單測上。
在這里,可以先下一個結(jié)論:好的單測不僅不會浪費時間,還會大大節(jié)省我們的時間。至于為什么會節(jié)省時間以及什么叫好的單測會在后面介紹。
二、單元測試應不應該開發(fā)人員來寫
這里暫不分析到底應不應該有單獨的測試人員,這是一個頗有爭議的話題(一部分人認為,開發(fā)就應該是全棧的。還有一部分人認為開發(fā)就應該只關(guān)注業(yè)務(wù)寫業(yè)務(wù)代碼)。這里只分析單元測試到底應該由誰來做。有人認為,單元測試也是測試的一種手段,應該交給專門的QA去做。也有人認為單元測試應該是開發(fā)人員來寫,那么,單元測試到底應不應該開發(fā)人員寫呢?
單元測試必須由最熟悉代碼的人來寫。這是好的單元測試的標準之一。那么還能有誰比寫代碼的人更了解代碼呢?代碼的作者最了解代碼的目的、特點和實現(xiàn)的局限性。所以,寫單元測試沒有比作者更適合的人選了。單獨的測試人員進行單元測試,往往工作量大,周期長,耗費巨大,其結(jié)果事倍功半。軟件的開發(fā)者總是應當負責程序的單個單元的測試,保證每個單元能夠完成設(shè)計的功能,其實在很多情況下,開發(fā)者也應進行集成測試。
我的觀點以為,開發(fā)人員寫了一個函數(shù),就要對這個函數(shù)負責,就有義務(wù)保證這個函數(shù)可以準確的執(zhí)行。單測便是一個很好的手段。所以,如果要寫單測,就應該開發(fā)人員自己來寫。
三、我很自信,我還需要單測嗎?
有人能寫出***無缺的代碼么?答案是否定的!
我認為程序員都是天生驕傲的。雖然程序員往往都會說:在我機器上明明是好的呀,是不是你用的方式不對呀。但是,好的程序員應該在說完這句話之后會偷偷的去排查問題。
寫代碼不是可以一蹴而就的,必須經(jīng)過各種各樣的測試,單元測試只是其中一種。
所以,無論你是一個多么天生驕傲的程序員,你都不是神!所以,你也需要單測。
四、單測真的有那么重要么?
很多程序員寧愿把時間花費在寫業(yè)務(wù)邏輯代碼上,他們多數(shù)是有時間的時候才會寫一些簡單的單元測試代碼,如果項目比較忙的話就不寫單元測試。據(jù)我所知,只有少數(shù)的公司會要求項目上線必須達到一定百分比的代碼覆蓋率(軟件測試中的一種度量,描述程式中源代碼被測試的比例和程度),大多數(shù)公司都不是很重視這一項,所有,很多人就不太重視單元測試。但是,很多發(fā)生故障的經(jīng)驗告訴我們,很多問題是可以通過單元測試避免的。
其實單元測試的重要性很簡單,就是一句話:不寫單元測試,你怎么知道你的代碼寫的對不對?沒有足夠豐富的測試用例,你怎么知道用戶會怎么使用到你的代碼,你又怎么會知道你的代碼應該怎么被執(zhí)行呢?
所以,單元測試很重要。和寫代碼一樣重要。無單測,不編碼!
五、單元測試有哪些好處?
前面說了這么多,其實以上這些問題都有一個最最根源的問題,那就是很多程序員不寫單測的最最根本原因是他們根本不知道寫單測和不寫單測的區(qū)別。不知道寫了單測能帶來好處。所以他們會認為寫單測是浪費時間,所以他們才會認為單測不應該是由我來寫,所以他們才會認為我不需要寫單測。
那么,單元測試到底能帶來哪些好處呢?
J.Timothy King寫過一篇關(guān)于先寫單元測試有哪些好處的文章:Twelve Benefits of Writing Unit Tests First(先寫單元測試的十二個好處),這里挑其中幾個顯而易見和比較突出的好處介紹一下。
1. 減少bug
單元測試的目的就是通過足夠準確的測試用例保證代碼邏輯是正確。所以,在單測過程中,必然可以解決一些bug。因為,一旦某條測試用例沒有通過,那么我們就會修改被測試的代碼來保證能夠通過測試。
2. 減少修復bug的成本
一般解決bug的思路都是先通過各種手段定位問題,然后在解決問題。定位問題的時候如果沒有單元測試,就只能通過debug的方式一點一點的追蹤代碼。解決問題的時候更是需要想盡各種方法來重現(xiàn)問題,然后改代碼,改了代碼之后在集成測試。
因為單元規(guī)模較小,復雜性較低,因而發(fā)現(xiàn)錯誤后容易隔離和定位,有利于調(diào)試工作。
3. 幫助重構(gòu),提高重構(gòu)的成功率
我相信,對一個程序員來說最痛苦的事就是修改別人的代碼。有時候,一個很大的系統(tǒng)會導致很多人不敢改,因為他不知道改了一個地方會不會導致其他地方出錯??梢?,一旦有了單元測試,開發(fā)人員可以很方便的重構(gòu)代碼,只要在重構(gòu)之后跑一遍單元測試就可以知道是不是把代碼“改壞了”
4. 提高開發(fā)速度
不寫單測也許能讓開發(fā)速度更快,但是無法保證自己寫出來的代碼真的可以正確的執(zhí)行。寫單測可以較少很多后期解決bug的時間。也能讓我們放心的使用自己寫出來的代碼。整體提高開發(fā)速度。
五、后記
據(jù)我說知,在facebook是沒有QA的,他們的所有代碼都是通過單元測試來保證能夠正確執(zhí)行的。在google也很重視單測,國外這樣的大公司都會要求單測的代碼覆蓋率達到一個高的水平,否則是絕對不會允許代碼發(fā)不到線上的。
所以,通過這樣一篇文章,希望讀者可以重視單元測試,并在實際項目中運用起來。但是,也請記得,單測只能在一定程度上減少bug的發(fā)生,并不是寫了單測就不會在發(fā)生問題。
無單測,不編碼!
【本文是51CTO專欄作者Hollis的原創(chuàng)文章,轉(zhuǎn)載聯(lián)系作者本人獲取授權(quán)】