使用 Cobertura 和 Jacoco 运行代码覆盖率 [英] Running code coverage with Cobertura and Jacoco

查看:15
本文介绍了使用 Cobertura 和 Jacoco 运行代码覆盖率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为 Maven 插件项目(使用调用程序插件进行集成测试)获取 Sonar 中的集成测试和单元测试的代码覆盖率报告时遇到了一点问题.

I have a bit of a problem getting code coverage reports for both Integration Tests and Unit Tests in Sonar for a Maven Plugin project (which uses invoker plugin for the integration tests).

我不能使用默认的 Jacoco 覆盖工具进行单元测试,因为它们使用 Powermock,这导致使用该工具的类的覆盖率为 0%.另一方面,如果不使用 Jacoco,我找不到可靠的方法来获得基于 Groovy 的集成测试的结果.

I can't use the default Jacoco coverage tool for the unit tests, as these use Powermock, which results in 0% coverage for classes using that. On the other hand, I can't find a reliable way to get results for the Groovy-based integration tests without using Jacoco.

所以我需要让 Cobertura 生成一个单元测试报告,让 Jacoco 生成一个集成测试报告,并且让 Sonar 能够读取很多内容.

So what I need is for Cobertura to produce a Unit Test report, Jacoco to produce an Integration Test report, and for Sonar to be able to read the lot.

我尝试使用此处的示例 https://github.com/Godin/sonar-experiments/tree/master/jacoco-examples/maven-invoker-plugin-example 但消除了绑定到测试阶段的执行,但是我得到了一个单元测试声纳中-"的覆盖范围.我认为这样做的原因是为了让这种方法起作用,我需要将 Jacoco 指定为 Sonar 的核心覆盖工具.

I tried using the example here https://github.com/Godin/sonar-experiments/tree/master/jacoco-examples/maven-invoker-plugin-example but eliminating the executions bound to the test phase, but I then get a unit test coverage of '-' in Sonar. I think the reason for this is that to get this method to work, I need to speicify Jacoco as the core coverage tool for Sonar.

有什么想法可以解决这个问题吗?我的 pom.xml 如下:

Any ideas on a way round this? My pom.xml follows:

<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.acme.myproj.plugins</groupId>
  <artifactId>slice2java-maven-plugin</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>maven-plugin</packaging>

  <name>Slice2Java Maven Plugin</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <sonar.exclusions>**/generated*/*.java</sonar.exclusions>
    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.itReportPath>${project.basedir}/target/jacoco-it.exec</sonar.jacoco.itReportPath>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>3.0.8</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
      <dependency>
          <groupId>org.mockito</groupId>
          <artifactId>mockito-all</artifactId>
          <version>1.9.5</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.powermock</groupId>
          <artifactId>powermock-core</artifactId>
          <version>1.5</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.powermock</groupId>
          <artifactId>powermock-module-junit4</artifactId>
          <version>1.5</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.powermock</groupId>
          <artifactId>powermock-api-mockito</artifactId>
          <version>1.5</version>
          <scope>test</scope>
      </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <goalPrefix>slice2java</goalPrefix>
          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
        </configuration>
        <executions>
          <execution>
            <id>mojo-descriptor</id>
            <goals>
              <goal>descriptor</goal>
            </goals>
          </execution>
          <execution>
            <id>help-goal</id>
            <goals>
              <goal>helpmojo</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>run-its</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-invoker-plugin</artifactId>
            <version>1.8</version>
            <configuration>
              <debug>true</debug>
              <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
              <pomIncludes>
                <pomInclude>*/pom.xml</pomInclude>
              </pomIncludes>
              <postBuildHookScript>verify</postBuildHookScript>
              <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
              <settingsFile>src/it/settings.xml</settingsFile>
              <goals>
                <goal>clean</goal>
                <goal>test-compile</goal>
              </goals>
            </configuration>
            <executions>
              <execution>
                <id>integration-test</id>
                <goals>
                  <goal>install</goal>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.5.3.201107060350</version>
                <configuration>
                    <includes>com.acme.*</includes>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-it.exec</destFile>
                            <propertyName>invoker.mavenOpts</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-it.exec</dataFile>
                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>

推荐答案

既然你已经将 Sonar 配置为

Since you've configure Sonar as

 <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
 <sonar.jacoco.itReportPath>
     ${project.basedir}/target/jacoco-t.exec
 </sonar.jacoco.itReportPath>

这意味着您告诉 Sonar重用来自 sonar.jacoco.itReportPath 的现有报告.如果没有现有报告,则没有任何覆盖范围.

This means you are telling Sonar to reuse the existing report from sonar.jacoco.itReportPath. If there is no existing report, there isn't any coverage.

就我而言,我使用 Cobertura 并使用以下配置属性重用 Maven 站点生成 的报告:

In my case, I use Cobertura and reuse its report from Maven site generation, using the following configuration properties:

<sonar.java.coveragePlugin>cobertura</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.surefire.reportsPath>
    ${project.build.directory}/surefire-reports
</sonar.surefire.reportsPath>
<sonar.cobertura.reportPath>
    ${project.build.directory}/site/cobertura/coverage.xml
</sonar.cobertura.reportPath>

我可以通过以下命令获得重用:

I can get the reuse by using the following command:

mvn clean install site sonar:sonar

我可以使用以下命令重现您的问题:

I can reproduce your issue by using the following command:

mvn clean install sonar:sonar

覆盖率为 0%.由于报告路径中没有现有报告.

The coverage is 0%. Since there is no existing report at the report path.

那么请确保在执行Sonar之前有一个名为jacoco-t.exec"的报告.

Then please make sure that there is a report named "jacoco-t.exec" as specified before executing Sonar.

由于我不熟悉 JaCoCo 并且不知道生成报告文件的 Maven 阶段,我建议执行如下命令:

Since I'm not familiar with JaCoCo and do not know which Maven phase that produces the report file, I would suggest to execute the command like the following:

mvn clean test sonar:sonar

mvn clean install sonar:sonar

还是和我一样

mvn clean install site sonar:sonar

我希望这会有所帮助.

这篇关于使用 Cobertura 和 Jacoco 运行代码覆盖率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