持續(xù)集成_為什么做代碼覆蓋率的分析

轉(zhuǎn)自https://tech.youzan.com/code-coverage/

引言

經(jīng)常有人問(wèn)這樣的問(wèn)題:“我們?cè)谧鰡卧獪y(cè)試郑趁,那測(cè)試覆蓋率要到多少才行梭纹?”绍载。答案其實(shí)很簡(jiǎn)答,“作為指標(biāo)的測(cè)試覆蓋率都是沒(méi)有用處的〖胙鳎”

Martin Fowler(重構(gòu)那本書(shū)的作者)曾經(jīng)寫(xiě)過(guò)一篇博客來(lái)討論這個(gè)問(wèn)題弄企,他指出:把測(cè)試覆蓋作為質(zhì)量目標(biāo)沒(méi)有任何意義约素,而我們應(yīng)該把它作為一種發(fā)現(xiàn)未被測(cè)試覆蓋的代碼的手段。


Alt text

代碼覆蓋率的意義

  1. 分析未覆蓋部分的代碼疾呻,從而反推在前期測(cè)試設(shè)計(jì)是否充分蟆肆,沒(méi)有覆蓋到的代碼是否是測(cè)試設(shè)計(jì)的盲點(diǎn)淤齐,為什么沒(méi)有考慮到义锥?需求/設(shè)計(jì)不夠清晰膨更,測(cè)試設(shè)計(jì)的理解有誤敞贡,工程方法應(yīng)用后的造成的策略性放棄等等鹏漆,之后進(jìn)行補(bǔ)充測(cè)試用例設(shè)計(jì)。
  2. 檢測(cè)出程序中的廢代碼饭聚,可以逆向反推在代碼設(shè)計(jì)中思維混亂點(diǎn)慨蓝,提醒設(shè)計(jì)/開(kāi)發(fā)人員理清代碼邏輯關(guān)系婆跑,提升代碼質(zhì)量数冬。
  3. 代碼覆蓋率高不能說(shuō)明代碼質(zhì)量高,但是反過(guò)來(lái)看,代碼覆蓋率低挟秤,代碼質(zhì)量不會(huì)高到哪里去抄伍,可以作為測(cè)試自我審視的重要工具之一艘刚。

代碼覆蓋率工具

目前Java常用覆蓋率工具Jacoco、Emma和Cobertura

image

覆蓋率工具工作流程

Alt text

1. 對(duì)Java字節(jié)碼進(jìn)行插樁截珍,On-The-Fly和Offine兩種方式攀甚。
2. 執(zhí)行測(cè)試用例,收集程序執(zhí)行軌跡信息岗喉,將其dump到內(nèi)存秋度。
3. 數(shù)據(jù)處理器結(jié)合程序執(zhí)行軌跡信息和代碼結(jié)構(gòu)信息分析生成代碼覆蓋率報(bào)告。
4. 將代碼覆蓋率報(bào)告圖形化展示出來(lái)钱床,如html荚斯、xml等文件格式。

插樁原理

Alt text

主流代碼覆蓋率工具都采用字節(jié)碼插樁模式,通過(guò)鉤子的方式來(lái)記錄代碼執(zhí)行軌跡信息事期。其中字節(jié)碼插樁又分為兩種模式On-The-Fly和Offine滥壕。On-The-Fly模式優(yōu)點(diǎn)在于無(wú)需修改源代碼,可以在系統(tǒng)不停機(jī)的情況下兽泣,實(shí)時(shí)收集代碼覆蓋率信息绎橘。Offine模式優(yōu)點(diǎn)在于系統(tǒng)啟動(dòng)不需要額外開(kāi)啟代理,但是只能在系統(tǒng)停機(jī)的情況下才能獲取代碼覆蓋率撞叨。 基于以上特性金踪,同時(shí)由于公司使用JDK8,我們采用Jacoco來(lái)獲取集成測(cè)試代碼覆蓋率牵敷,單元測(cè)試使用Cobertura胡岔。

On-The-Fly插樁 Java Agent

  • JVM中通過(guò)-javaagent參數(shù)指定特定的jar文件啟動(dòng)Instrumentation的代理程序
  • 代理程序在每裝載一個(gè)class文件前判斷是否已經(jīng)轉(zhuǎn)換修改了該文件,如果沒(méi)有則需要將探針插入class文件中枷餐。
  • 代碼覆蓋率就可以在JVM執(zhí)行代碼的時(shí)候?qū)崟r(shí)獲取靶瘸。
  • 典型代表:Jacoco

