使用Jacoco獲取 Java 程序的代碼執(zhí)行覆蓋率的步驟詳解
Jacoco是Java Code Coverage的縮寫,顧名思義,它是獲取Java代碼執(zhí)行覆蓋率的一個工具,通常用它來獲取單元測試覆蓋率。它通過分析Java字節(jié)碼來得到代碼執(zhí)行覆蓋率,因此它還可以分析任何基于JVM的語言(如Croovy、Kotlin)的覆蓋率。本文不討論如何用Jacoco獲取單元測試的代碼覆蓋率,而是從Jacoco的原理出發(fā),介紹如何通過Jacoco獲取SIT或者UAT的測試覆蓋率。更準(zhǔn)確來講,是獲取一個應(yīng)用執(zhí)行過的代碼占總代碼的比率。包括字節(jié)碼指令覆蓋率,分支覆蓋率,圈復(fù)雜度覆蓋率,行覆蓋率,方法覆蓋率和類覆蓋率。
Jacoco原理簡介
Jacoco通過修改喂給JVM的字節(jié)碼來達(dá)到獲取那些代碼執(zhí)行了的目的。修改方式有兩種,一種在線(on-the-fly),是通過Java agent,在JVM執(zhí)行字節(jié)碼之前動態(tài)對其進(jìn)行修改,這種方式更靈活,也是Jcoco的一大特性。另一種是離線(offline)模式,在Java程序字節(jié)碼文件(.class文件)生成之前進(jìn)行修改,這樣的字節(jié)碼就不純了。一般在無法使用on-the-fly方式的時候才使用offline方式。
上面這些概括起來講,Jacoco最牛X的地方就在于它能夠知道一個基于JVM的應(yīng)用程序中哪些代碼(指令、分支、行、方法、類)被執(zhí)行了。用它除以總代碼量,就得到了代碼執(zhí)行覆蓋率。
由此,我們可以推斷出Jacoco生成單元測試覆蓋率報告的原理:單元測試代碼會調(diào)用被測試代碼,被測試代碼的字節(jié)碼指令會被Jacoco截獲,用被截獲的代碼量除以總代碼量,就算出了單元測試代碼覆蓋率。舉一反三,在SIT或者UT的時候,也需要執(zhí)行Java應(yīng)用程序中的代碼,因此可以也通過Jacoco獲取被執(zhí)行過的代碼,從而計算出SIT,UT測試代碼覆蓋率。
使用Jacoco生成代碼執(zhí)行覆蓋率報告
接下來通過一個實驗介紹如何使用Jacoco獲取一個Java web應(yīng)用代碼的執(zhí)行率。就拿Tomcat自帶的example應(yīng)用來做實驗,我們在啟動Tomcat時帶上Jacoco的Java agent;然后在頁面上做一些點擊操作,觸發(fā)后臺Java代碼的執(zhí)行;再抓取包含執(zhí)行情況數(shù)據(jù),放到.exec的二進(jìn)制文件中;最后由這些二進(jìn)制文件生成html格式的報告,驗證被覆蓋的代碼是否和我們點擊的內(nèi)容相關(guān)。
下載Jacoco(https://www.jacoco.org),解壓縮。
下載Tomcat(https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/ 清華mirror),然后解壓縮,進(jìn)入bin目錄,找到catalina.bat文件(Windows)。

修改如下代碼,讓Tomcat在啟動時帶上Javacoco的agent。
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"
修改為
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS% -javaagent:C:\Users\Robot\Application\jacoco-0.8.5\lib\jacocoagent.jar=destfile=jacoco.exec,output=tcpserver"
其中指定了javaagent是C:\Users\Robot\Application\jacoco-0.8.5\lib\jacocoagent.jar,解壓Jacoco可以得到;指定了output是tcpserver,也就是需要通過訪問一個地址才能獲取到數(shù)據(jù)。默認(rèn)地址是本地IP地址,端口號是6300。其它參數(shù)說明見:https://www.jacoco.org/jacoco/trunk/doc/agent.html。

設(shè)置完成之后,雙擊Tomcat bin目錄下的startup.bat,啟動Tomcat??刂婆_可以看見javaagent設(shè)置生效。此時Jacoco就可以動態(tài)地攔截喂給JVM的字節(jié)碼,并且監(jiān)聽6300端口號和所以本機地址,等待獲取代碼執(zhí)行情況數(shù)據(jù)(暫且稱為.exec文件數(shù)據(jù))的請求。

輸入地址http://127.0.0.1:8080/ ,打開Tomcat 歡迎頁面,做一些點擊操作,可以確定它已經(jīng)執(zhí)行了一些字節(jié)碼。

獲取執(zhí)行情況數(shù)據(jù),在jacococli.jar所在目錄(與jacocoagent.jar目錄一致)執(zhí)行命令:
java -jar jacococli.jar dump --port 6300 --destfile data/jacoco-it.exec
Jacoco會在當(dāng)前目錄下生成data/jacoco-it.exec文件,這個文件是一個二進(jìn)制文件,我們無法直接查看它,需要用它生成html或者其它格式的文件。

執(zhí)行如下命令生成html報告。--classfiles制定應(yīng)用程序的class文件所在目錄,--html指定html報告所在目錄。
java -jar jacococli.jar report data/jacoco-it.exec --classfiles C:/Users/Robot/Application/apache-tomcat-9.0.29/webapps/examples/WEB-INF/classes --html html

打開html目錄下的index.html文件就可以看到報告了。

小結(jié)
上面實驗比較簡單,只為輔助對Jacoco原理的理解。理解了原理之后,參照官網(wǎng)的手冊就可以用Jacoco來做一些實用的操作,提高Java代碼的質(zhì)量。
以上就是使用Jacoco獲取 Java 程序的代碼執(zhí)行覆蓋率的步驟詳解的詳細(xì)內(nèi)容,更多關(guān)于使用Jacoco獲取 Java 程序的代碼執(zhí)行覆蓋率的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Springboot實現(xiàn)定時任務(wù)的4種方式舉例詳解
在我們開發(fā)項目過程中經(jīng)常需要定時任務(wù)來幫助我們來做一些內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于Springboot實現(xiàn)定時任務(wù)的4種方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
java 使用idea將工程打成jar并創(chuàng)建成exe文件類型執(zhí)行的方法詳解
這篇文章主要介紹了java 使用idea將工程打成jar并創(chuàng)建成exe文件類型執(zhí)行,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-09-09
利用java和sqlserver建立簡易圖書管理系統(tǒng)的完整步驟
圖書館管理系統(tǒng)是圖書館管理工作中不可缺少的部分,它對于圖書館的管理者和使用者都非常重要,下面這篇文章主要給大家介紹了關(guān)于利用java和sqlserver建立簡易圖書管理系統(tǒng)的完整步驟,需要的朋友可以參考下2022-06-06
Spring解讀@Component和@Configuration的區(qū)別以及源碼分析
通過實例分析@Component和@Configuration注解的區(qū)別,核心在于@Configuration會通過CGLIB代理確保Bean的單例,而@Component不會,在Spring容器中,使用@Configuration注解的類會被CGLIB增強,保證了即使在同一個類中多次調(diào)用@Bean方法2024-10-10
Java Socket+mysql實現(xiàn)簡易文件上傳器的代碼
最近在做一個小項目,項目主要需求是實現(xiàn)一個文件上傳器,通過客戶端的登陸,把本地文件上傳到服務(wù)器的數(shù)據(jù)庫(本地的)。下面通過本文給大家分享下實現(xiàn)代碼,感興趣的朋友一起看看吧2016-10-10
Java中關(guān)鍵字final finally finalize的區(qū)別介紹
這篇文章主要給大家分享的是 Java中final,finally,finalize 到底有什么區(qū)別,文章圍繞final,finally,finalize的相關(guān)資料展開詳細(xì)內(nèi)容,具有一定的參考的價值,需要的朋友可以參考一下2022-04-04
SpringBoot實現(xiàn)過濾器、攔截器與切片的實現(xiàn)和區(qū)別
本文詳細(xì)介紹了使用過濾器、攔截器與切片實現(xiàn)每個請求耗時的統(tǒng)計,并比較三者的區(qū)別與聯(lián)系,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02
詳解Java時區(qū)處理之Date,Calendar,TimeZone,SimpleDateFormat
這篇文章主要介紹了Java時區(qū)處理之Date,Calendar,TimeZone,SimpleDateFormat的區(qū)別于用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Java實戰(zhàn)之小蜜蜂擴音器網(wǎng)上商城系統(tǒng)的實現(xiàn)
這篇文章主要介紹了如何利用Java實現(xiàn)簡單的小蜜蜂擴音器網(wǎng)上商城系統(tǒng),文中采用到的技術(shù)有JSP、Servlet?、JDBC、Ajax等,感興趣的可以動手試一試2022-03-03

