随着向Java 11的迁移,Jacoco的代码覆盖率下降了 [英] Jacoco code coverage dropped with migration to Java 11

查看:106
本文介绍了随着向Java 11的迁移,Jacoco的代码覆盖率下降了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个使用Java 8构建的Gradle项目,最近将它们转换为使用Java 11之后,Jacoco代码覆盖率报告所报告的百分比大大低于以前。在一个项目中,过渡之后,我的覆盖率从81%下降到16%。



我尝试将Jacoco插件更新为0.8.3(官方



如果有帮助,请参阅我的Jacoco Gradle设置。我正在使用自定义插件对其进行配置。

 类ManagedJacocoPlugin实现ManagedPlugin {
@Override
void apply(PluginManager pluginManager){
pluginManager.apply(JacocoPlugin.class)
}

@Override
void configure(Project project,GradlePluginConfig pluginConfig){
def jacoco = project.extensions.getByName( jacoco)
jacoco.toolVersion = 0.8.3

def jacocoTestReport = project.tasks.getByName('jacocoTestReport')
jacocoTestReport.reports {
xml.enabled false
csv.enabled false
}

project.tasks.withType(Test).each {t-> ;
t.jacoco {
destinationFile = project.file( $ project.buildDir / jacoco / test.exec)
}
}

jacocoTestReport .dependsOn integrationTest
}
}

据我所知鉴于我正在使用的工具版本,Jacoco可以全面支持Java 11。我在这里想念什么?

解决方案

这是什么页面



因此,我们可以得出结论,所提供的示例肯定不完整。



让我们再次尝试猜测并添加到 src中/main/java/Example.java

  public void anotherMethod(){
}

并放入 src / test / java / ExampleTest.java

  @Test(groups = unit)
public void test(){
新的Example()。anotherMethod();
}

现在执行 grad clean jacocoTestReport 产生以下报告





因此,我们可以得出结论: Gradle中的某些内容已更改。让我们检查一下它的变更日志- https://docs.gradle.org/5.0/release-notes .html 包含一个非常有趣的语句:


JaCoCo插件现在可用于构建缓存和并行测试执行



...配置了代码覆盖范围的任务被配置为在执行数据开始执行之前删除执行数据...


任务 integrationTest 删除任务 test 收集的数据。让我们尝试不使用相同的文件:

  // project.tasks.withType(Test).each {t-> 
// t.jacoco {
// destinationFile = project.file( $ project.buildDir / jacoco / test.exec)
//}
//}

jacocoTestReport.executionData(测试)
jacocoTestReport.executionData(integrationTest)

现在即使使用Gradle 5.4也会执行 gradle clean jacocoTestReport




I have several Gradle projects that were built using Java 8, and after converting them recently to use Java 11, Jacoco code coverage reports have been reporting much lower percentages than before. On one project, immediately after the transition, my coverage dropped from 81% to 16%.

I tried updating the Jacoco plugin to 0.8.3 (which has official JDK 11 support), Gradle to 5.4, and TestNG to 6.14.3 (not sure if this has any effect; thought it couldn't hurt to be on the latest version). Even after these changes, the project I mentioned above has 16% coverage. I manually checked a few of the classes it reported 0% coverage on and found that they actually did have test coverage on them.

For example, I added this method to one of my classes:

public String helloWorld(){
        return "hello";
    }

I then used it in a test:

@Test(groups = IntegrationTest.INTEGRATION_GROUP)
    public void testHelloWorld() {
        String helloWorld = authManager.helloWorld();
        assertEquals(helloWorld, "hello");
    }

And the coverage reported as 0:

If it's helpful, here are my Jacoco Gradle settings. I'm using a custom plugin to configure them.

  class ManagedJacocoPlugin implements ManagedPlugin {
  @Override
  void apply(PluginManager pluginManager) {
    pluginManager.apply(JacocoPlugin.class)
  }

  @Override
  void configure(Project project, GradlePluginConfig pluginConfig) {
    def jacoco = project.extensions.getByName("jacoco")
    jacoco.toolVersion = "0.8.3"

    def jacocoTestReport = project.tasks.getByName('jacocoTestReport')
    jacocoTestReport.reports {
      xml.enabled false
      csv.enabled false
    }

    project.tasks.withType(Test).each { t ->
      t.jacoco {
        destinationFile = project.file("$project.buildDir/jacoco/test.exec")
      }
    }

    jacocoTestReport.dependsOn "integrationTest"
  }
}

As far as I'm able to gather, Java 11 should be fully supported for Jacoco coverage given the versions of the tools I'm using. What am I missing here?

解决方案

Here is what page https://stackoverflow.com/help/mcve says about How to create a Minimal, Complete, and Verifiable example:

Make sure it's complete

Copy the code from your question into a new file or project, then run it. If it doesn't run for you, then it won't run for anyone else.

However who knows what is ManagedPlugin in your example?

But ok, let's try to follow the above advice and use what we have, pretending that we have time on guessing and that we'll be lucky to guess correctly.

Everything except ManagedPlugin after addition of many missing pieces becomes a following build.gradle

apply plugin: 'java'
apply plugin: 'jacoco'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'org.testng', name: 'testng', version: '6.14.3'
}

test {
    useTestNG() {
        includeGroups('unit')
    }
}

task integrationTest(type: Test, dependsOn: ['test']) {
    useTestNG() {
        includeGroups('integration')
    }
}


def jacoco = project.extensions.getByName("jacoco")
jacoco.toolVersion = "0.8.3"

def jacocoTestReport = project.tasks.getByName('jacocoTestReport')
jacocoTestReport.reports {
    xml.enabled false
    csv.enabled false
}

project.tasks.withType(Test).each { t ->
    t.jacoco {
        destinationFile = project.file("$project.buildDir/jacoco/test.exec")
    }
}

jacocoTestReport.dependsOn "integrationTest"

method helloWorld goes into src/main/Example.java

class Example {
    public String helloWorld() {
        return "hello";
    }
}

method testHelloWorld goes into src/test/ExampleTest.java

import org.testng.annotations.Test;
import static org.testng.Assert.*;

class ExampleTest {
    Example authManager = new Example();

    @Test(groups = "integration")
    public void testHelloWorld() {
        String helloWorld = authManager.helloWorld();
        assertEquals(helloWorld, "hello");
    }
}

Execution of gradle clean jacocoTestReport using Gralde 5.4 and JDK 11.0.1 produces following report

Thus we can conclude that provided example is definitely not complete.

Let's try to guess againg and add into src/main/java/Example.java

    public void anotherMethod() {
    }

and into src/test/java/ExampleTest.java

    @Test(groups = "unit")
    public void test() {
       new Example().anotherMethod();
    }

Now execution of gradle clean jacocoTestReport produces following report

Seems that now we can reproduce your problem.

Why anotherMethod is not covered? Let's follow another great advice from https://stackoverflow.com/help/mcve :

Divide and conquer. When you have a small amount of code, but the source of the problem is entirely unclear, start removing code a bit at a time until the problem disappears – then add the last part back.

which also works not only for code, but for changes in versions - let's try to reverse your change of Gradle version back from 5.4 to 4.10.3 and with it execution of gradle clean jacocoTestReport produces

Thus we can conclude that something in Gradle was changed. Let's check its changelog - https://docs.gradle.org/5.0/release-notes.html contains a very interesting statement:

JaCoCo plugin now works with the build cache and parallel test execution

... the tasks running with code coverage are configured to delete the execution data just before they starts executing ...

Task integrationTest removes data collected by task test. Let's try to not use same file:

//project.tasks.withType(Test).each { t ->
//    t.jacoco {
//        destinationFile = project.file("$project.buildDir/jacoco/test.exec")
//    }
//}

jacocoTestReport.executionData(test)
jacocoTestReport.executionData(integrationTest)

Now execution of gradle clean jacocoTestReport even with Gradle 5.4 produces

这篇关于随着向Java 11的迁移,Jacoco的代码覆盖率下降了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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