On-The-Fly插樁 Class Loader

  • 自定義classloader實(shí)現(xiàn)自己的類裝載策略,在類加載之前將探針插入class文件中
  • 典型代表:Emma

Offine插樁

  • 在測(cè)試之前先對(duì)文件進(jìn)行插樁毛肋,生成插過(guò)樁的class文件或者jar包怨咪,執(zhí)行插過(guò)樁的class文件或者jar包之后,會(huì)生成覆蓋率信息到文件润匙,最后統(tǒng)一對(duì)覆蓋率信息進(jìn)行處理诗眨,并生成報(bào)告。
  • Offline插樁又分為兩種:
    • Replace:修改字節(jié)碼生成新的class文件
    • Inject:在原有字節(jié)碼文件上進(jìn)行修改
  • 典型代表:Cobertura

On-The-Fly和Offine比較

  • On-The-Fly模式更加方便的獲取代碼覆蓋率孕讳,無(wú)需提前進(jìn)行字節(jié)碼插樁匠楚,可以實(shí)時(shí)獲取代碼覆蓋率信息
  • Offline模式適用于以下場(chǎng)景:
    • 運(yùn)行環(huán)境不支持java agent
    • 部署環(huán)境不允許設(shè)置JVM參數(shù)
    • 字節(jié)碼需要被轉(zhuǎn)換成其他虛擬機(jī)字節(jié)碼,如Android Dalvik VM
    • 動(dòng)態(tài)修改字節(jié)碼過(guò)程中和其他agent沖突
    • 無(wú)法自定義用戶加載類

實(shí)踐應(yīng)用

單元測(cè)試覆蓋率

目前有贊開(kāi)發(fā)人員會(huì)寫(xiě)單元測(cè)試用例厂财,為了能夠引入持續(xù)集成芋簿,我們選取了Sonar+Cobertura來(lái)獲取單元測(cè)試覆蓋率。 我們將代碼覆蓋率綁定到代碼編譯階段璃饱,這樣每次代碼編譯就能夠執(zhí)行單元測(cè)試同時(shí)獲取代碼單元測(cè)試覆蓋率

<plugin>  
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.7</version>
    <configuration>
        <formats>
            <format>xml</format>
        </formats>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>cobertura</goal>
            </goals>
        </execution>
    </executions>
</plugin>  

生成代碼覆蓋率文件以后与斤,通過(guò)Jenkins SonarQube Scanner或者執(zhí)行mvn sonar:sonar將該文件上傳至Sonar 服務(wù)器,就可以解析該文件荚恶,生成圖形化的界面

image

集成測(cè)試覆蓋率

測(cè)試人員執(zhí)行集成測(cè)試測(cè)試用例時(shí)(包括手工執(zhí)行和自動(dòng)化執(zhí)行)撩穿,我們需要代碼覆蓋率來(lái)發(fā)現(xiàn)測(cè)試用例設(shè)計(jì)的遺漏,及時(shí)補(bǔ)充用例來(lái)覆蓋未被覆蓋到的代碼谒撼。

被測(cè)系統(tǒng)冗锁,在服務(wù)啟動(dòng)時(shí),都會(huì)通過(guò)javaagent的方式做On-The-Fly插樁

image
  • 被測(cè)服務(wù)器啟動(dòng)之后嗤栓,測(cè)試人員手工執(zhí)行測(cè)試用例冻河,Jacoco Agent會(huì)實(shí)時(shí)將代碼覆蓋率信息傳輸給Jacoco Prase Server箍邮,該服務(wù)器保存了被測(cè)代碼源文件以及編譯后的目標(biāo)文件,服務(wù)器會(huì)結(jié)合源文件叨叙、目標(biāo)文件以及代碼覆蓋率信息生成圖表化的覆蓋率文件锭弊。

  • 自動(dòng)化執(zhí)行測(cè)試用例完成之后,獲取代碼覆蓋率信息擂错,通過(guò)Jenkins Jacoco插件解析味滞,獲取圖表化的覆蓋率文件。
    image

    獲取代碼覆蓋率報(bào)告之后钮呀,結(jié)合git獲取的本次代碼變動(dòng)信息剑鞍,得到測(cè)試用例覆蓋的變動(dòng)文件的測(cè)試覆蓋率統(tǒng)計(jì)信息。來(lái)分析是否有由于測(cè)試用例設(shè)計(jì)遺漏導(dǎo)致的代碼沒(méi)有覆蓋或者是開(kāi)發(fā)的無(wú)效代碼導(dǎo)致該代碼無(wú)法被覆蓋爽醋,如果測(cè)試用例設(shè)計(jì)有所遺漏蚁署,可以對(duì)照的增加相應(yīng)的用例;如果是無(wú)效代碼可以刪除蚂四。

