Coverage_JacocoWebServer
Code coverage platform for Android project.
Base on jacoco,SpringBoot,Vue,java,kotlin....
項目地址:https://github.com/duqian291902259/android_coverage_jacoco
- web-vue 前端工程
- src后端邏輯
- docker:mvn插件自動生成鏡像的目錄
- 根目錄的Dockerfile是使用cmd命令操作build、run鏡像
概述
代碼覆蓋率(Code coverage)是軟件測試中的一種度量,描述程序中原始碼被測試的比例和程度,所得比例稱為代碼覆蓋率。 代碼覆蓋是由系統(tǒng)化軟件測試所派生的方式。代碼覆蓋率統(tǒng)計,主要用于測試人員進行功能測試、集成測試、回歸測試等場景,以及研發(fā)人員的開發(fā)自測后查看覆蓋率情況。
通過自研,開發(fā)了一套代碼覆蓋率報告管理系統(tǒng),該系統(tǒng)具備收集移動端覆蓋率信息,并實現(xiàn)全量、增量覆蓋率報告的生成與管理功能。
解決的問題
- 統(tǒng)一覆蓋率報告的生成與管理,管理平臺提供多平臺支持。
- 支持生成全量、增量的覆蓋率報告。
- 支持按分支提交點生成覆蓋率報告,支持在線預(yù)覽報告和下載報告。
- 報告的檢索與預(yù)覽便捷,降低研發(fā)與QA的測試成本。
- 系統(tǒng)易集成,可拓展到其他產(chǎn)品或者其他終端。
覆蓋率統(tǒng)計平臺的意義
- 滿足了QA、研發(fā)人員對全量、增量覆蓋率統(tǒng)計的需要。
- 平臺化,屏蔽各端生成報告的流程差異,讓流程更加自動、便捷。
- 分析未覆蓋部分的代碼,從而反推程序邏輯、測試用例是否合理。
- 及時發(fā)現(xiàn)程序中的冗余邏輯,提升代碼質(zhì)量。
- 對測試過程提供有效的數(shù)據(jù)支持。
現(xiàn)有方案對比
覆蓋率報告的生成,有很多現(xiàn)有的實現(xiàn)方案,現(xiàn)狀如下:
- 不同編程語言有各自的實現(xiàn)方案,生成流程和表現(xiàn)形式良莠不齊。
- 各端本地生成靜態(tài)報告,缺乏系統(tǒng)性,不方便統(tǒng)一管理。
- 開發(fā)集成的覆蓋率工具,適用于開發(fā)人員,不符合QA的工作流程。
- 本地開發(fā)階段開啟覆蓋率功能,很耗性能和時間,無法大規(guī)模應(yīng)用。
通過研究,Java語言比較成熟的覆蓋率統(tǒng)計實現(xiàn)方案有Jacoco,但是在Android大型項目的落地方面,有很多問題需要處理解決。
經(jīng)過不斷開發(fā)迭代,將Android覆蓋率統(tǒng)計的功能,做了IDE環(huán)境生成和云端生成。云端生成,可將復(fù)雜且耗時的功能交給服務(wù)器處理,聚合各端的覆蓋率報告,一定程度上解決了以上痛點。
技術(shù)思路

