我试图用gradle jacoco做一个测试覆盖率。
我们的想法是实现组织.gradle.api.tasks.tests.TestListener
,并在常规事件(测试开始和测试结束)和转储覆盖率时重置会话ID。
(演示问题的整个项目位于https://github.com/jayanmn/gradle-coverage-per-test-debug/tree/main )
测试是通过Jacoco-离线测试完成的,使用gradle中的ant任务。(离线,因为测试环境包括一些测试-有点集成类型)。
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.5', classifier: 'runtime'
classpath group: 'org.jacoco', name: 'org.jacoco.core', version: '0.8.5'
}
}
依赖项部分如下所示
dependencies {
//offline instrument via ant task
jacocoAnt group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.5', classifier: 'nodeps'
//the jacoco runtime private for RT.getAgent()
jacocoRuntime group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.5', classifier: 'runtime'
testImplementation 'junit:junit:4.12'
}
运行测试(样本测试)
task sampletest(type: Test) {
ignoreFailures = true
//jars used every step is same.
println classpath.asPath
forkEvery 1
maxParallelForks 1
doFirst {
println "org.jacoco.agent.rt.RT loaded from " + RT.class.getProtectionDomain().getCodeSource()
systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/firsttests.exec'
classpath = files(instrument.outputDir) + classpath + configurations.jacocoRuntime
}
beforeTest { TestDescriptor descriptor ->
println "org.jacoco.agent.rt.RT loaded from " + RT.class.getProtectionDomain().getCodeSource()
}
afterTest { TestDescriptor descriptor ->
//get agent will fail with Agent not started.
systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/aftertests.exec'
//agent not started error
def agent = RT.getAgent()
agent.sessionId = descriptor.name
agent.dump(true)
}
}
出于某种原因
> java.lang.IllegalStateException: JaCoCo agent not started.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':sampletest'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:207)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:205)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:186)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:114)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:356)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: java.lang.IllegalStateException: JaCoCo agent not started.
at org.jacoco.agent.rt.internal_43f5073.Agent.getInstance(Agent.java:77)
at org.jacoco.agent.rt.RT.getAgent(RT.java:33)
at org.jacoco.agent.rt.RT$getAgent.call(Unknown Source)
at build_q0s35v9r0an7s8a7ayxelgpr$_run_closure6$_closure13.doCall(C:\repos\number-utils\build.gradle:91)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:41)
at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:245)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:157)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:346)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:249)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:141)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy69.afterTest(Unknown Source)
at org.gradle.api.internal.tasks.testing.results.TestListenerAdapter.completed(TestListenerAdapter.java:50)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:245)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:157)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:346)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:249)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:141)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy71.completed(Unknown Source)
at org.gradle.api.internal.tasks.testing.results.StateTrackingTestResultProcessor.completed(StateTrackingTestResultProcessor.java:96)
at org.gradle.api.internal.tasks.testing.results.AttachParentTestResultProcessor.completed(AttachParentTestResultProcessor.java:56)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
问题可能是“构建脚本”和测试块的类加载器?添加jacoco代理运行时的正确方法是什么?
您还需要雅各科代理初始化插件。这是专家的例子,但我相信gradle一定有类似的东西:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${basedir}\target\jacoco.exec</destFile>
<propertyName>argLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${basedir}\target\jacoco.exec</dataFile>
<outputDirectory>${basedir}\target</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
afterTest
org.gradle.api.tasks.testing。TestListener
由Gradle在Gradle的VM中执行,而不是在使用JaCoCo的测试的VM中。
为了证明:
对于src/test/java/ExampleTest.java
public class ExampleTest {
@org.junit.Test
public void test() {
System.out.println(java.lang.management.ManagementFactory.getRuntimeMXBean().getName());
}
}
和< code>build.gradle
plugins {
id "java"
}
repositories {
mavenCentral()
}
dependencies {
testImplementation "junit:junit:4.12"
}
test {
testLogging.showStandardStreams = true
afterTest {
System.println(java.lang.management.ManagementFactory.getRuntimeMXBean().getName())
}
}
执行命令< code>gradle build将产生类似
> Task :test
ExampleTest > test STANDARD_OUT
33542@Godin.local
33018@Godin.local
两个数字< code>33542和< code>33018是Java进程的id,正如您所看到的,它们是不同的。
org.jacoco.agent.rt.rt
只能用于与在同一虚拟机中运行的jacoco通信。
要在另一个VM中与JaCoCo通信,您可以使用代理输出
模式tcpClient
和tcpserver
,或者通过JMX使用代理选项jmx=true
-请参阅https://www.jacoco.org/jacoco/trunk/doc/agent.html以及离线检测情况下可用的相同选项-请参阅https://www.eclemma.org/jacoco/trunk/doc/offline.html
想法是实现org.gradle.api.tasks.testing.TestListener,并在常规事件(测试开始和测试结束)和转储覆盖时重置会话ID。
JUnit4有一个<code>org.JUnit.runner.notification。RunListener是在虚拟机内部由JUnit执行测试的,其实现示例与您的想法类似,可以在https://github.com/SonarSource/sonar-java/blob/5.14.0.18788/sonar-jacoco-listeners/src/main/java/org/sonar/java/jacoco/JUnitListener.java
不幸的是,根据https://github.com/gradle/gradle/issues/1330的说法,似乎目前在Gradle中还没有简单的方法来配置JUnit 4以使用< code > org . JUnit . runner . notification . run listener ,但是似乎可以配置JUnit 5以使用其< code > org . JUnit . platform . launcher . testexecutionlistener 。
代码覆盖率在仪表板上显示为 0% build.gradle文件 运行此命令 JacocoTestReport使用正确的代码覆盖率生成 声纳曲渐变任务生成此日志 在谷歌上搜索了半天,这个问题的唯一真正解决方案是:财产的sonar.jacoco。不推荐使用“报告路径”。请使用“声纳”jacoco。改为“报告路径” 此处的答案解释了双重输出: 但是,这似乎尚未添加到gradle插件中,因为正在使用的插件
当运行Gradle的Jacoco插件时,我在一组选定的类上得到零代码覆盖率报告。我已经确认测试这些类的所有单元测试都已成功运行。 非常有趣的是,EclEmma在Eclipse中生成了正确的代码覆盖率结果。我已经确认这两个工具使用的是相同版本的Jacoco。 我想知道这两种工具的区别是什么?我需要Gradle Jacoco插件的额外配置吗。 编辑:我的Gradle Jacoco输出显示“com类的执
我正在尝试集成Jacoco,以便使用Maven获得Cucumber测试的代码覆盖率。以下是我的项目结构: > -src主java页面 -src主java助手 -src-测试-java-资源-功能 -src测试java步骤 以下是我的POM中的Jacoco配置。xml 我能够生成代码覆盖率报告。但是,在报告中,它涵盖了-src主包中的所有类。根据不同的google搜索和SO帖子,我试图修改POM以排
我正在将ANT构建转换为Maven。我不用声纳。 在Maven中,Jacoco似乎并没有报告单元测试本身的覆盖率,而ANT报告。我也一直在尝试为我的Maven build获得这个,但是我没有找到任何东西。 似乎我应该添加一个
我使用JaCoCo进行代码覆盖。单元测试报告是用junit创建的,它们被正确地导入,因此单元测试信息被正确地显示出来。问题是,我得到了错误消息:没有关于每个测试覆盖率的信息。代码覆盖率显示单元测试、集成测试和整体覆盖率的值为0%。我检查了sonar项目中所有需要的信息,如二进制、src、测试等属性。 我使用的是:<br>-SonarQube 4.5.1<br>-SonarRunner 2.4<br