Jacoco是Java Code Coverage的縮寫,顧名思義,它是獲取Java代碼執行覆蓋率的一個工具,一般用它來獲取單元測試覆蓋率。它經過分析Java字節碼來獲得代碼執行覆蓋率,所以它還能夠分析任何基於JVM的語言(如Croovy、Kotlin)的覆蓋率。本文不討論如何用Jacoco獲取單元測試的代碼覆蓋率,而是從Jacoco的原理出發,介紹如何經過Jacoco獲取SIT或者UAT的測試覆蓋率。更準確來說,是獲取一個應用執行過的代碼佔總代碼的比率。包括字節碼指令覆蓋率,分支覆蓋率,圈複雜度覆蓋率,行覆蓋率,方法覆蓋率和類覆蓋率。html
Jacoco經過修改餵給JVM的字節碼來達到獲取那些代碼執行了的目的。修改方式有兩種,一種在線(on-the-fly),是經過Java agent,在JVM執行字節碼以前動態對其進行修改,這種方式更靈活,也是Jcoco的一大特性。另外一種是離線(offline)模式,在Java程序字節碼文件(.class文件)生成以前進行修改,這樣的字節碼就不純了。通常在沒法使用on-the-fly方式的時候才使用offline方式。java
上面這些歸納起來說,Jacoco最牛X的地方就在於它可以知道一個基於JVM的應用程序中哪些代碼(指令、分支、行、方法、類)被執行了。用它除以總代碼量,就獲得了代碼執行覆蓋率。web
由此,咱們能夠推斷出Jacoco生成單元測試覆蓋率報告的原理:單元測試代碼會調用被測試代碼,被測試代碼的字節碼指令會被Jacoco截獲,用被截獲的代碼量除以總代碼量,就算出了單元測試代碼覆蓋率。觸類旁通,在SIT或者UT的時候,也須要執行Java應用程序中的代碼,所以能夠也經過Jacoco獲取被執行過的代碼,從而計算出SIT,UT測試代碼覆蓋率。apache
接下來經過一個實驗介紹如何使用Jacoco獲取一個Java web應用代碼的執行率。就拿Tomcat自帶的example應用來作實驗,咱們在啓動Tomcat時帶上Jacoco的Java agent;而後在頁面上作一些點擊操做,觸發後臺Java代碼的執行;再抓取包含執行狀況數據,放到.exec的二進制文件中;最後由這些二進制文件生成html格式的報告,驗證被覆蓋的代碼是否和咱們點擊的內容相關。tomcat
下載Jacoco(https://www.jacoco.org),解壓縮。app
下載Tomcat(https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/ 清華mirror),而後解壓縮,進入bin目錄,找到catalina.bat文件(Windows)。webapp
修改以下代碼,讓Tomcat在啓動時帶上Javacoco的agent。tcp
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,也就是須要經過訪問一個地址才能獲取到數據。默認地址是本地IP地址,端口號是6300。其它參數說明見:https://www.jacoco.org/jacoco/trunk/doc/agent.html。單元測試
設置完成以後,雙擊Tomcat bin目錄下的startup.bat,啓動Tomcat。控制檯能夠看見javaagent設置生效。此時Jacoco就能夠動態地攔截餵給JVM的字節碼,而且監聽6300端口號和因此本機地址,等待獲取代碼執行狀況數據(暫且稱爲.exec文件數據)的請求。
輸入地址http://127.0.0.1:8080/ ,打開Tomcat 歡迎頁面,作一些點擊操做,能夠肯定它已經執行了一些字節碼。
獲取執行狀況數據,在jacococli.jar所在目錄(與jacocoagent.jar目錄一致)執行命令:
java -jar jacococli.jar dump --port 6300 --destfile data/jacoco-it.exec
Jacoco會在當前目錄下生成data/jacoco-it.exec文件,這個文件是一個二進制文件,咱們沒法直接查看它,須要用它生成html或者其它格式的文件。
執行以下命令生成html報告。--classfiles制定應用程序的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文件就能夠看到報告了。
上面實驗比較簡單,只爲輔助對Jacoco原理的理解。理解了原理以後,參照官網的手冊就能夠用Jacoco來作一些實用的操做,提升Java代碼的質量。