当前位置: 首页 > 知识库问答 >
问题:

将JaCoCo从离线改为在线,但仍未看到其他模块中的课程覆盖范围

孙钱青
2023-03-14

我有一个大型Maven多模块项目构建。我将使用PowerMock和Jacoco0.7.8以及离线检测从所有测试开始。

尽管这些被称为“单元测试”,但对一个模块中的类的测试确实会调用其他模块中的重要代码。因此,当我们查看生成的报告时,我们看到了与测试相同的模块中的类的复盖率,但我们看不到测试期间执行的其他模块中的类的复盖率。

我的假设是,如果我能够将其更改为使用在线检测,那么得到的覆盖率报告将包括来自当前模块之外的其他模块的类。

构建完成后,我在浏览器中打开了“target/site/jacoco/index.html”文件,发现它只包括当前模块和单个类的覆盖范围。

同样奇怪的是,我粗略地检查了生成的“jacoco.exec”文件。我注意到它肯定比我习惯从其他仍然使用离线仪器的模块看到的要大。我没有任何方法来解释文件的格式,但我确实尝试简单地“cat”文件,只是为了看看我能看到什么。我在测试正在执行的其他模块中看到了表示类名的字符串。

所以,看起来在线检测至少是为其他模块中的类记录数据,但结果报告并没有显示这一点。

以下是“Effective-POM”输出的节选:

  <plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.8</version>
    <executions>
      <execution>
        <id>default-instrument</id>
        <phase>none</phase>
        <goals>
          <goal>instrument</goal>
        </goals>
      </execution>
      <execution>
        <id>default-restore-instrumented-classes</id>
        <phase>none</phase>
        <goals>
          <goal>restore-instrumented-classes</goal>
        </goals>
      </execution>
      <execution>
        <id>default-report</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>report</goal>
        </goals>
      </execution>
      <execution>
        <id>prepare-agent</id>
        <goals>
          <goal>prepare-agent</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
      <execution>
        <id>default-test</id>
        <phase>test</phase>
        <goals>
          <goal>test</goal>
        </goals>
        <configuration>
          <argLine>@{argLine} -Xmx1024m</argLine>
          <includes>
            <include>**/*Test.java</include>
          </includes>
          <systemPropertyVariables>
            <running-unit-test>true</running-unit-test>
            <jacoco-agent.destfile>...\target/jacoco.exec</jacoco-agent.destfile>
          </systemPropertyVariables>
        </configuration>
      </execution>
    </executions>
    <configuration>
      <argLine>@{argLine} -Xmx1024m</argLine>
      <includes>
        <include>**/*Test.java</include>
      </includes>
      <systemPropertyVariables>
        <running-unit-test>true</running-unit-test>
        <jacoco-agent.destfile>...\target/jacoco.exec</jacoco-agent.destfile>
      </systemPropertyVariables>
    </configuration>
  </plugin>

请注意,用于脱机检测的执行具有阶段“none”,因此不使用它们,并且我还设置了“jacoco-agent.destfile”属性,该属性仅用于脱机检测。

共有1个答案

杭镜
2023-03-14

Goalreport仅对当前模块中的类执行分析,并创建仅包含这些类的报表,即使为其他类记录了数据。和目标报告-聚合

Reactor内多个项目的覆盖报告

(例如见下文)

package example;

class A {
  // to be tested in module "a"
  void a() {
    System.out.println("A_a" + fun());
  }

  // to be tested in module "b"
  void b() {
    System.out.println("A_b" + fun());
  }

  // to be mocked by PowerMockito
  static String fun() {
    return "";
  }
}
package example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@PrepareForTest({A.class})
@RunWith(PowerMockRunner.class)
public class ATest {
  @Test
  public void test() {
    PowerMockito.mockStatic(A.class);
    Mockito.when(A.fun()).thenReturn("fun");

    new A().a();
  }
}
package example;

class B {
  // to be tested in module "b"
  void b() {
    System.out.println("B_b" + fun());
  }

  // to be mocked by PowerMockito
  static String fun() {
    return "";
  }
}
package example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@PrepareForTest({A.class, B.class})
@RunWith(PowerMockRunner.class)
public class BTest {
  @Test
  public void test() {
    PowerMockito.mockStatic(A.class);
    Mockito.when(A.fun()).thenReturn("fun");

    PowerMockito.mockStatic(B.class);
    Mockito.when(B.fun()).thenReturn("fun");

    new A().b();
    new B().b();
  }
}

