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