當前位置:
首頁 > 最新 > 增量代碼覆蓋率工具

增量代碼覆蓋率工具

文 | Winta on 測試


背景

目前有贊共享技術團隊測試介入的微服務應用有幾百個,大部分底層應用的單測覆蓋率在 70% 以上,同時測試組提供的多緯度集成測試自動化的覆蓋率也在 70% 以上。有贊的業務發展非常快,當存量代碼較多時,新項目功能測試的整體覆蓋率偏低是正常現象,另外開發提測時,並不能依據已有的全量覆蓋率來判斷對新增代碼的自測完成度,基於這個背景,我們研發了增量代碼覆蓋率工具,作為項目質量的參考緯度之一,支持統計功能測試、單測和集成測試,並集成到了 DevOps 平台。


有贊的 JAVA 代碼覆蓋率工具用的是 JaCoCo ,它是一個開源的覆蓋率工具,支持 JVM ,使用方法非常靈活,很多第三方的工具提供了對 JaCoCo 的集成,如 sonar、Jenkins 等。

關於 JaCoCo 的注入原理以及注入方式,在官方網站上寫的非常詳細了,網上翻譯修改的資料也非常多,不做過多贅述。經過對比,我們在統計功能測試覆蓋率以及集成測試覆蓋率時,選擇的是 On-the-fly 模式。原因是 On-the-fly 方式無須入侵應用啟動腳本,只需在 JVM 中通過 -javaagent 參數指定 jar 文件啟動 Instrumentation 的代理程序,代理程序在通過 Class Loader 裝載一個 class 前判斷是否需要注入 class 文件,將統計代碼插入 class ,測試覆蓋率分析就可以在 JVM 執行測試的過程中完成。

(圖片來源 官網 )

我們設計的方案也是基於 JaCoCo 做相應改造,生成我們所需要的覆蓋率模型,並通過 JaCoCo 開放的 API 實現相關功能。這裡面主要需要解決的點在獲取增量代碼並解析生成覆蓋率上。可以拆分成如下幾個步驟:

獲取測試完成後的 exec 文件(二進位文件,裡面有探針的覆蓋執行信息);

獲取基線提交與被測提交之間的差異代碼;

對差異代碼進行解析,切割為更小的顆粒度,我們選擇方法作為最小緯度;

改造 JaCoCo ,使它支持僅對差異代碼生成覆蓋率報告;

整體的流程如上圖,下面針對整個流程,分別說下我們是怎麼做的。


在講具體實現步驟之前,先談下我們對 JaCoCo 做的改造思路。 JaCoCo 的注入邏輯用的是 ASM 庫,對於沒有接觸過位元組碼注入技術的測試同學來說,改造注入邏輯需要花費較多時間,而對該工具從調研到完成的預期時間,只有不到10人日,所以我們用了一個比較快速簡單的方式:前面生成全量覆蓋率數據的流程不變,只對解析exec 文件生成報告做改造,生成我們所需要的覆蓋率模型。

JaCoCo 對 exec 的解析主要是在 Analyzer 類的方法。這裡面會調用方法,生成一個用於解析的 ASM 類訪問器,繼續跟代碼,發現對方法級別的探針計算邏輯是在 ClassProbesAdapter 類的方法裡面。所以我們只需要改造方法,使它只對提取出的每個類的新增或變更方法做解析,非指定類和方法不做處理。

改造後的核心代碼片段如下:


我們在部署 qa 項目 java 應用服務時,指定了 -javaagent 參數的 output 為 tcpserver ,並指定可用埠。官方對 output 的參數說明見下圖,默認是,目前有贊的集成測試覆蓋率用的是這種方式,所以必須要將 JVM 停掉以後才能將信息 dump 到指定文件。

(圖片截自JaCoCo官網)

我們獲取 exec 文件是通過 tcp 方式獲取的,且每一次收集的覆蓋率數據是追加的形式,所以 javaagent 參數設定如下:,然後將 javaagent 參數注入 JVM ,這部分由運維團隊配合支持,完成了持續交付項目下的 java 應用自動注入 JVM 。

以上步驟完成以後,在我們工具內就可以通過 JaCoCo 開放出來的 API 進行 exec 文件獲取,部分代碼片段如下:

在項目測試過程中,會遇到需要重新發布代碼的情況,此時大部分人不希望之前測試覆蓋的記錄被清空,希望對 dump 出來的覆蓋率進行累加。對於虛擬機,只要在 javaagent 參數裡面設置 append=true(默認就為 true)即可,但對於用 docker 部署的應用,每次重新發布,原先的 exec 文件會丟失,且 ip 也可能會變,需要找運維團隊進行配合支持。


這部分會涉及到較多的 Git 操作,我們是用 JGit 實現的。JGit 是一個用 Java 寫成的功能比較健全的 Git 的實現,它在 Java 社區中被廣泛使用。在這一步的主要流程是獲取基線提交與被測提交之間的差異代碼,然後過濾一些需要排除的文件(比如非 Java 文件、測試文件等等),對剩餘文件進行解析,將變更代碼解析到方法緯度,部分代碼片段如下:


這步是用 JaCoCo 開放的 API 和改造後的 JaCoCo 來實現的,根據前兩步獲取到的 class 和差異方法信息,用改造後的 JaCoCo 去解析 exec 文件,使它按照我們的覆蓋率模型,只生成增量代碼部分的覆蓋率報告。 生成報告的大致流程如圖:

生成報告和獲取報告的觸發時點是不同的,生成報告涉及較多的 Git 和 IO 操作,處理時間會比較長,跟 DevOps 的交互上是通過非同步方式進行處理。而獲取報告是通過批量查詢資料庫信息來獲取所需的報告信息。所以生成報告介面需要保存覆蓋率報告以及行覆蓋率信息併入庫,將覆蓋率報告地址在 tengine 裡面配置後,DevOps 平台即可實現訪問,部分代碼片段如下:


最終效果如下圖,在圖中是某個 service 的實現類,實際上在最新的代碼中有14個方法,但是只會對變更或新增的4個方法進行覆蓋率統計與顯示:另外在覆蓋率報告中顯示的覆蓋率數據也只是對變更的方法進行統計,不會按照全量代碼進行覆蓋率計算。對於沒有進行測試覆蓋的類,覆蓋率顯示為0:


目前我們的增量覆蓋率工具已經集成到運維的 DevOps 平台,所有接入持續交付的項目在測試完成後,觸發生成提測分支的增量代碼覆蓋率、展示報告,整個流程全自動化。與 DevOps 平台的整體交互大致如下圖:

OPS 即有贊的 DevOps 平台,icov 是我們增量代碼覆蓋率工具提供的服務。 icov 通過 tcp 方式從伺服器端獲取 exec 文件, OPS 觸發 icov 生成報告,並從 icov 獲取報告。

生成報告的觸發時點是在 qa 環境功能測試完成以後,由於每個項目下有多個應用,所以開放給 DevOps 平台的介面全部為批量非同步介面,另外我們的工具提供了多維度的介面封裝,可支持其他平台接入,後續會將工具插件化,測試博客也會持續更新。

增量代碼覆蓋率只能作為一個參考緯度,反推功能測試、單元測試或者集成測試是否存在遺漏,並進行補充,也可以作為開發自測完成度的一個參考,謹慎作為評估指標。

ps:

有贊測試組在持續招人中,大量崗位空缺,只要你來,就能幫你點亮全棧開發技能樹,有意向換工作的同學可以發簡歷到。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 有贊coder 的精彩文章:

TAG:有贊coder |