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