客戶端預(yù)處理。
各端在編譯構(gòu)建階段,對項目中的代碼插樁,插入探針,用于監(jiān)測代碼執(zhí)行情況。打包構(gòu)建,將編譯后的相關(guān)產(chǎn)物上傳到服務(wù)器。
如Android上傳.class字節(jié)碼文件和java文件,ios上傳.gcno和.gcda文件,用于后續(xù)服務(wù)器根據(jù)不同的工具生成報告。安裝&運行程序,收集覆蓋率信息并上傳到服務(wù)器。
安裝插樁后的程序包,使用對應(yīng)的功能(待測試的功能),記錄代碼運行的情況,并生成記錄了覆蓋率信息的文件,各端用統(tǒng)一的接口,上傳文件到服務(wù)器,用于后續(xù)生成報告。web前端頁面,提交表單,生成覆蓋率報告并在線預(yù)覽。
頁面顯示出當(dāng)前支持的應(yīng)用、平臺、已經(jīng)支持覆蓋率功能的分支,以及生成報告對應(yīng)的Git提交點等信息,用戶安裝好對應(yīng)的客戶端,上傳好覆蓋率文件后,選擇對應(yīng)平臺的某個應(yīng)用,提交請求,生成覆蓋率報告。覆蓋率server端,負責(zé)報告的生成和管理邏輯。
Server提供API接口給各端使用;提供已有覆蓋率報告的管理功能:查詢,預(yù)覽,下載和刪除等。
用戶自定義生成報告的條件,系統(tǒng)可根據(jù)條件,生成全量或者增量覆蓋率報告。增量報告通過git diff功能找出增量修改的代碼文件,用于報告的過濾處理。
覆蓋率報告生成的邏輯,基于各自平臺的命令行工具完成。
技術(shù)實現(xiàn)
整體流程

一. Coverage-Server
覆蓋率后臺服務(wù),通過SpringBoot MVC實現(xiàn)。后端服務(wù),根據(jù)不同平臺覆蓋率生成的邏輯差異,需要分別處理。
比如Android項目,是java編程語言實現(xiàn),所以可以直接調(diào)用jacoco框架的jar包,通過report方法生成報告,需要傳入生成報告所需的各種參數(shù),命令為:java -jar execPath --classfilessrcPath --html $reportPath --encoding=utf8。
服務(wù)架構(gòu)如圖所示。

后端提供文件上傳和下載服務(wù),android客戶端收集的覆蓋率信息(.ec文件),編譯后上傳的.src文件和.class文件,都是通過這個統(tǒng)一的接口上傳,按應(yīng)用名稱、git提交點的commitId值等來命名文件目錄,文件的保存路徑的命名,依賴于后續(xù)web提交表單的內(nèi)容,需要一一對應(yīng),方便檢索到對應(yīng)的文件。
生成覆蓋率報告,依賴的文件在服務(wù)器都能找到時,就可以使用jacococli.jar生成對應(yīng)的html報告,返回給前端展示。
二. Coverage-Web
前端展示報告的服務(wù),是通過Node.js開啟一個http-server服務(wù),指定服務(wù)器某個文件路徑,即可打開改路徑下的靜態(tài)頁面。
表單頁面使用Vue+Webpack實現(xiàn),與后端邏輯分離,頁面只是用來收集生成報告所需的條件,并請求后端的接口,待后端生成報告后,返回報告相關(guān)的數(shù)據(jù),web前端展示報告即可。
頁面包含覆蓋率生成的條件表單編輯、提交功能,有已生成報告的在線預(yù)覽、下載、管理界面。部分請求表單如下圖所示:

選擇對應(yīng)的分支、兩個提交點commitId,并勾選增量覆蓋率,就可以通過使用gitlab的api,或者git diff命令,計算出兩個提交點之間的diff文件列表,通過分支名和這些文件列表,去檢索前面上傳的.ec文件、src源碼和class文件,從而針對這些增量修改的文件統(tǒng)計對應(yīng)的覆蓋率。如果不勾選增量覆蓋率,就是統(tǒng)計所選分支項目代碼的全量覆蓋率。

三. 客戶端技術(shù)實現(xiàn)
以Android、Java工程為例,一般覆蓋率報告的生成過程如下:
[圖片上傳失敗...(image-d3a151-1650857287076)]
Android端,Java開發(fā),采用Jacoco實現(xiàn)覆蓋率報告,Off-line模式。
集成jacoco的plugin,在功能開啟時,實現(xiàn)對自定義類的插樁,在debug包構(gòu)建過程中,插入探針,便于記錄每行代碼執(zhí)行情況。安裝對應(yīng)的apk,運行app,首次打開應(yīng)用或者進入設(shè)置界面可dump覆蓋率數(shù)據(jù)保存到本地存儲目錄,然后上傳ec覆蓋率文件給該系統(tǒng)對應(yīng)的服務(wù)器。
如何實現(xiàn)插樁呢?
Java的Class初始化時,Jacoco初始化了一個Boolean類型的數(shù)組,用于記錄每一個方法內(nèi)部邏輯的執(zhí)行情況,默認值是false表示沒有執(zhí)行,如果代碼執(zhí)行過,就會記錄為true,這些探針會dump到本地文件保存下來。Android保存的覆蓋率文件的拓展名為.ec文件,后續(xù)會上傳到覆蓋率平臺。
下圖,以一個源代碼為例說明代碼注入探針的過程:

