轉(zhuǎn)帖|行業(yè)資訊|編輯:蔣永|2016-09-26 10:15:01.000|閱讀 230 次
概述:本文從單元測(cè)試的定義和必要性講到但其中一些重要概念,單元測(cè)試不僅是測(cè)試人員的工作,開(kāi)發(fā)人員也應(yīng)該具備相關(guān)技能知識(shí)。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
一、什么是單元測(cè)試?
為了測(cè)試某個(gè)類中的某一個(gè)方法能否正常工作,而寫的測(cè)試代碼。
單元的定義:代碼中可度量的最小單元(函數(shù)/方法);
是否正常工作:不同的輸入對(duì)應(yīng)的輸出是否與預(yù)期一致。
二、單元測(cè)試有必要嗎?
1 對(duì)是否有必要寫單元測(cè)試的疑惑
沒(méi)有價(jià)值:不做單元測(cè)試一樣地開(kāi)發(fā),并沒(méi)有什么問(wèn)題(解釋:);
浪費(fèi)時(shí)間:寫單元測(cè)試需要大量的時(shí)間,還不如寫具體的實(shí)現(xiàn),具體的實(shí)現(xiàn)能看到明顯的效果,但單元測(cè)試可能耽誤正常的迭代進(jìn)度;
無(wú)法測(cè)試:比如無(wú)返回值的方法、UI等;
2 不寫單元測(cè)試會(huì)存在的一些問(wèn)題:
要有足夠的耐心:改一個(gè)參數(shù),需要重新運(yùn)行一遍程序;
沒(méi)有足夠的自信:每次提測(cè)和發(fā)布,心驚膽戰(zhàn),對(duì)自己寫的程序沒(méi)有信心;
要有足夠的時(shí)間:必須要等到測(cè)試發(fā)現(xiàn)bug后才去改善;
bug太多,程序很難穩(wěn)定:可以看下你自己開(kāi)發(fā)的應(yīng)用,如果有做異常采集,上報(bào)的大多數(shù)異常問(wèn)題,都是因?yàn)槌绦驔](méi)有做好容錯(cuò)導(dǎo)致的,比如空指針、被除數(shù)為0、數(shù)組越界等;
3 單元測(cè)試能夠解決的問(wèn)題
效率:如果沒(méi)有單元測(cè)試就必須把程序運(yùn)行起來(lái)測(cè)試;運(yùn)行一次單元測(cè)試,最多幾分鐘,cover得比較全面,相比于執(zhí)行程序,效率高很多很多;
質(zhì)量:對(duì)于每個(gè)最小單元,針對(duì)不同輸入對(duì)應(yīng)的輸出有與預(yù)期做對(duì)比,能夠減少因?yàn)閰?shù)導(dǎo)致的異常問(wèn)題,同時(shí)提測(cè)和發(fā)布版本的時(shí)候,有信心;
提升設(shè)計(jì)能力:為了每個(gè)單元都可測(cè),需要將每個(gè)方法拆得盡量獨(dú)立,如果不拆得足夠獨(dú)立,就無(wú)法測(cè)試,間接可以提高程序設(shè)計(jì)能力;
代碼重用:跑過(guò)單元測(cè)試的代碼,穩(wěn)定性能夠得到保證,可以在其它項(xiàng)目或者項(xiàng)目重構(gòu)時(shí)重復(fù)利用;
縮短測(cè)試周期:程序自測(cè)(開(kāi)發(fā)人員寫單元測(cè)試、手動(dòng)跑基本功能、跑monkey都屬于自測(cè))可以提高產(chǎn)品提測(cè)的質(zhì)量,避免返工;同時(shí)核心功能的穩(wěn)定有助于縮短黑盒測(cè)試的周期。三、哪些可以做單元測(cè)試?
任何方法都可以做單元測(cè)試;
從必要性來(lái)講,針對(duì)UI相關(guān)的做單元測(cè)試必要性不大,并且很多東西需要主觀判斷;所以只針對(duì)Model和Control層做測(cè)試;
私有方法同樣可以測(cè)試(反射,或者在測(cè)試時(shí)改為public方法),但非public方法是這個(gè)類的實(shí)現(xiàn)細(xì)節(jié),其它類并不關(guān)心,不用測(cè)試;
四、關(guān)于單元測(cè)試的一些概念
1 分類
按測(cè)試內(nèi)容分:
功能測(cè)試:和UI無(wú)關(guān),測(cè)試IO操作、算法、流程等;
UI測(cè)試:測(cè)試UI交互邏輯,比如點(diǎn)擊、登陸等;
按是否依賴設(shè)備分
不依賴Android設(shè)備,只需要運(yùn)行在JVM上的;→真正的單元測(cè)試,執(zhí)行快,效率高;
依賴Android設(shè)備(模擬器/真機(jī)),需要程序運(yùn)行時(shí)狀態(tài)信息的,比如獲取磁盤空間、四大組件的上下文信息、異步任務(wù)、消息傳遞等;→其實(shí)是集成測(cè)試,需要運(yùn)行整個(gè)程序,執(zhí)行慢,效率低;
2 測(cè)試框架
如果沒(méi)有框架該如何做單元測(cè)試
自己寫程序進(jìn)行邏輯判斷(麻煩、加入測(cè)試程序有bug怎么辦?);
在console中觀察測(cè)試結(jié)果;
測(cè)試框架能夠提高測(cè)試效率
JUnit、Instrumentation test、Espresso、UI Automator、Robolectric、Appium、Robotium
JUnit:能夠直接在PC上執(zhí)行;
AndroidTest:需要依賴Android設(shè)備;
Robolectric:在不需要依賴Android環(huán)境的前提下,實(shí)現(xiàn)在PC上直接運(yùn)行Android的單元測(cè)試;
Robotium:第三方UI測(cè)試框架;
Espresso:Google推出的UI測(cè)試框架;
UI Automator:流程的UI測(cè)試框架;
3 覆蓋率
衡量單元測(cè)試質(zhì)量,通過(guò)覆蓋率測(cè)試,可以明確知道哪部分代碼已經(jīng)被單元測(cè)試覆蓋到,哪部分沒(méi)有進(jìn)行單元測(cè)試;常用的單元測(cè)試插件有Emma、JaCoCo;
4 JUnit框架中的常用方法
setUp/@Before:在每個(gè)單元測(cè)試方法執(zhí)行之前調(diào)用;
tearDown/@After:在每個(gè)單元測(cè)試方法執(zhí)行后調(diào)用;
setUpBeforeClass/@BeforeClass:在每個(gè)單元測(cè)試類運(yùn)行前調(diào)用;
tearDownAfterClass/@AfterClass:在每個(gè)單元測(cè)試類運(yùn)行完成后調(diào)用。
Junit3中每個(gè)測(cè)試方法必須以test打頭,Junit4中增加了注解,對(duì)方法名沒(méi)有要求,@Test就可以。
5 一個(gè)單元測(cè)試的流程
setUp:設(shè)置前提條件,比如初始化;
執(zhí)行動(dòng)作:調(diào)用被測(cè)方法,并得到返回結(jié)果;
驗(yàn)證結(jié)果:驗(yàn)證獲取的結(jié)果和預(yù)期是否一致;
6 關(guān)于Mock
在寫單元測(cè)試的過(guò)程中,我們可能會(huì)發(fā)現(xiàn)需要和系統(tǒng)內(nèi)的某個(gè)模塊或系統(tǒng)外某個(gè)實(shí)體交互,而這些模塊或?qū)嶓w在您做單元測(cè)試的時(shí)候可能并不存在,比如您遇到了數(shù)據(jù)庫(kù)、遇到了驅(qū)動(dòng)程序等。這時(shí)開(kāi)發(fā)人員就需要使用mock技術(shù)來(lái)完成單元測(cè)試。
mock就是創(chuàng)建一個(gè)類的虛假的對(duì)象,在測(cè)試環(huán)境中,用來(lái)替換掉真實(shí)的對(duì)象,以達(dá)到兩個(gè)目的:
驗(yàn)證這個(gè)對(duì)象的某些方法的調(diào)用情況,調(diào)用了多少次,參數(shù)是什么等等;
指定這個(gè)對(duì)象的某些方法的行為,返回特定的值,或者是執(zhí)行特定的動(dòng)作。
要使用mock技術(shù),就需要使用mock框架,Mockito和Jmockit是android平臺(tái)兩個(gè)常用的mock框架,其中Mockito不能mock static method和final class、final method,但Jmockit可以。
7 依賴注入在單元測(cè)試中的使用
上文中提到的Mock技術(shù)就是創(chuàng)建一個(gè)類的虛假的對(duì)象,在測(cè)試環(huán)境中用來(lái)替換掉真實(shí)的對(duì)象,但如何在測(cè)試環(huán)境下,將某個(gè)類替換成mock的對(duì)象就需要使 用到依賴注入了,他的基本理念是,某一個(gè)類(比如說(shuō)DataActivity),用到的內(nèi)部對(duì)象(比如說(shuō)DataModel)的創(chuàng)建過(guò)程不在 DataActivity內(nèi)部去new,而是由外部去創(chuàng)建好DataModel的實(shí)例,然后通過(guò)某種方式set給DataActivity。這種模式應(yīng)用 是非常廣泛的,尤其是在測(cè)試的時(shí)候。常見(jiàn)的依賴注入框架有:Roboguice、Dagger、Dagger2。
在實(shí)際寫單元測(cè)試的過(guò)程中,mock技術(shù)會(huì)經(jīng)常用到,所有非常有必要熟悉其中一種依賴注入框架,關(guān)于依賴注入的詳細(xì)解釋可以參見(jiàn)公共技術(shù)點(diǎn)之依賴注入。
五、單元測(cè)試集成到Jenkins
Jenkins上不需要任何改動(dòng),執(zhí)行現(xiàn)有的gradle命令會(huì)自動(dòng)執(zhí)行單元測(cè)試,測(cè)試不通過(guò)會(huì)報(bào)編譯錯(cuò)誤;
六、說(shuō)明
不要指望對(duì)某個(gè)方法的單元測(cè)試一次能夠?qū)懙米銐蛲昝溃瑔?元測(cè)試也是需要持續(xù)迭代的(比如入?yún)⒖紤]得不全面、單元測(cè)試粒度沒(méi)有足夠細(xì)等);
并不是所有針對(duì)源碼級(jí)別寫的測(cè)試代碼都叫單元測(cè)試,針對(duì)具體某一個(gè)方法的測(cè)試叫單元測(cè)試,涉及到UI層面、必須要運(yùn)行程序才能跑的測(cè)試叫集成測(cè)試,比如很多基于android平臺(tái)的第三方UI測(cè)試框架;
test和androidTest文件夾的區(qū)別:如果你是用Android Studio做開(kāi)發(fā),在創(chuàng)建工程的時(shí)候,src文件夾下會(huì)同時(shí)生成三個(gè)文件夾main、test、androidTest,其中test和androidTest是專門針對(duì)源碼級(jí)別的白盒測(cè)試的,test 文件夾用于寫不依賴設(shè)備環(huán)境的單元測(cè)試,即直接在PC上即可運(yùn)行的測(cè)試,特點(diǎn)是測(cè)試效率高;androidTest文件夾用于寫需要在設(shè)備上才能運(yùn)行的測(cè) 試,比如測(cè)試依賴android API和設(shè)備環(huán)境的時(shí)候(context、IO操作、UI測(cè)試等),就需要在這個(gè)文件夾下面寫單元測(cè)試了,其特點(diǎn)是必須要編譯生成APK后才能測(cè)試,效率 低;
測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)的這種軟件開(kāi)發(fā)方法提倡先寫測(cè)試程序,再才編碼實(shí)現(xiàn)具體的功能;
本文轉(zhuǎn)自()
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn