最近,在網(wǎng)上看到過一個(gè)調(diào)查,調(diào)查的內(nèi)容是“程序員在項(xiàng)目開發(fā)中編寫單元測(cè)試的情況”。當(dāng)然,至于調(diào)查的結(jié)果,我想聰明的你已經(jīng)可以猜到了。高達(dá) 58.3% 的比例,一般情況下不寫單元測(cè)試,只有偶爾的情況才會(huì)寫寫。16.6% 的程序員從來都不寫單元測(cè)試。只有很少的一部分程序員才會(huì)在自己的代碼中進(jìn)行單元測(cè)試,并**方法測(cè)試通過??吹竭@些,你想到了什么?
01、單元測(cè)試現(xiàn)狀
雖然,這個(gè)調(diào)查可能會(huì)有些片面性,但這也基本反應(yīng)了國(guó)內(nèi)程序員的開發(fā)現(xiàn)狀,很少有程序員能夠比較認(rèn)真的去編寫單元測(cè)試。而且,甚至有的程序員根本就不知道為什么要寫單元測(cè)試(這一點(diǎn)讓我很郁悶)。他們經(jīng)常會(huì)說,公司里不是有測(cè)試人員嘛,測(cè)試應(yīng)該是他們要做的事,我們的工作只是開發(fā)(這位仁兄肯定沒有學(xué)過軟件工程)。當(dāng)然,這些并不是偶然的,正如佛經(jīng)里邊說的“因果循環(huán)”,有果必有因。那么,到底是什么原因,導(dǎo)致程序員對(duì)單元測(cè)試這么不感冒呢?
02、錯(cuò)誤認(rèn)知
通過與幾個(gè)朋友的討論,以及網(wǎng)上的調(diào)查,主要有這幾種原因,導(dǎo)致程序員對(duì)單元測(cè)試很排斥,或許說很不以為意。
不知道怎么編寫單元測(cè)試
項(xiàng)目沒有要求,所以不編寫
單元測(cè)試價(jià)值不高,完全是浪費(fèi)時(shí)間
業(yè)務(wù)邏輯比較簡(jiǎn)單,不值得編寫單元測(cè)試
不管怎樣,集成測(cè)試將會(huì)抓住所有的 bug,用不著進(jìn)行單元測(cè)試
在項(xiàng)目的前期還是盡量去編寫單元測(cè)試,但是越到項(xiàng)目的后期就越失控
為了完成編碼任務(wù),沒有足夠的時(shí)間編寫單元測(cè)試。編寫單元測(cè)試會(huì)導(dǎo)致不能按時(shí)完成編碼任務(wù),導(dǎo)致項(xiàng)目延期
很顯然,這幾種原因歸根結(jié)底,無外乎就是不了解單元測(cè)試,自認(rèn)為很聰明,自己懶不想去測(cè)試,對(duì)項(xiàng)目的時(shí)間、進(jìn)度把控不好。
03、解析原因
不知道怎么編寫單元測(cè)試
這個(gè)問題在于,還沒有接觸過單元測(cè)試,同時(shí),也沒有體會(huì)過企業(yè)級(jí)的代碼開發(fā)。不知道同時(shí)也不了解單元測(cè)試能帶給你什么。設(shè)想一下,當(dāng)你開發(fā)完一個(gè)功能模塊的時(shí)候,你如何確定你的模塊沒有 bug 呢?如果涉及到具體的業(yè)務(wù),你會(huì)執(zhí)行 debug 模式,然后一點(diǎn)一點(diǎn)的深入到代碼中去查看嗎?如果你一直都是這樣,那么你早就已經(jīng) OUT 了。趕快去了解一下單元測(cè)試的工具吧,你會(huì)收獲很大的。
項(xiàng)目沒有要求,所以不編寫
這個(gè)問題反映出了一種現(xiàn)象,同時(shí)也是一種習(xí)慣。項(xiàng)目有沒有要求,只能說明項(xiàng)目的管理上不嚴(yán)格,并不是程序員不編寫單元測(cè)試的理由。他們?cè)谝酝拈_發(fā)中,并沒有養(yǎng)成寫單元測(cè)試的好習(xí)慣。可想而知,他們的代碼質(zhì)量,我就不敢恭維了。給個(gè)建議,嘗試著寫漂亮的代碼,之所以因?yàn)槠?,是指得健康、?jiǎn)潔、健壯。當(dāng)然,完成漂亮的代碼就離不開單元測(cè)試了。
單元測(cè)試價(jià)值不高,完全是浪費(fèi)時(shí)間
這種說法其實(shí)是錯(cuò)誤的。為什么這么說呢?在日常的開發(fā)中,代碼的完工其實(shí)并不等于開發(fā)的完工。如果沒有單元測(cè)試,那么如何**代碼能夠正常運(yùn)行呢?測(cè)試人員做的只是業(yè)務(wù)上的集成測(cè)試,也就是黑盒測(cè)試,對(duì)單個(gè)的方法是沒有辦法測(cè)試的,而且,測(cè)試出的 bug 的范圍也會(huì)很廣,根本不能確定 bug 的范圍,還得去花時(shí)間來確定 bug 出在什么地方。難道這就不浪費(fèi)時(shí)間了嗎?甚至,這樣的方式,時(shí)間浪費(fèi)的會(huì)更多。
業(yè)務(wù)邏輯比較簡(jiǎn)單,不值得編寫單元測(cè)試
所謂的業(yè)務(wù)邏輯比較簡(jiǎn)單,其實(shí)是相對(duì)的。當(dāng)你對(duì)某一塊業(yè)務(wù)邏輯很熟悉的時(shí)候,你自然會(huì)認(rèn)為它很簡(jiǎn)單。然而,單元測(cè)試的必要性并不是僅僅在于測(cè)試代碼的功能是否正確,還在于,當(dāng)其他同事在了解你的業(yè)務(wù)的時(shí)候,能夠很快的通過單元測(cè)試來熟悉代碼的功能,甚至不用去讀代碼,就能夠知道它做了哪些事情。因此,寫單元測(cè)試不僅是解放了自己,更方便了別人。
項(xiàng)目前期還在盡量寫測(cè)試,到了后期就失控了
這種問題的原因在于,對(duì)項(xiàng)目進(jìn)度、項(xiàng)目中的技術(shù)點(diǎn)研究時(shí)間、人員的溝通、業(yè)務(wù)需求的熟悉程度等沒有把控好。這個(gè)問題的出現(xiàn)并不是個(gè)人的問題,而是反映了項(xiàng)目管理中存在的問題。當(dāng)然,個(gè)人的原因也存在,就是如何在有限的時(shí)間里,提高效率。這一點(diǎn)需要大家好好思考一下了。我的建議,多做計(jì)劃,根據(jù)實(shí)際情況變更計(jì)劃。多和項(xiàng)目組長(zhǎng)、組成員進(jìn)行溝通。及時(shí)反應(yīng)項(xiàng)目中存在的問題。
為了完成編碼任務(wù),沒有足夠的時(shí)間編寫單元測(cè)試
這個(gè)問題在于,程序員領(lǐng)取的任務(wù)較為復(fù)雜,或者自己的開發(fā)效率有待提高。其實(shí),開發(fā)任務(wù)是包括編碼和單元測(cè)試的。在領(lǐng)任務(wù)的時(shí)候,應(yīng)該跟據(jù)自身的能力,跟組長(zhǎng)或經(jīng)理溝通好,以便留出一定的測(cè)試時(shí)間。當(dāng)然,提高自己的編碼效率也是很有必要的。至于如何提高開發(fā)效率,網(wǎng)上有很多這樣的文章,這里就不再贅述了。
04、單元測(cè)試的重要性
測(cè)試常常是程序員十分厭倦的一個(gè)活動(dòng)。測(cè)試能給我們帶來什么?了解這些是非常重要的,測(cè)試不可能**一個(gè)程序是完全正確的,但是測(cè)試卻可以增強(qiáng)我們對(duì)程序完整的信心,測(cè)試可以讓我們相信程序做了我么期望它做的事情。測(cè)試能夠使我們盡早的發(fā)現(xiàn)程序的 bug 和不足。
一個(gè) bug 被隱藏的時(shí)間越長(zhǎng),修復(fù)這個(gè) bug 的代價(jià)就越大。在《快速軟件開發(fā)》一書中已引用了大量的研究數(shù)據(jù)指出:之后才修改一個(gè) bug 的代價(jià)是在 bug 產(chǎn)生時(shí)修改它的代價(jià)的10倍。
當(dāng)然,我們主要討論的是單元測(cè)試。單元測(cè)試是一個(gè)方法層面上的測(cè)試,也是最細(xì)粒度的測(cè)試。用于測(cè)試一個(gè)類的每一個(gè)方法都已經(jīng)滿足了方法的功能要求。在開發(fā)中,對(duì)于自己開發(fā)的模塊,只有在通過單元測(cè)試之后,才能提交到 SVN 庫 或者 Git 庫。
05、測(cè)試的應(yīng)用
正是由于測(cè)試在開發(fā)中的重要地位,才會(huì)在IT界刮起了 TDD 的旋風(fēng)。TDD,也就是測(cè)試驅(qū)動(dòng)開發(fā)模式。它旨在強(qiáng)調(diào)在開發(fā)功能代碼之前,先編寫測(cè)試代碼。也就是說在明確要開發(fā)某個(gè)功能后,首先思考如何對(duì)這個(gè)功能進(jìn)行測(cè)試,并完成測(cè)試代碼的編寫,然后編寫相關(guān)的代碼滿足這些測(cè)試用例。然后循環(huán)進(jìn)行添加其他功能,直到完成全部功能的開發(fā)。
06、測(cè)試工具
JUnit 在日常開發(fā)中還是很常用的,而且 Java 的各種 IDE (Eclipse、MyEclipse、IntelliJ IDEA)都集成了 JUnit 的組件。當(dāng)然,自己添加插件也是很方便的。JUnit 框架是 Java 語言單元測(cè)試當(dāng)前的一站式解決方案。這個(gè)框架值得稱贊,因?yàn)樗褱y(cè)試驅(qū)動(dòng)的開發(fā)思想介紹給 Java 開發(fā)人員并教給他們?nèi)绾斡行У鼐帉憜卧獪y(cè)試。
TestNG,即Testing Next Generation,下一代測(cè)試技術(shù)。是根據(jù)JUnit和NUnit思想,采用 jdk 的 annotation 技術(shù)來強(qiáng)化測(cè)試功能并借助XML 文件強(qiáng)化測(cè)試組織結(jié)構(gòu)而構(gòu)建的測(cè)試框架。TestNG 的強(qiáng)大之處還在于不僅可以用來做單元測(cè)試,還可以用來做集成測(cè)試。
俗話說,一屋不掃,何以掃天下。開發(fā)中,我們自己的代碼都不能**功能的正確性,那么還有什么效率可言呢?做再多的任務(wù),寫再多的代碼也只不過是在搭雞窩,做著機(jī)器一樣的重復(fù)的工作。IT界有一個(gè)原則,DRY原則 —— Don't Repeat Yourself !只有通過對(duì)自己的工作不斷的檢查,不斷的測(cè)試,才能不斷的突破,不斷的脫穎而出,當(dāng)然,你才能不斷的提高。