首页 文章

无法让Jacoco使用离线工具与Powermockito合作

提问于
浏览
28

鉴于Jacoco在“动态”工具时不能很好地与PowerMockito配合使用,我一直在尝试配置离线工具,希望这能为我提供适用于使用PowerMockito的类的单元测试覆盖率 .

我已经将我的pom设置如下,但我的测试课程仍然保持0%的覆盖率 . 任何帮助都非常感激,因为它让我慢慢疯狂!

<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>mandy</groupId>
    <artifactId>jacoco-test</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>jacoco-test Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <powermock.version>1.5.4</powermock.version>
        <jacoco.version>0.7.1.201405082137</jacoco.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.agent</artifactId>
            <classifier>runtime</classifier>
            <version>${jacoco.version}</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>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <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>restore-report</id>
                        <phase>prepare-package</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.17</version>
                <configuration>
                    <!--<argLine>${argLine}</argLine>-->
                    <systemPropertyVariables>
                        <!-- JaCoCo runtime must know where to dump coverage: -->
                        <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
        </plugins>
        <finalName>jacoco-test</finalName>
    </build>
</project>

这是我的课程:

public class Utils {

    private Utils() {

    }

    public static String say(String s) {
        return "hello:"+s;
    }
}

这是我的测试:

@RunWith(PowerMockRunner.class)

@PrepareOnlyThisForTest(Utils.class)
@PowerMockIgnore("org.jacoco.agent.rt.*")
public class UtilsTest {

    @Test
    public void testSay() throws Exception {
        PowerMockito.mockStatic(Utils.class);
        Mockito.when(Utils.say(Mockito.anyString())).thenReturn("hello:mandy");
        assertEquals("hello:mandy", Utils.say("sid"));
    }

}

我运行mvn clean install生成jacoco.exe

覆盖率报告(使用ant脚本从jacoco.exec生成): -

Coverage report

