滴滴開源Super-jacoco:java代碼覆蓋率收集平臺文檔

桔妹導讀:Super-Jacoco是基於Jacoco、git二次開發打造的一站式JAVA代碼全量/diff覆蓋率收集平臺,能夠低成本、無侵入的收集代碼覆蓋率數據;Super-Jacoco除了支持JVM運行時間段的覆蓋率收集外;還能夠和環境無縫對接,收集服務端自定義時間段代碼全量/增量覆蓋率;並提供可視化的html覆蓋率報表,協助覆蓋率分析,支撐精準測試落地。

分析、產品迭代 工作都要圍繞它進行,這樣一來移動端上的操作行爲就顯得格外重要,運用好了就可以帶來效率提升,創造用戶價值和商業價值,那我們如何才能更好的運用它們呢

0. 
背景

在軟件生產交付過程中,我們通過單元測試、接口測試、功能測試等手段來保障軟件質量;無論哪種測試手段,case設計是否全面、精簡,顯得尤爲重要。在實際項目測試過程中,case的設計經常會出現以下問題:


1. 開發同學寫了大量單測,一直重複執行一段代碼邏輯,少數場景或異常代碼邏輯並未執行到;


2. 測試同學設計的測試用例經過反覆評審,仍然有未覆蓋到的異常場景,出現漏測情況;


3. 接口自動化測試case作爲日常回歸手段,無法確定是否覆蓋所有代碼邏輯,其可靠性無法評估。


那麼,如何才能用最精簡的case來保障測試的全面性呢?目前業界比較認可的是手段是通過分析變更代碼的覆蓋率補充響應的case;我們調研了業界開源的java代碼覆蓋率統計工具jacoco和EMMA,發現jacoco和EMMA都只支持收集全量代碼覆蓋率,不能滿足精準分析增量代碼覆蓋程度的訴求。因此,我們亟需一款能夠收集變更代碼覆蓋率的工具。



1. 
Super-jacoco簡介
Super-Jacoco是基於Jacoco、git二次開發打造的一站式JAVA代碼全量/diff覆蓋率收集平臺,能夠低成本、無侵入的收集代碼覆蓋率數據。Super-Jacoco除了支持JVM運行時間段的覆蓋率收集外;還能夠和環境無縫對接,收集服務端自定義時間段代碼全量/增量覆蓋率。並提供html格式的可視化覆蓋率報表,協助覆蓋情況精準分析,支撐精準測試落地。

單測代碼全量/增量覆蓋率收集:
on-the-fly模式,無需對開發代碼做任何改造,即可收集覆蓋率數據;

功能測試全量/增量覆蓋率收集:
和環境部署平臺ebase集成,只需要在JAVA啓動命令中添加-javaagent:jacocoagent.jar=includes=com.*即可收集功能測試覆蓋率數據;

可視化報告:
可視化的html覆蓋率報表,協助覆蓋情況精準分析,支撐精準測試落地。


2. 
Super-jacoco原理

2.1. 整體流程




爲了支持增量覆蓋率收集,我們需要做兩件事情:1)獲取不同版本代碼diff文件;2)對jacoco進行二次開發,使其支持增量方法列 表參數。

2.2.  獲取增量代碼


主要流程:拉取master(參照分支)和feature(提測分支)代碼,再通過JGit對兩個分支源碼進行比對,獲取增量代碼。以下爲部分代碼片段:



2.3.  jacoco 二次改造,支持增量方法列表參數


JaCoCo 對 exec 的解析主要是在 Analyzer 類的 analyzeClass(final byte[] source) 方法。這裏面會調用 createAnalyzingVisitor 方法,生成一個用於解析的 ASM 類訪問器,繼續跟代碼,發現對方法級別的探針計算邏輯是在 ClassProbesAdapter 類的 visitMethod 方法裏面。所以我們只需要改造 visitMethod 方法,使它只對提取出的每個類的新增或變更方法做解析,非指定類和方法不做處理。改造後的核心代碼片段如下: 



2.4.  執行


只需要在執行的mvn命令中加入-Djacoco.diffFile=變更方法列表,即可收集變更方法的代碼覆蓋率。如果不傳入-Djacoco.diffFile或者Djacoco.diffFile參數爲空,則默認收集全量覆蓋率。


