一、jacoco 簡介
jacoco 是一個開源的覆寫率工具,它針對的開發語言是 java。其使用方法很靈活,可以嵌入到 ant、maven 中;可以作為 Eclipse 插件;可以作為 javaAgent 探針監控 java 程式等等。
很多第三方的工具提供了對 jacoco 的內建,如 sonar、jenkins 等等。
jacoco 包含了多種尺度的覆寫率計數器,包含指令級覆寫(Instructions,C0coverage)、分支覆寫(Branches,C1coverage)、圈複雜度(CyclomaticComplexity)、行覆寫(Lines)、方法覆寫(non-abstract methods)、類覆寫(classes),其含義如下:
- 行覆寫率:度量被測程式的每行代碼是否被執行,判斷标準行中是否至少有一個指令被執行。
- 類覆寫率:度量計算 class 類檔案是否被執行。
- 分支覆寫率:度量 if 和 switch 語句的分支覆寫情況,計算一個方法裡面的總分支數,确定執行和不執行的分支數量。
- 方法覆寫率:度量被測程式的方法執行情況,是否執行取決于方法中是否有至少一個指令被執行。
- 指令覆寫:計數單元是單個 java 二進制代碼指令,指令覆寫率提供了代碼是否被執行的資訊,度量完全獨立源碼格式。
- 圈複雜度:在(線性)組合中,計算在一個方法裡面所有可能路徑的最小數目,缺失的複雜度同樣表示測試案例沒有完全覆寫到這個子產品。
二、jacoco 和 maven 內建
2.1 mvn 指令增加參數
在執行 mvn 指令時,加上 "org.jacoco:jacoco-maven-plugin:prepare-agent" 參數即可。示例:
mvn clean test org.jacoco:jacoco-maven-plugin:0.8.5:prepare-agent install -Dmaven.test.failure.ignore=true
其中,jacoco-maven-plugin 後面跟的是jacoco的版本。"-Dmaven.test.failure.ignore=true" 建議加上,否則如果單元測試失敗,就會直接中斷,不會産生 .exec 檔案。
執行以上指令後,會在目前目錄的 target 目錄下産生一個jacoco.exec檔案,該檔案就是覆寫率的檔案。
總體說來,這種方式比較簡單,在與 jenkins 內建時也非常友善。
2.2 在 pom 檔案中使用 jacoco 插件
首先,需要添加 jacoco 的依賴:
<properties>
<jacoco.version>0.8.5</jacoco.version>
</properties>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
接着,我們需要配置 jacoco-maven-plugin 和 maven-surefire-plugin 内容:
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar=destfile=${project.basedir}/target/coverage-reports/jacoco-unit.exec
</argLine>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<!--檢查代碼覆寫率的插件配置-->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<!--指定生成.exec檔案的存放位置-->
<destFile>target/coverage-reports/jacoco-unit.exec</destFile>
<!--Jacoco是根據.exec檔案生成最終的報告,是以需指定.exec的存放路徑-->
<dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
<includes>
<include>**/service/**</include>
</includes>
<!-- rules裡面指定覆寫規則 -->
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<!-- 指定方法覆寫到50% -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>METHOD</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<!-- 指定分支覆寫到50% -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<!-- 指定類覆寫到100%,不能遺失任何類 -->
<limit implementation="org.jacoco.report.check.Limit">
<counter>CLASS</counter>
<value>MISSEDCOUNT</value>
<maximum>0</maximum>
</limit>
</limits>
</rule>
</rules>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<includes>或<excludes>标簽的值應該是相對于目錄 /classes/ 的編譯類的類路徑(而不是包名),用來指定哪些類需要進行單元測試。
另外 maven 的測試類需要遵循相應的規範命名,否則無法運作測試類,無法生成測試報告以及覆寫率報告。jacoco 使用的是 maven-surefire-plugin 插件,它的預設測試類名規範是:
- Test*.java:以 Test 開頭的 Java 類;
- *Test.java:以 Test 結尾的 Java 類;
- *TestCase.java:以 TestCase 結尾的 Java 類;
或者可以在pom中自定義測試類:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Tests.java</include>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/Abstract*.java</exclude>
</excludes>
</configuration>
</plugin>
<rules> 指定篩選規則。
接着運作 mvn test 生成 index.html,即覆寫率報告

推薦閱讀:
- ant 內建 jacoco:http://eclemma.org/jacoco/trunk/doc/ant.html
- eclipse 使用 jacoco:http://www.eclemma.org/