随着向Java 11的迁移,Jacoco的代码覆盖率下降了 [英] Jacoco code coverage dropped with migration to Java 11
问题描述
我有几个使用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屋!