a/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>

  <parent>
    <groupId>org.example</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>a</artifactId>
</project>

b/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>

  <parent>
    <groupId>org.example</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>a</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

  <artifactId>b</artifactId>
</project>

report/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>

  <parent>
    <groupId>org.example</groupId>
    <artifactId>example</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>report</artifactId>
  <packaging>pom</packaging>

  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>a</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>b</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

最后是最重要的部分-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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>example</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

    <jacoco.version>0.7.9</jacoco.version>
    <powermock.version>1.6.6</powermock.version>
  </properties>

  <modules>
    <module>a</module>
    <module>b</module>
  </modules>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-module-junit4</artifactId>
      <version>${powermock.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-api-mockito</artifactId>
      <version>${powermock.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.0.2</version>
      </plugin>
    </plugins>
  </build>

  <profiles>
    <profile>
      <id>coverage</id>
      <modules>
        <module>report</module>
      </modules>
      <dependencies>
        <dependency>
          <groupId>org.jacoco</groupId>
          <artifactId>org.jacoco.agent</artifactId>
          <classifier>runtime</classifier>
          <version>${jacoco.version}</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco.version}</version>
            <executions>
              <execution>
                <id>instrument</id>
                <phase>process-classes</phase>
                <goals>
                  <goal>instrument</goal>
                </goals>
              </execution>
              <execution>
                <id>report</id>
                <!--
                restore original classes before generation of report,
                but after packaging of JAR:
                -->
                <phase>post-integration-test</phase>
                <goals>
                  <goal>restore-instrumented-classes</goal>
                  <goal>report</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.12.2</version>
            <configuration>
              <systemPropertyVariables>
                <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
              </systemPropertyVariables>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

在这样设置中

mvn clean verify -Pcoverage
    null
mvn package -DskiptTests -Dmaven.jar.forceCreation
<profile>
  <id>coverage</id>
  <modules>
    <module>report</module>
  </modules>
  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>prepare-agent</goal>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>
 类似资料:
  • 似乎有几个问题,这些问题很老了,而且从Java 8对Jacoco的支持开始就发生了变化。 我的项目包含以下结构 我已经这样配置了 主要聚甲醛.xml 一个Pom.xml B pom.xml 我正在执行这个命令< code>mvn clean package。我可以看到jacoco.exec正在生成,但是我看不到任何验证数据的HTML报告。 请帮帮我。另一点是,我的配置对于项目是否正确? 更新 已识

  • 我有一个问题,在声纳Qube v6.7中,线路覆盖范围低于哈科报告。 当我打开声纳时,我的类文件有很多未覆盖的行。打开 jacoco 报告时,它显示这些行已覆盖。 我正在使用gradle插件。(v2.6) 有什么想法可以是问题吗?

  • 我正在进行Maven多项目构建。我正在使用Powermock模拟用于编写单元测试用例的类。因此,为了获得jacoco的覆盖范围,我正在使用jacoco离线仪器,并设置声纳。dynamicAnalysis=重用报告以获得声纳覆盖范围。当我尝试这样做时,我会收到来自Jacoco和Sonar的错误: 我不知道为什么雅各科试图再次仪器类获得声纳覆盖。我被这个问题困扰了一段时间。任何帮助都会很棒。

  • 我有一个多模块项目,如下所示: 在这个项目中,服务客户端将实现对我正在调用的任何服务的调用,数据模块将只是数据类。目前,雅各科考虑了所有这些模块。有没有办法排除完整的模块,如数据模块或服务客户模块,因为在这两种情况下都不需要UTs?

  • 当我的Jenkins管道失败时,试图从覆盖报告中排除包。我有一个包含所有POJO: s的子项目。我不想为所有这些编写uittest。因此,它们会拖累覆盖范围将低于阈值的分支/线路覆盖范围,并使我的构建失败。 应该可以排除一些包,但我无法让它工作。 我有以下雅各布.gradle文件: 以下是我的声纳.gradle文件中的内容: 在我的build.gradle中: 最后从我的詹金斯文件中: 但是,xx

  • 我一直在尝试在JBoss服务器中实现JaCoCo离线代码覆盖,使用仪表化的EAR进行部署和jacococagent.jar,以便跟踪针对所述JBoss运行的外部集成测试的代码覆盖。 我一直在关注这样的指南: http://www.eclemma.org/jacoco/trunk/doc/offline.html http://automationrhapsody.com/code-coverage