2.5.  報告輸出


覆蓋率報告如下圖,在圖中是某個 service 的實現類,在最新的代碼中有23個方法,但是隻會對變更或新增的5個方法進行覆蓋率統計與顯示:




3. 
特性
  • 通用 :既支持單元測試覆蓋率收集,也支持手工測試覆蓋率收集;既支持全量覆蓋率收集,也支持diff覆蓋率收集;
  • 無侵入 :採用on-the-fly模式,無需對開發代碼做任何改造,即可收集覆蓋率數據;
  • 高可用 :分佈式架構,任務機可無限擴展,避免任務機down機或者任務過多時出現性能瓶頸;
  • 可視化:提供html格式的覆蓋率報告,可讀性高。



4. 
架構


5. 
如何使用
5.1. 數據庫安裝和初始化

5.1.1 安裝mysql數據庫,創建數據庫後執行sql/db.sql文件中的建表SQL



5.2. 編譯打包


5.2.1 安裝JDK1.8、mavan3

5.2.2 clone代碼,更改application.properties文件中的數據庫和gitlab配置:
spring.datasource.url=jdbc:mysql://IP:端口/數據庫名?useUn icode=true&characterEnco ding=utf8

    spring.datasource.username=
    pring.datasource.password=
    gitlab.username=
    gitlab.password=
5.2.3 執行mvn package -Dmaven.test.skip=true生成super-jacoco.jar


5.3. 部署


5.3.1 執行“nohup java -jar super-jacoco.jar &”啓動代碼覆蓋率服務,默認端口爲8899


5.4. 覆蓋率收集接口


5.4.1 單測覆蓋率接口


1)啓動覆蓋率收集URL:/cov/triggerUnitCover調用方法:POST參數(body方式傳入):{"uuid":"uuid","type":1,"gitUrl":"git@git","subModule":"","baseVersion":"master","nowVersion":"feature","envType":"-Ptest"}返回:{"code":200,"data":true,"msg":"msg"}備註:
2)獲取覆蓋率結果URL:/cov/getUnitCoverResult調用方法:GET參數:uuid(String)返回:{"code":200,"data":{"coverStatus":1,"errMsg":"msg","lineCoverage":100.0,"branchCoverage":100.0,"logFile":"file content","reportUrl":"http://"},"msg":"msg"}備註:


5.4.2 環境覆蓋率接口


1)啓動覆蓋率收集URL:/cov/triggerEnvCov調用方法:POST參數(body方式傳入):{"uuid":"uuid","type":1,"gitUrl":"git@git","subModule":"","baseVersion":"master","nowVersion":"feature","address":"127.0.0.1","port":"8088"}返回:{"code":200,"data":true,"msg":"msg"}備註:IP和port爲模塊部署服務器的IP和端口,在dump jacoco.exec時使用,需要提前把org.jacoco.agent-0.8.5-runtime.jar包拷貝到服務器:/home/xxx/目錄,服務啓動時需要添加啓動參數:-javaagent:/home/xxx/org.jacoco.agent-0.8.5-runtime.jar=includes=*,output=tcpserver,address=*,port=18513
2)獲取覆蓋率結果URL:/cov/getEnvCoverResult調用方法:GET參數:uuid(String)返回:{"code":200,"data":{"coverStatus":1,"errMsg":"msg","lineCoverage":100.0,"branchCoverage":100.0,"logFile":"file content","reportUrl":"http://"},"msg":"msg"}備註:



6. 
總結
在業務快速迭代的背景下,精準測試將是高效測試的發展趨勢,代碼覆蓋率則是其中重要的一環,Super-jacoco將java的代碼覆蓋率統計做到方便、快捷有助於精準測試的推動和發展,歡迎加入!



7. 
GitHub項目地址

https://github.com/didi/super-jacoco


開源團隊


團隊成員皆來自滴滴車服技術團隊



延伸閱讀


   
   
   

內容編輯 | Teeo
聯繫我們 | [email protected]

本文分享自微信公衆號 - 滴滴技術(didi_tech)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章