反編譯代碼,查看插樁后的代碼邏輯,可以看到如下圖所示的邏輯變化,構(gòu)造函數(shù)初始化時,Jacoco也做了一些初始化的工作。
[圖片上傳中...(image.png-271fd0-1650857113830-0)]
Jacoco包含了多種維度的覆蓋率計數(shù)器:指令級計數(shù)器(C0 coverage)、分支級計數(shù)器(C1 coverage)、圈復(fù)雜度、行覆蓋、方法覆蓋、類覆蓋等。
生成的靜態(tài)報告頁面如下,可以查看對應(yīng)的覆蓋率數(shù)據(jù)和源碼執(zhí)行情況:

HTML靜態(tài)報告,內(nèi)容用不同的背景顏色區(qū)分,表示不同的覆蓋情況。解釋說明如下:
- 綠色:表示行覆蓋充分。
- 紅色:表示未覆蓋的行。
- 黃色棱形:表示分支覆蓋不全。
- 綠色棱形:表示分支覆蓋完全。
應(yīng)用場景
系統(tǒng)主要應(yīng)用在以下使用場景:
1.新開發(fā)功能的分支測試
1)全部都跑一遍該分支新增全部功能的測試用例,收集各個功能點的覆蓋率信息,計算出覆蓋率。
2)修復(fù)bug后看覆蓋率,只看當(dāng)前分支的提交,對比修bug前的版本的提交記錄,得出增量修改的代碼并計算出覆蓋率。
3)測試分支過程中同步了dev分支的代碼,通過計算當(dāng)前分支相比dev的修改部分,計算出覆蓋率。
2.master分支全回歸測試
1)全部回歸完后看覆蓋率,統(tǒng)一App版本的回歸,可以看全量覆蓋率。
2)修復(fù)bug后看覆蓋率,前后對比diff,需要修改部分的代碼覆蓋率。
QA根據(jù)覆蓋率報告可針對性測試,并且發(fā)現(xiàn)一些程序bug或優(yōu)化點。
有些邏輯永遠執(zhí)行不到,經(jīng)核實是該類中無用的方法,如:

QA應(yīng)用后反饋:平臺優(yōu)點是可以看測試過的覆蓋率與代碼增刪是否一致,沒有測試到改動處,可以再去測試。
方案效果
本覆蓋率報告生成與管理的系統(tǒng),帶來的收益:
1)通過流程改造,解決了移動端覆蓋率統(tǒng)計的多種難點。
2)端上自定義覆蓋率統(tǒng)計的邏輯,實現(xiàn)增量覆蓋率的統(tǒng)計。如Android通過Gradle插件開發(fā),用于自定義class、src路徑,并上傳文件,再基于gitlab的api實現(xiàn)獲取項目增量修改,從而滿足全量、增量覆蓋率統(tǒng)計的需求。
3)移動端項目,配合web前端和服務(wù)端,使得覆蓋率系統(tǒng)鏈路完整,平臺化,讓整個流程更加規(guī)范、便捷、高效。
4)Web形式展示報告,方便各端人員查閱報告并分析未覆蓋部分的代碼,從而反推程序邏輯、測試用例是否合理,對測試過程提供有效的數(shù)據(jù)支持。
應(yīng)用案例
可以在團中廣泛應(yīng)用,開發(fā)人員與測試人員都能根據(jù)代碼覆蓋率信息驗證問題、發(fā)現(xiàn)問題并解決。
其他
DMEO工程為初期項目,但包含了Android端覆蓋率統(tǒng)計平臺化的思想,實際項目會有很大的改進和優(yōu)化。僅供學(xué)習(xí)交流,如有問題,請留言聯(lián)系杜小菜。