9 回答

  • 0

    我和JaCoCo On-the-fly和PowerMock有同样的问题 . 每次都会生成0%的代码覆盖率

    发现JaCoCo版本0.7.7.201606060606和PowerMock版本1.6.2兼容并且代码覆盖成功生成 .

  • 1

    这个pom对我有用:

    <build>
        <finalName>final-name</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <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.18.1</version>
                <configuration>
                    <systemPropertyVariables>
                        <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.2.201409121644</version>
                <executions>
                    <execution>
                        <id>default-instrument</id>
                        <goals>
                            <goal>instrument</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-restore-instrumented-classes</id>
                        <goals>
                            <goal>restore-instrumented-classes</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>default-report</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    

    this链接 .

  • 7

    我看到了同样的行为,虽然在GitHub问题上跟随线程之后,似乎在1.6.5中修复了,这对我来说是正确的 .

    希望这会在以后让人头疼:) .

    工作配置:

    • jacoco-maven-plugin 0.7.7.201606060606

    • powermock 1.6.5

    我没有使用离线仪器 .

  • 0

    我使用PowerMock的javaagent使它工作 . 看到这里:https://code.google.com/p/powermock/wiki/PowerMockAgent

    删除 @RunWith 注释,按照上面的链接中的说明放置 PowerMockRule . 把它公之于众 .

    将以下行放在maven-surefire-plugin配置中:

    -javaagent:${org.powermock:powermock-module-javaagent:jar}
    

    (使用此处描述的技术:Can I use the path to a Maven dependency as a property?

    <?xml version="1.0" encoding="UTF-8"?>
    <project>
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.stackoverflow</groupId>
        <artifactId>q2359872</artifactId>
        <version>2.0-SNAPSHOT</version>
        <name>q2359872</name>
    
        <properties>
            <!-- Must be listed in the dependencies section otherwise it will be null. -->
            <my.lib>${org.jmockit:jmockit:jar}</my.lib>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.jmockit</groupId>
                <artifactId>jmockit</artifactId>
                <version>1.11</version>
            </dependency>
        </dependencies>
        <build>
            <defaultGoal>generate-sources</defaultGoal>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.3</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>properties</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- Example usage: -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.2</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <phase>generate-sources</phase>
                        </execution>
                    </executions>
                    <configuration>
                        <executable>echo</executable>
                        <arguments>
                            <argument>path to jar=</argument>
                            <argument>${org.jmockit:jmockit:jar}</argument>
                            <argument>my.lib=</argument>
                            <argument>${my.lib}</argument>
                        </arguments>
                    </configuration>
                </plugin>
                <!-- end of Example usage -->
            </plugins>
        </build>
    </project>
    
  • 14

    我也面临同样的问题 . 我能够部分生成报告 . 我已将这两个标签用于我的测试用例@RunWith(PowerMockRunner.class)@PrepareForTest({}) . 并且我没有为我使用上述标签的测试案例生成报告 . 但是对于其中一个测试用例,只有@RunWith(PowerMockRunner.class)这个标签 . 不知何故,报告是针对该案例生成的 . 而且我从未使用过离线仪器 . 当我尝试使用离线工具时,我收到错误,说该课程已经过检测 . 我尝试了各种方案,并遵循各种链接,但无法生成报告 . 最后根据上面的评论我将我的powermock版本从1.5.5升级到1.6.5,我能够生成报告 . 以下是我的 pom.xml 条目

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.5.201505241946</version>
        <executions>
            <execution>
                <id>pre-unit-test</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
                 <configuration>
                        <!-- Sets the path to the file which contains the execution data. -->
                        <destFile>${basedir}/target/jacoco.exec</destFile>
                        <!--
                            Sets the name of the property containing the settings
                            for JaCoCo runtime agent.
                        -->
                </configuration>
            </execution>
            <execution>
                <!--<id>post-unit-test</id>
                <phase>test</phase>-->
                <id>default-report</id>
                <phase>verify</phase>
                <goals>
                    <goal>report</goal>
                </goals>
                  <configuration>
                    <!-- Sets the path to the file which contains the execution data. -->
                    <dataFile>${basedir}/target/jacoco.exec</dataFile>
                    <!-- Sets the output directory for the code coverage report. -->
                    <outputDirectory>${basedir}/target/jacoco-ut</outputDirectory>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

    以下是我在 pom .xml for maven-surefire-plugin 的报名

    <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
          <configuration>
                <argLine>@{argLine}</argLine>
                <skipTests>false</skipTests>
                <testFailureIgnore>true</testFailureIgnore>
            </configuration>
        </plugin>
    

    @ was set as a property

    <properties>
        <argLine>-noverify -Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=512m</argLine>
    </properties>
    

    And upgraded my powermock version from 1.5.5 to 1.6.5 . 最后,我可以在我的测试用例中使用以下标记的类看到我的报告生成 @RunWith(PowerMockRunner.class) @PrepareForTest({})

  • 0

    我最终使用离线仪器和Jacoco(类似于你所做的)与sonar一起使用,我能够从中获得覆盖率数字 .

  • 0

    我使用Jacoco离线工具,并在执行测试恢复原始类之后,借助“恢复仪表级”目标 . 我的JaCoCo配置如下所示:

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.7.9</version>
        <executions>
          <execution>
            <id>default-prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
          <execution>
            <id>jacoco-instrument</id>
            <goals>
              <goal>instrument</goal>
            </goals>
          </execution>
          <execution>
            <id>jacoco-restore-instrumented-classes</id>
            <goals>
              <goal>restore-instrumented-classes</goal>
            </goals>
          </execution>
          <execution>
            <id>jacoco-report</id>
            <phase>package</phase>
            <goals>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <excludes>
            <exclude>*</exclude>
          </excludes>
        </configuration>
      </plugin>
    
  • 0

    使用下面的maven插件代码片段,这在jenkins和本地工作正常,并显示PowermockRunner单元测试的完整代码覆盖率

    <build>
                <plugins>
                    <plugin>
                        <groupId>org.jacoco</groupId>
                        <artifactId>jacoco-maven-plugin</artifactId>
                        <version>${jacoco-maven-plugin.version}</version>
                        <executions>
                            <execution>
                                <id>pre-test</id>
                                <goals>
                                    <goal>prepare-agent</goal>
                                </goals>
                                <configuration>
                                    <append>true</append>                           
                                </configuration>
                            </execution>
                            <execution>
                                <id>pre-integ-test</id>
                                <goals>
                                    <goal>prepare-agent-integration</goal>
                                </goals>
                                <configuration>
                                    <append>true</append>                           
                                </configuration>
                            </execution>
    
                            <execution>
                                <id>jacoco-instrument</id>
                                <goals>
                                    <goal>instrument</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>jacoco-restore-instrumented-classes</id>
                                <goals>
                                    <goal>restore-instrumented-classes</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <excludes>
                                <exclude>*</exclude>
                            </excludes>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
    
  • 1

    对我来说,Offline Instrumentation的样本效果很好 .

    但在我的情况下,有一个更简单的解决方案:只是在声明之前不要在@PrepareForTest({})注释中包含测试类 .

相关问题