桔妹導讀:Super-Jacoco是基於Jacoco、git二次開發打造的一站式JAVA代碼全量/diff覆蓋率收集平臺,能夠低成本、無侵入的收集代碼覆蓋率數據;Super-Jacoco除了支持JVM運行時間段的覆蓋率收集外;還能夠和環境無縫對接,收集服務端自定義時間段代碼全量/增量覆蓋率;並提供可視化的html覆蓋率報表,協助覆蓋率分析,支撐精準測試落地。
在軟件生產交付過程中,我們通過單元測試、接口測試、功能測試等手段來保障軟件質量;無論哪種測試手段,case設計是否全面、精簡,顯得尤爲重要。在實際項目測試過程中,case的設計經常會出現以下問題:
1. 開發同學寫了大量單測,一直重複執行一段代碼邏輯,少數場景或異常代碼邏輯並未執行到;
2. 測試同學設計的測試用例經過反覆評審,仍然有未覆蓋到的異常場景,出現漏測情況;
3. 接口自動化測試case作爲日常回歸手段,無法確定是否覆蓋所有代碼邏輯,其可靠性無法評估。
那麼,如何才能用最精簡的case來保障測試的全面性呢?目前業界比較認可的是手段是通過分析變更代碼的覆蓋率補充響應的case;我們調研了業界開源的java代碼覆蓋率統計工具jacoco和EMMA,發現jacoco和EMMA都只支持收集全量代碼覆蓋率,不能滿足精準分析增量代碼覆蓋程度的訴求。因此,我們亟需一款能夠收集變更代碼覆蓋率的工具。
▍2.1. 整體流程
▍2.2. 獲取增量代碼
▍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個方法進行覆蓋率統計與顯示:
-
通用 :既支持單元測試覆蓋率收集,也支持手工測試覆蓋率收集;既支持全量覆蓋率收集,也支持diff覆蓋率收集; -
無侵入 :採用on-the-fly模式,無需對開發代碼做任何改造,即可收集覆蓋率數據; -
高可用 :分佈式架構,任務機可無限擴展,避免任務機down機或者任務過多時出現性能瓶頸; 可視化:提供html格式的覆蓋率報告,可讀性高。
▍5.2. 編譯打包
5.2.1 安裝JDK1.8、mavan3
▍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"}
備註:
https://github.com/didi/super-jacoco
開源團隊
▬
團隊成員皆來自滴滴車服技術團隊
內容編輯 | Teeo
聯繫我們 | [email protected]
本文分享自微信公衆號 - 滴滴技術(didi_tech)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。