来自JaCoCo Maven插件的SonarQube集成测试覆盖率显示0%

时间:2015-02-18 17:20:31

标签: maven configuration sonarqube integration-testing jacoco-maven-plugin

我们有一个多模块多语言maven java项目,使用jacoco进行覆盖分析。 模块的主要部分是带有REST API的后端(Java代码),我们的webapp模块包含前端(AngularJS)和java中的Integration-Tests。 我们的Jacoco-IT.exec文件包含大约100Kb的数据,因此我们猜测可以收集集成测试的一些Coverage数据。然而,我们无法在SonarQube中看到任何报道(使用版本5.0和4.5)

我们运行构建项目并使用

运行集成测试
mvn clean install

并使用

分析数据
mvn sonar:sonar

项目被配置为多语言,但我们只是分析了java代码(我们曾经有过单语言配置,但是与覆盖数据相关的结果没有差别)

我们的父母POM:

<properties>
    <hibernate.version>4.2.2.Final</hibernate.version>
    <spring.version>3.2.3.RELEASE</spring.version>
    <resteasy.version>3.0.4.Final</resteasy.version>
    <cucumber.version>1.1.3</cucumber.version>
    <selenium-java.version>2.33.0</selenium-java.version>
    <!-- Sonar -->
    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
    <jacoco.dataFile>${project.basedir}/../target/jacoco-it.exec</jacoco.dataFile>
</properties>
<build>
   <plugins>
       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
                <debug>true</debug>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>

            <executions>
                <execution>
                    <id>default-prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>default-prepare-agent-integration</id>
                    <goals>
                        <goal>prepare-agent-integration</goal>
                    </goals>
                </execution>
                <execution>
                    <id>default-report</id>
                    <goals>
                        <goal>report</goal>
                    </goals>
                </execution>
                <execution>
                    <id>default-report-integration</id>
                    <goals>
                        <goal>report-integration</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.16</version>
        </plugin>
    </plugins>
    <pluginManagement>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.2.201409121644</version>
            </plugin>
    </pluginMangement>
</build>

来自带有集成测试的webapp的POM:

<properties>
    <sonar.sources>src/main</sonar.sources>
</properties>
<build>
    <finalName>web</finalName>
    <plugins>
        <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>8.1.7.v20120910</version>
        <configuration>...</configuration>
        <executions>...</executions>
    </plugin>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <configuration>
                <!-- The destination file for the code coverage report has to be set to the same value
                in the parent pom and in each module pom. Then JaCoCo will add up information in
                the same report, so that, it will give the cross-module code coverage. -->
                <destFile>${project.basedir}/../target/jacoco-it.exec</destFile>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.16</version>
            <executions>
                <execution>
                    <id>default</id>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

正如您在我们的父POM中所看到的,我们将itReportPath配置为位于所有模块的同一目录中。因此,当Sonar分析所有模块时,它始终读取相同的覆盖数据,并应将它们与当前模块的二进制文件中的调试信息对齐。 在maven的分析阶段(mvn sonar:sonar),我们得到一些消息,我们不确定它们是否是一个问题:

对于所有java模块,我们得到以下几行:

    [INFO] [17:30:42.992] Sensor SurefireSensor...
    [INFO] [17:30:42.992] parsing \git\airport-core\rest\target\surefire-reports
    [INFO] [17:30:43.009] Sensor SurefireSensor done: 17 ms
    [INFO] [17:30:43.009] Sensor JaCoCoItSensor...
    [INFO] [17:30:43.010] Analysing \git\airport-core\rest\..\target\jacoco-it.exec
    [INFO] [17:30:43.018] No information about coverage per test.
    [INFO] [17:30:43.018] Sensor JaCoCoItSensor done: 9 ms
    [INFO] [17:30:43.018] Sensor JaCoCoOverallSensor...
    [INFO] [17:30:43.027] Analysing \git\airport-core\rest\target\sonar\jacoco-overall.exec
    [INFO] [17:30:43.046] No information about coverage per test.
    [INFO] [17:30:43.046] Sensor JaCoCoOverallSensor done: 28 ms

“没有关于每次测试覆盖率的信息。”一个问题?好的,我们不知道哪个测试导致了覆盖率,但是我们应该在SonarQube中获得与0%不同的值

