4

Maven整合JaCoCo和Sonar,看看你的测试写够了没

 2 years ago
source link: https://www.pkslow.com/archives/maven-jacoco-sonar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

单元测试是保证代码质量的重要一环,而如何衡量单元测试写得好不好呢?覆盖率(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

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="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>

                </configuration>
                <executions>
                    <execution>
                        <id>jacoco-initialize</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <phase>test-compile</phase>
                    </execution>

<!--                    <execution>-->
<!--                        <id>check</id>-->
<!--                        <goals>-->
<!--                            <goal>check</goal>-->
<!--                        </goals>-->
<!--                    </execution>-->

                    <execution>
                        <id>jacoco-site</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

    <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>
<!--                <sonar.login>admin</sonar.login>-->
<!--                <sonar.password>admin</sonar.password>-->
                <sonar.login>9656c84090b2481db6ea97b6d14d87d546bff619</sonar.login>

            </properties>
        </profile>
    </profiles>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <jacoco.version>0.8.5</jacoco.version>
    </properties>

</project>

欢迎关注微信公众号<南瓜慢说>,将持续为你更新...

推荐阅读:
如何制定切实可行的计划并好好执行
容器技术(Docker-Kubernetes)
SpringBoot-Cloud相关
Https专题


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK