引言
經(jīng)常有人問(wèn)這樣的問(wèn)題:“我們在做單元測試,那測試覆蓋率要到多少才行?”。答案其實(shí)很簡(jiǎn)答,“作為指標的測試覆蓋率都是沒(méi)有用處的。”
Martin Fowler(重構那本書(shū)的作者)曾經(jīng)寫(xiě)過(guò)一篇博客來(lái)討論這個(gè)問(wèn)題,他指出:把測試覆蓋作為質(zhì)量目標沒(méi)有任何意義,而我們應該把它作為一種發(fā)現未被測試覆蓋的代碼的手段。
代碼覆蓋率的意義
分析未覆蓋部分的代碼,從而反推在前期測試設計是否充分,沒(méi)有覆蓋到的代碼是否是測試設計的盲點(diǎn),為什么沒(méi)有考慮到?需求/設計不夠清晰,測試設計的理解有誤,工程方法應用后的造成的策略性放棄等等,之后進(jìn)行補充測試用例設計。
檢測出程序中的廢代碼,可以逆向反推在代碼設計中思維混亂點(diǎn),提醒設計/開(kāi)發(fā)人員理清代碼邏輯關(guān)系,提升代碼質(zhì)量。
代碼覆蓋率高不能說(shuō)明代碼質(zhì)量高,但是反過(guò)來(lái)看,代碼覆蓋率低,代碼質(zhì)量不會(huì )高到哪里去,可以作為測試自我審視的重要工具之一。
代碼覆蓋率工具
目前Java常用覆蓋率工具Jacoco、Emma和Cobertura
覆蓋率工具工作流程
1. 對Java字節碼進(jìn)行插樁,On-The-Fly和Offine兩種方式。
2. 執行測試用例,收集程序執行軌跡信息,將其dump到內存。
3. 數據處理器結合程序執行軌跡信息和代碼結構信息分析生成代碼覆蓋率報告。
4. 將代碼覆蓋率報告圖形化展示出來(lái),如html、xml等文件格式。
插樁原理
主流代碼覆蓋率工具都采用字節碼插樁模式,通過(guò)鉤子的方式來(lái)記錄代碼執行軌跡信息。其中字節碼插樁又分為兩種模式On-The-Fly和Offine。 On-The-Fly模式優(yōu)點(diǎn)在于無(wú)需修改源代碼,可以在系統不停機的情況下,實(shí)時(shí)收集代碼覆蓋率信息。Offine模式優(yōu)點(diǎn)在于系統啟動(dòng)不需要額外開(kāi)啟代理,但是只能在系統停機的情況下才能獲取代碼覆蓋率。 基于以上特性,同時(shí)由于公司使用JDK8,我們采用Jacoco來(lái)獲取集成測試代碼覆蓋率,單元測試使用Cobertura。
On-The-Fly插樁 Java Agent
JVM中通過(guò)-javaagent參數指定特定的jar文件啟動(dòng)Instrumentation的代理程序
代理程序在每裝載一個(gè)class文件前判斷是否已經(jīng)轉換修改了該文件,如果沒(méi)有則需要將探針插入class文件中。
代碼覆蓋率就可以在JVM執行代碼的時(shí)候實(shí)時(shí)獲取。
典型代表:Jacoco
On-The-Fly插樁 Class Loader
自定義classloader實(shí)現自己的類(lèi)裝載策略,在類(lèi)加載之前將探針插入class文件中
典型代表:Emma
Offine插樁
在測試之前先對文件進(jìn)行插樁,生成插過(guò)樁的class文件或者jar包,執行插過(guò)樁的class文件或者jar包之后,會(huì )生成覆蓋率信息到文件,最后統一對覆蓋率信息進(jìn)行處理,并生成報告。
Offline插樁又分為兩種:
Replace:修改字節碼生成新的class文件
Inject:在原有字節碼文件上進(jìn)行修改
典型代表:Cobertura
On-The-Fly和Offine比較
On-The-Fly模式更加方便的獲取代碼覆蓋率,無(wú)需提前進(jìn)行字節碼插樁,可以實(shí)時(shí)獲取代碼覆蓋率信息
Offline模式適用于以下場(chǎng)景:
運行環(huán)境不支持java agent
部署環(huán)境不允許設置JVM參數
字節碼需要被轉換成其他虛擬機字節碼,如Android Dalvik VM
動(dòng)態(tài)修改字節碼過(guò)程中和其他agent沖突
無(wú)法自定義用戶(hù)加載類(lèi)
實(shí)踐應用
單元測試覆蓋率
目前有贊開(kāi)發(fā)人員會(huì )寫(xiě)單元測試用例,為了能夠引入持續集成,我們選取了Sonar+Cobertura來(lái)獲取單元測試覆蓋率。 我們將代碼覆蓋率綁定到代碼編譯階段,這樣每次代碼編譯就能夠執行單元測試同時(shí)獲取代碼單元測試覆蓋率
org.codehaus.mojo
cobertura-maven-plugin
2.7
xml
原文轉自: http://tech.youzan.com/code-coverage/