Maven整合JaCoCo和Sonar,看看你的測試寫夠了沒
1 簡介
單元測試是保證程式碼質量的重要一環,而如何衡量單元測試寫得好不好呢?覆蓋率(Coverage)
是一個重要指標。而JaCoCo
則是專門為Java
提供的用於檢測測試覆蓋率的工具,英文全稱為Java Code Coverage
。
本文將講解如何在Maven
專案中整合JaCoCo
,並在SonarQube
中展示。SonarQube
的安裝可以參考這篇文章:
《Docker搭建程式碼檢測平臺SonarQube並檢測maven專案》
2 基本概念
這裡所講的覆蓋率
是指測試程式碼的覆蓋率,這個指標有多種計算方式,如下是比較常用的有:
-
行覆蓋率:執行程式碼行數 / 總程式碼行數,判斷有多少行程式碼被測試執行;
-
類覆蓋率:執行的類 / 程式碼中類總個數;
-
分支覆蓋率:執行的邏輯分支數 / 總的分支數,一般用於檢測是不是
lf/else
都有測試覆蓋; -
方法覆蓋率:執行的方法數 / 程式碼總方法數,檢測是否有方法被遺漏,構造方法也看作為方法。
-
圈複雜度:用於判斷程式碼結構的複雜程式,
JaCoCo
不考慮異常處理的分支;一般認為圈複雜度大於10,就存在比較大的風險,嚴格要求不可大於15。
顏色標識:
JaCoCo
會通過顏色來標識程式碼覆蓋情況,使其一目瞭然。紅色表示沒有覆蓋,綠色表示已經覆蓋,黃色表示部分覆蓋。
執行方式:
執行JaCoCo
有多種方式:
(1)直接通過命令執行:https://www.eclemma.org/jacoco/trunk/doc/agent.html
(2)Ant執行:https://www.eclemma.org/jacoco/trunk/doc/ant.html
(3)Maven執行:https://www.eclemma.org/jacoco/trunk/doc/maven.html
(4)整合IDE執行:https://www.eclemma.org/
我們接下來主要講解maven
的方式。
3 maven整合
3.1 基礎整合
Maven
整合JaCoCo
也容易,配置如下:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<skip>${maven.test.skip}</skip>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
<output>file</output>
<append>true</append>
<excludes>
<exclude>com/pkslow/basic/containsperformance/**</exclude>
<exclude>com/pkslow/basic/ReadPropertiesFile</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<phase>test-compile</phase>
</execution>
<execution>
<id>jacoco-site</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
執行mvn clean test
,則會生成報告target/coverage-reports/jacoco-unit.exec
,但這是人不可讀的,Sonar
可讀的。Intellij Idea
也可以閱讀,按照Run--Show Code Coverage Data
開啟即可。
執行mvn clean verify
,就會生成報告target/site/jacoco/
,有多種格式,用瀏覽器開啟index.html
檔案可以方便檢視。如下圖所示:
3.2 選擇範圍
指定某些類不執行檢測:
<excludes>
<exclude>com/pkslow/basic/containsperformance/**</exclude>
<exclude>com/pkslow/basic/ReadPropertiesFile</exclude>
</excludes>
3.3 規則與閾值
Rules
標籤可以指定檢查閾值,比如類覆蓋率必須為100%
。在configuration
裡面配置如下:
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<limit implementation="org.jacoco.report.check.Limit">
<counter>METHOD</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<limit implementation="org.jacoco.report.check.Limit">
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>0.50</minimum>
</limit>
<limit implementation="org.jacoco.report.check.Limit">
<counter>CLASS</counter>
<value>MISSEDCOUNT</value>
<maximum>0</maximum>
</limit>
</limits>
</rule>
</rules>
這時需要有下面的check
才會執行這個規則校驗:
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
</execution>
如果不滿足條件,maven build
就會失敗。不過,如果我們集成了SonarQube
,我們則會通過SonarQube
來設定這個規則和閾值。
4 提交到Sonar
新增SonarQube
配置資訊如下,有三種配置方式:
(1)配置資料庫資訊
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.jdbc.url>jdbc:postgresql://localhost/sonar</sonar.jdbc.url>
<sonar.jdbc.driver>org.postgresql.Driver</sonar.jdbc.driver>
<sonar.jdbc.username>user</sonar.jdbc.username>
<sonar.jdbc.password>password</sonar.jdbc.password>
<sonar.host.url>http://localhost:9000</sonar.host.url>
</properties>
</profile>
</profiles>
(2)配置使用者名稱密碼
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>http://localhost:9000</sonar.host.url>
<sonar.login>admin</sonar.login>
<sonar.password>admin</sonar.password>
</properties>
</profile>
</profiles>
(3)配置令牌
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>http://localhost:9000</sonar.host.url>
<sonar.login>9656c84090b2481db6ea97b6d14d87d546bff619</sonar.login>
</properties>
</profile>
</profiles>
以上三種都可以,配置完成後,執行命令如下:
mvn clean verify sonar:sonar
如果不想新增配置,可以直接通過命令來指定,命令如下:
mvn clean verify sonar:sonar -Dsonar.host.url=http://localhost:9000 -Dsonar.login=9656c84090b2481db6ea97b6d14d87d546bff619
5 總結
JaCoCo
對專案質量管理作用重大,應該加以使用。最終的maven配置檔案pom.xml
行數太大,請到( https://www.pkslow.com/archives/maven-jacoco-sonar )參考。
6 整合後的pom.xml
整合以後,最終的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.larry</groupId>
<artifactId>JavaBasic</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<configuration>
<skip>${maven.test.skip}</skip>
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
<output>file</output>
<append>true</append>
<excludes>
<exclude>com/pkslow/basic/containsperformance/**</exclude>
<exclude>com/pkslow/basic/ReadPropertiesFile</exclude>
</excludes>
<rules>
<rule implementation="org.jacoco.maven.RuleConfiguration">
<element>BUNDLE</element>
<limits>
<limit implementation