对于我们的webapp模块,除了集成测试源本身之外,它不包含任何java源/类,我们得到以下几行:

    [INFO] [17:30:48.370] Sensor JaCoCoItSensor...
    [INFO] [17:30:48.370] No JaCoCo analysis of project coverage can be done since there is no class files.
    [INFO] [17:30:48.370] Sensor JaCoCoItSensor done: 0 ms

这应该不是问题,因为此模块中没有类。 这种观察是否正确?

对于主要部分,我们的配置基于官方的SonarCube演示配置(https://github.com/SonarSource/sonar-examples/tree/master/projects/languages/java/code-coverage/combined%20ut-it/combined-ut-it-multimodule-maven-jacoco),我们刚刚添加了“准备 - 代理 - 集成”目标。当然,它已改为多语言项目。

我们在网上发现了很多被删除的信息(argLine设置等),这些信息对我们没有任何改变。

指向我们使用的文档和教程的链接:

5 个答案:

答案 0 :(得分:2)

在为Jersey配置JaCoCo时,我有同样的经历。我最终应用了 bisection方法,以找出导致整个项目的代码覆盖率降至0%的模块。

如果我没记错的话,最大的惊喜是maven-shade-plugin,它以某种方式破坏了收集的覆盖范围和类的位置之间的关联,导致Sonar显示0%的代码覆盖率。我最终通过将其绑定到阶段none来禁用其执行以修复它(请参阅this commit)。

作为示例,这是如何扩展子模块的pom.xml以便具有工作声纳(假设,声纳用sonar maven配置文件执行。

<profile>
    <id>sonar</id>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <!-- disable parallel execution so that JaCoCo listener can properly work -->
                    <parallel>none</parallel>
                    <perCoreThreadCount>false</perCoreThreadCount>
                    <forkCount>1</forkCount>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <id>shade-archive</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm-debug-all</artifactId>
            <optional>false</optional>
        </dependency>
    </dependencies>
</profile>

答案 1 :(得分:2)

在与Jacoco和Maven打了很长时间之后,只有这样才对我有用:

  1. 在pom.xml中创建配置文件

    <profile>
      <id>coverage-per-test</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
             <!-- disable parallel execution so that JaCoCo listener can properly work -->
              <parallel>none</parallel>
              <perCoreThreadCount>false</perCoreThreadCount>
              <forkCount>1</forkCount>
              <properties>
                <property>
                  <name>listener</name>
                  <value>org.sonar.java.jacoco.JUnitListener</value>
                </property>
              </properties>
            </configuration>
          </plugin>
        </plugins>
      </build>
    
      <dependencies>
        <dependency>
          <groupId>org.sonarsource.java</groupId>
          <artifactId>sonar-jacoco-listeners</artifactId>
          <version>3.10</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    </profile>
    
  2. 将maven surefire插件更新到最新版本

  3. 执行命令:

    mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Pcoverage-per-test -Dmaven.test.failure.ignore=true
    
    mvn sonar:sonar
    
  4. github sonar example

    中描述的相似

答案 2 :(得分:2)

我使用类似的设置,一切都与以下配置完美配合:

然而SmtpSectionPath最初导致了麻烦。这就是我必须在argLine标记中添加SmtpSectionPath的原因,因为maven-surefire-plugin目标是在@{argLine}之前执行的。 (见https://stackoverflow.com/a/25774988

希望我能帮忙

jacoco-maven-plugin:prepare-agent

答案 3 :(得分:0)

考虑其他答案,我想添加一件事,这对于显示Sonar的测试覆盖率非常重要:

  1. 您必须在期望显示覆盖范围之前构建项目:mvn clean install
  2. 你必须在不使用-DskipTests的情况下进行构建
  3. 你必须为运行测试的插件保留正确的配置(surefire,failsafe,... plugin) - 将仅考虑<includes>或类似配置中插件配置中包含的那些测试来显示覆盖率。< / LI>

答案 4 :(得分:0)

我使用JUnit,在我的情况下,问题是因为除了JUnit之外,我的pom.xml中还有TestNG依赖项。删除这种不必要的依赖后,一切都开始按预期工作。