自動(dòng)化集成流程

Alt text

1. 業(yè)務(wù)開(kāi)發(fā)完成之后光戈,開(kāi)發(fā)人員做單元測(cè)試,單元測(cè)試完成之后遂赠,保證單元測(cè)試全部通過(guò)同時(shí)單元測(cè)試代碼覆蓋率達(dá)到一定程度(這個(gè)需要開(kāi)發(fā)和測(cè)試約定久妆,理論上越高越好),開(kāi)發(fā)提測(cè)跷睦。
2. 測(cè)試人員根據(jù)測(cè)試用例進(jìn)行測(cè)試(包括手工測(cè)試和自動(dòng)化測(cè)試)筷弦,結(jié)合git獲取本次變動(dòng)代碼的覆蓋率信息。行覆蓋率需達(dá)到100%抑诸,分支達(dá)到50%以上烂琴,這個(gè)需要具體場(chǎng)景具體分析。
3. 測(cè)試通過(guò)之后哼鬓,代碼合并至主干,進(jìn)行自動(dòng)化回歸边灭。
4. 回歸測(cè)試通過(guò)之后异希,代碼可以上線。

基于這套流程绒瘦,我們可以將單元測(cè)試代碼覆蓋率和集成測(cè)試代碼覆蓋率整合到持續(xù)集成流程中称簿,如果代碼覆蓋率達(dá)不到我們?cè)O(shè)置的某個(gè)值時(shí),可以終止流程繼續(xù)下去獲取需要人工確認(rèn)之后惰帽,繼續(xù)流程憨降。

總結(jié)

本文主要介紹了Java代碼覆蓋率統(tǒng)計(jì)原理以及結(jié)合有贊測(cè)試的工程實(shí)踐介紹了代碼覆蓋率該如何應(yīng)用的實(shí)際測(cè)試中。不管是白盒測(cè)試還是黑盒測(cè)試该酗,代碼覆蓋率統(tǒng)計(jì)都是必不可少的一環(huán)授药,它可以直接反映本次測(cè)試的遺漏點(diǎn)(不是100%反映)士嚎。結(jié)合到自動(dòng)發(fā)布場(chǎng)景也是一個(gè)較好地衡量指標(biāo)。

最后再重申一下本文開(kāi)篇的觀點(diǎn):

  • 代碼覆蓋率統(tǒng)計(jì)是用來(lái)發(fā)現(xiàn)沒(méi)有被測(cè)試覆蓋的代碼
  • 代碼覆蓋率統(tǒng)計(jì)不能完全用來(lái)衡量代碼質(zhì)量
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悔叽,一起剝皮案震驚了整個(gè)濱河市莱衩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娇澎,老刑警劉巖笨蚁,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異趟庄,居然都是意外死亡括细,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)戚啥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奋单,“玉大人,你說(shuō)我怎么就攤上這事虑鼎∪枘洌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵炫彩,是天一觀的道長(zhǎng)匾七。 經(jīng)常有香客問(wèn)我,道長(zhǎng)江兢,這世上最難降的妖魔是什么昨忆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮杉允,結(jié)果婚禮上邑贴,老公的妹妹穿的比我還像新娘。我一直安慰自己叔磷,他們只是感情好拢驾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著改基,像睡著了一般繁疤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秕狰,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天稠腊,我揣著相機(jī)與錄音,去河邊找鬼鸣哀。 笑死架忌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的我衬。 我是一名探鬼主播叹放,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼饰恕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了许昨?” 一聲冷哼從身側(cè)響起懂盐,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糕档,沒(méi)想到半個(gè)月后莉恼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡速那,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年俐银,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端仰。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捶惜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荔烧,到底是詐尸還是另有隱情吱七,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布鹤竭,位于F島的核電站踊餐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臀稚。R本人自食惡果不足惜吝岭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吧寺。 院中可真熱鬧窜管,春花似錦、人聲如沸稚机。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赖条。三九已至失乾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谋币,已是汗流浹背仗扬。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工症概, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蕾额,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓彼城,卻偏偏與公主長(zhǎng)得像诅蝶,于是被迫代替她去往敵國(guó)和親退个。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355