代码之家  ›  专栏  ›  技术社区  ›  neaGaze

jacoco+junit 5.0动态测试不工作

  •  1
  • neaGaze  · 技术社区  · 6 年前

    我正在尝试使用带有junit 5和spring boot的jacoco生成代码覆盖率报告。我正在尝试使用junit 5的动态特性。它成功运行,但jacoco生成的测试覆盖率报告中不包括动态测试。JUnit5动态测试目前不在Jacoco的范围内吗?

    代码如下:

        @RunWith(JUnitPlatform.class)
        @SelectPackages("com.troll.jpt.abc.model")
        @SelectClasses({Status.class})
        public class DynamicModelTester {
    
        private Status status;
    
        @BeforeEach
        public void setUp() {
            status = new Status();
        }
    
        @TestFactory
        public Stream<DynamicTest> checkDynamicTestsFromStream() {
    
            List<String> input = Arrays.asList("abc");
            List<String> output = Arrays.asList("abc");
    
            status.setCode(input.get(0));
    
            return input.stream().map(str ->  DynamicTest.dynamicTest("status test", () -> {
                assertEquals(output.get(0), status.getCode());
            }));
        }
    }
    

    我使用的jacoco插件是:

        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.2-SNAPSHOT</version>
            <executions>
                <execution>
                    <id>prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                </execution>
                <execution>
                    <id>post-unit-test</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <!-- Sets the path to the file which contains the execution data. -->
    
                        <dataFile>target/jacoco.exec</dataFile>
                        <!-- Sets the output directory for the code coverage report. -->
                        <outputDirectory>target/jacoco-ut</outputDirectory>
                    </configuration>
                </execution>
            </executions>
            <configuration>
                <systemPropertyVariables>
                    <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                </systemPropertyVariables>
            </configuration>
        </plugin>
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Godin    6 年前

    它成功运行,但jacoco生成的测试覆盖率报告中不包括动态测试。

    jacoco-maven-plugin:report 在测试中不显示覆盖率,而是显示测试目标的覆盖率-在您的案例中,目标似乎是类 Status ,其定义完全不存在。以后我强烈推荐你读 https://stackoverflow.com/help/mcve 并遵循它的建议,特别是关于“完成”的部分:

    确保包含了重现问题所需的所有信息


    关于“jacoco支持junit 5动态测试吗?”是: jacoco记录了这样一个事实:代码的执行与执行方式无关 -通过JUnit 4或JUnit 5,甚至手动或其他执行方式。

    对于“为什么有些代码没有标记为已覆盖”之类的问题,给出了一般性的回答。是: 确保代码实际执行 ,如果是自动测试,这意味着- 确保这些测试实际执行

    但是让我们试试JUnit5动态测试。在没有 src/main/java/Status.java 我想大概是

    public class Status {
    
      private String code;
    
      public void setCode(String code) {
        this.code = code;
      }
    
      public String getCode() {
        return code;
      }
    
    }
    

    不知道你为什么需要 systemPropertyVariables ,快照版本 jacoco-maven-plugin ,多次执行 report 以及 dataFile 以其默认值,因此也将假定 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>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-api</artifactId>
          <version>5.2.0</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-engine</artifactId>
          <version>5.2.0</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
          <version>5.2.0</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.junit.platform</groupId>
          <artifactId>junit-platform-runner</artifactId>
          <version>1.2.0</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
          </plugin>
          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.1</version>
            <configuration>
              <outputDirectory>target/jacoco-ut</outputDirectory>
            </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>prepare-agent</goal>
                  <goal>report</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    
    </project>
    

    放置后

    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.DynamicTest;
    import org.junit.jupiter.api.TestFactory;
    import org.junit.platform.runner.JUnitPlatform;
    import org.junit.platform.suite.api.SelectClasses;
    import org.junit.platform.suite.api.SelectPackages;
    import org.junit.runner.RunWith;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    import static org.junit.Assert.assertEquals;
    
    @RunWith(JUnitPlatform.class)
    @SelectPackages("com.troll.jpt.abc.model")
    @SelectClasses({Status.class})
    public class DynamicModelTester {
    
      private Status status;
    
      @BeforeEach
      public void setUp() {
        status = new Status();
      }
    
      @TestFactory
      public Stream<DynamicTest> dynamicTestsFromStream() {
        List<String> input = Arrays.asList("abc");
        List<String> output = Arrays.asList("abc");
    
        status.setCode(input.get(0));
    
        return input.stream().map(str ->  DynamicTest.dynamicTest("status test", () -> {
          assertEquals(output.get(0), status.getCode());
        }));
      }
    
    }
    

    进入之内 src/test/java/DynamicModelTester.java 以及执行 mvn clean verify :

    [INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ example ---
    [INFO]
    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ example ---
    [INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
    [INFO]
    [INFO] --- jacoco-maven-plugin:0.8.1:report (default) @ example ---
    [INFO] Skipping JaCoCo execution due to missing execution data file.
    

    最后一行很可疑,而且没有执行的测试数量 maven-surefire-plugin 加上没有 target/surefire-reports/

    让我们重命名 DynamicModelTester 进入之内 DynamicModelTest 并执行 MVN清洁验证 再一次:

    [INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ example ---
    [INFO]
    [INFO] -------------------------------------------------------
    [INFO]  T E S T S
    [INFO] -------------------------------------------------------
    [INFO] Running DynamicModelTest
    [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in DynamicModelTest
    [INFO]
    [INFO] Results:
    [INFO]
    [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    [INFO]
    [INFO]
    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ example ---
    [INFO] Building jar: /private/tmp/jacoco/target/example-1.0-SNAPSHOT.jar
    [INFO]
    [INFO] --- jacoco-maven-plugin:0.8.1:report (default) @ example ---
    [INFO] Loading execution data file /private/tmp/jacoco/target/jacoco.exec
    [INFO] Analyzed bundle 'example' with 1 classes
    

    与上次尝试相比,这次执行了测试。和覆盖报告 target/jacoco-ut/default/Status.html 看起来像:

    coverage report

    我认为测试未执行的原因在于 default value of includes of maven-surefire-plugin :

    指定测试(按模式)的元素列表 应该包括在测试中。当未指定和测试时 未指定参数,默认包括

    <includes>
        <include>**/Test*.java</include>
        <include>**/*Test.java</include>
        <include>**/*Tests.java</include>
        <include>**/*TestCase.java</include>
    </includes>
    

    DynamicModelTester.java 不符合这些模式,而 DynamicModelTest.java 第二个匹配,但我将把这个作为一个小练习来验证。

    推荐文章