springboot多模块工程单元测试jacoco统计代码覆盖率总结

jacoco统计代码覆盖率的文章一搜一大堆,方法也很简单,就是在pom中引用两个插件:

maven-surefire-plugin

jacoco-maven-plugin

其中jacoco-maven-plugin的关键配置为要有两个execution:

一个goal是prepare-agent,即准备agent,实现为代码插桩

一个goal是report,顾名思义,即生成覆盖率报告

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
            <skipTests>false</skipTests>
            <testFailureIgnore>true</testFailureIgnore>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <executions>
            <execution>
                <id>my-prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
            <execution>
                <id>my-report</id>
                <phase>test</phase>
                <goals>
                    <goal>report</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

但是如果是多模块的工程呢?如下面的结构:

├── module1
│   └── pom.xml
├── module2
│   └── pom.xml
├── module3
│   └── pom.xml
├── pom.xml

每个模块都这么配置的话,生成的报告是各自独立的,即会生成3个报告,那么怎么把各个模块的代码覆盖率统计在一起,生成一个聚合的报告呢?

可以参考七个披萨的博客,我觉得他的这篇文章写的特别好,强烈推荐读一下:jacoco插件配置生成单元测试覆盖率报告_七个披萨的博客-CSDN博客_jacoco:report-aggregate

我在这里复述一下其给出的做法:

jacoco提供了报告聚合的能力(goal为report-aggregate,注意与上面提到的report的区别),这就需要有一个模块来做报告聚合,这个模块需要引用所有的其他模块(以上面举例的工程为例,这个模块可以是新增的module4,也可以在module1/2/3中任选一个,一般在多模块的工程中,都会有一个主模块做为启动模块,可以用这个启动模块来做jacoco的报聚合)

划一下重点:

  1. 一个模块配置jacoco的report-aggregate
  2. 这个模块需要引用所有的其他模块

具体做法如下:

第一:在项目根目录下的父pom中添加jacoco-maven-plugin,并配置goal是prepare-agent(这么做的好处是不用在每个module的pom中都重复添加同样的内容)

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
            <skipTests>false</skipTests>
            <testFailureIgnore>true</testFailureIgnore>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <executions>
            <execution>
                <id>my-prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

第二:在聚合模块中配置jacoco聚合报告:

<plugins>
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <executions>
            <execution>
                <id>my-report</id>
                <phase>test</phase>
                <goals>
                    <goal>report-aggregate</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

第三:在聚合模块中引用其他模块(非常重要,只有引用的模块的覆盖率才会被聚合到报告中,未引用的模块的覆盖率不会被收集和聚合):

  <dependencies>
    <dependency>
      <groupId>@project.groupId@</groupId>
      <artifactId>module1</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>@project.groupId@</groupId>
      <artifactId>module2</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>@project.groupId@</groupId>
      <artifactId>module3</artifactId>
      <version>${project.version}</version>
    </dependency>
 </dependencies>

但是我按照上述文章提到的方法配置后,可以得到聚合的报告了,但是覆盖率都为0,这又是怎么回事呢?

搜索了很多文章都无解,最后查看jacoco的help才找到答案:

这里需要涉及另外一个插件:maven-surefire-plugin

需要在maven-surefire-plugin中配置引用jacoco插件的输出属性argLine

原理分析:jacoco在prepare-agent阶段会生成一个属性,这个属性指向jacoco的runtime agent,默认这个属性叫argLine,我们需要在maven-surefire-plugin的配置中,引用这个属性,这样在surefire执行测试时,才会能够找到并挂载jacoco的agent,从而实现代码覆盖率的统计(当然我们也可以自定义这个属性的名字)

        <configuration>
          <argLine>${argLine}</argLine>
        </configuration>

最终在根目录的pom.xml是这样的

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
            <skipTests>false</skipTests>
            <testFailureIgnore>true</testFailureIgnore>
            <argLine>${argLine}</argLine>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <executions>
            <execution>
                <id>my-prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

或者在prepare-agent阶段自定义jacoco输出的属性名,那么你的根pom文件是这样的:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
            <skipTests>false</skipTests>
            <testFailureIgnore>true</testFailureIgnore>
            <argLine>${jacocoArgLine}</argLine>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.5</version>
        <executions>
            <execution>
                <id>my-prepare-agent</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
                <configuration>
                  <propertyName>jacocoArgLine</propertyName>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

好了,这时再去运行一下:

mvn test -Dmaven.test.failure.ignore=true

看看聚合报告的结果吧。

jacoco帮助命令行提示原文如下,有兴趣的英文好的同学可以看看

jacoco:prepare-agent
  Prepares a property pointing to the JaCoCo runtime agent that can be passed as
  a VM argument to the application under test. Depending on the project
  packaging type by default a property with the following name is set:
  
  - tycho.testArgLine for packaging type eclipse-test-plugin and
  - argLine otherwise.
  
  If your project already defines VM arguments for test execution, be sure that
  they will include property defined by JaCoCo.
  
  One of the ways to do this in case of maven-surefire-plugin - is to use syntax
  for late property evaluation:
  
   <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
   <argLine>@{argLine} -your -extra -arguments</argLine>
   </configuration>
   </plugin>
  
  You can define empty property to avoid JVM startup error Could not find or
  load main class @{argLine} when using late property evaluation and
  jacoco-maven-plugin not executed.
  
  Another way is to define 'argLine' as a Maven property rather than as part of
  the configuration of maven-surefire-plugin:
  
   <properties>
   <argLine>-your -extra -arguments</argLine>
   </properties>
   ...
   <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
   <!-- no argLine here -->
   </configuration>
   </plugin>
  
  Resulting coverage information is collected during execution and by default
  written to a file when the process terminates.

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
可以使用 Maven 进行 springboot模块单元测试Jacoco 代码覆盖率统计。 对于多模块项目,需要在父 POM 文件中添加 Jacoco 插件配置,以及指定子模块的测试目录: ```xml <modules> <module>module1</module> <module>module2</module> <module>module3</module> </modules> <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report-aggregate</id> <phase>test</phase> <goals> <goal>report-aggregate</goal> </goals> </execution> </executions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>unit-test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skipTests>false</skipTests> <skip>false</skip> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <argLine>${jacoco.agent.argLine}</argLine> <excludedGroups>org.junit.experimental.categories.ExcludeCategory</excludedGroups> <testFailureIgnore>true</testFailureIgnore> <includes> <include>**/*Test.java</include> </includes> </configuration> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </profile> </profiles> <modules> <module>module1</module> <module>module2</module> <module>module3</module> </modules> <profiles> <profile> <id>unit-test</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <skipTests>false</skipTests> <skip>false</skip> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <argLine>${jacoco.agent.argLine}</argLine> <excludedGroups>org.junit.experimental.categories.ExcludeCategory</excludedGroups> <testFailureIgnore>true</testFailureIgnore> <includes> <include>**/*Test.java</include> </includes> </configuration> <dependencies> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-surefire-provider</artifactId> <version>1.6.2</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </profile> </profiles> ``` 这个配置会在编译和测试时启动 Jacoco 代理,同时在测试后生成 Jacoco 报告。 同时,可以使用 Maven Profiles 来区分测试和生产环境的配置,例如上面的配置中就定义了一个名为 `unit-test` 的 Profile。在执行单元测试时,可以使用命令 `mvn clean test -Punit-test` 来指定使用 `unit-test` Profile。 对于单个模块的项目,可以在模块的 POM 文件中添加 Jacoco 插件配置: ```xml <build> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.7</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> ``` 这个配置会在编译和测试时启动 Jacoco 代理,同时在测试后生成 Jacoco 报告。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值