最近已經把 Java in Visual Studio Code 摸索到一定程度,但是獨缺 Test Coverage Report 報告可看。這篇文章我打算分享如何在專案中加入 JaCoCo Java Code Coverage Library,並透過微軟最新推出的 Live Preview 這個 VSCode 擴充套件查看報告。
測試覆蓋率報告設定步驟
雖然 JaCoCo 有個 Maven Plug-in 可用,不過官網文件寫的真的很不清楚。以下是產生測試覆蓋率報告的完整設定步驟:
-
加入 jacoco-maven-plugin
外掛的 Maven 設定到 pom.xml
檔案中
請加入以下片段到 <build>
的 <plugins>
區段下:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
請加入以下片段到 <reporting>
的 <plugins>
區段下:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
</plugin>
-
使用 Maven for Java 執行測試
執行測試的過程會產生一個測試覆蓋率報告,檔案路徑為 target/jacoco.exec
,這是一個 binary format 的檔案,我們沒辦法直接閱讀其內容,但有一些第三方工具是可以解析這個檔案的,例如。
Sonar Qube 可以利用這個檔案產生測試覆蓋率報告與程式碼複雜度報告,詳細步驟請參見 Code Coverage with SonarQube and JaCoCo 文章。
還好我們在 jacoco-maven-plugin
外掛中可以找到一個 jacoco:report 目標,執行這個目標就會自動產生 HTML, CSV 與 XML 格式的測試覆蓋率報告,檔案路徑位於 target/site/jacoco/
目錄下,其中有個 index.html
就是我們 HTML 報告的主要檔案。
注意:jacoco-maven-plugin
外掛的 jacoco:report 目標,預設綁定到 verify
生命週期階段(lifecycle phase),所以當你執行 mvn verify
的時候,也會自動執行測試並產生報告:
-
安裝 VSCode 的 Live Preview 擴充套件
-
找到 target/site/jacoco/index.html
檔案,按下滑鼠右鍵,點擊 Live Preview: Show Preview 就可以產生即時預覽畫面!
此時你就可以看到非常清楚的測試覆蓋率報告:
最後一張圖片顯示的事 JaCoCo 報表對於特定方法的分析狀況,幫你你用比較視覺化的方式理解程式碼覆蓋率。其中「有底色」的部分顯示的是每一行程式碼的覆蓋率情形。而有些地方會出現「鑽石」則代表程式邏輯包含了分支,會需要多個測試案例才能完整覆蓋這些地方。
以下是不同鑽石顏色代表的意義:
- 紅色鑽石 (Red diamond) 代表這個分支並沒有被測到。
- 黃色鑽石 (Yellow diamond) 代表這個分支只有被部分覆蓋到,有些分支沒有測到。
- 綠色鑽石 (Green diamond) 代表所有分支都有被完整測試到。
閱讀測試覆蓋率報告
表格上的欄位介紹:
-
Element
代表報告項目的對象,可能是 package 或 class 或 method,有連結的話可以點擊進去看更細部的報告。
-
Missed Instructions
這部分又稱 Lines coverage,但這裡指的 Lines 是指 Java bytecode 的指令集數量,而非 Java 的程式碼數量。
紅色部分代表未被測試覆蓋的測試程式碼 (bytecode instructions),綠色代表有測試到的比例。
旁邊的 Cov.
代表測試覆蓋率。
-
Missed Branches
這部分又稱 Branches coverage,但這裡指的 Branches 是指「判斷式」的分支數量,如果你的程式碼中有個 if
/ else
/ switch
語句,裡面用到的所有判斷式,那麼對程式邏輯來說,這就是一個「分支」,如果你的測試案例不夠多,可以測試到的「分支」就自然會有所缺漏,這裡就是顯示出你有多少「分支」沒有被測試到。
代表沒有測到的分支比例。這裡的「分支」就是
旁邊的 Cov.
代表分支覆蓋率。
-
Missed / Cxty
這部分又稱 Cyclomatic complexity (循環複雜度),意味著程式碼有多複雜,你要經過多少路徑才能測過所有程式碼。
如果 Missed / Cxty 分別是 61 / 66 的話,那麼就代表這個 package 有 66 條不同的路徑,但有 61 條路徑都沒有測試到。如果有某個方法 (method) 完全沒有 if
或 switch
判斷式,那麼這個程式的 複雜度(complexity) 為 1
。
-
Missed / Lines
這裡的 Lines 就真的是 Java 程式碼的行數了,而非 Bytecode 的指令集數量。Missed 就是沒有測試到的數量。
-
Missed / Methods
這裡的 Methods 指的是類別中的方法數量。Missed 就是沒有測試到的數量。
-
Missed / Classes
這裡的 Classes 指的是類別的數量。Missed 就是沒有測試到的數量。
相關連結