1. 程式人生 > 其它 >Maven整合JaCoCo和Sonar,看看你的測試寫夠了沒

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