Jacoco-Gradle adds the agent last to JVM args

Hi

I am having problems getting coverage for my spring-based integrationTests

...
tasks.withType(JavaCompile) {
    options.fork = true
    options.encoding = 'UTF-8'
}
  task integrationTest(type: Test) {
    useTestNG()
    include '**/*IT.class'
    reports.html.destination = file("$reports.html.destination/integration")
    reports.junitXml.destination = file("$reports.junitXml.destination/integration")
      jvmArgs "-javaagent:${configurations.testAgent.files.iterator().next()}"
      // listen to events in the test execution lifecycle
    beforeTest { descriptor ->
        logger.lifecycle("Running test: " + descriptor)
    }
    jacoco {
        append = true
        destinationFile = file(jacocoItReportPath)
        classDumpFile = file("$jacocoOutDir/classpathdumps")
    }
}
...

If I run the tests this way I get the java agents in this order

-javaagent:/Users/rainer/.gradle/caches/modules-2/files-2.1/org.springframework/spring-instrument/3.2.1.RELEASE/de3a33ae6206be1dcc1326d20d6a2a022fcf498b/spring-instrument-3.2.1.RELEASE.jar -javaagent:build/tmp/expandedArchives/org.jacoco.agent-0.6.2.201302030002.jar_6of7cnvrvkf16b2u233la0sipt/jacocoagent.jar=destfile=../reports/jacoco/jacoco-it.exec,append=true,dumponexit=true,output=file,classdumpdir=../reports/jacoco/classpathdumps,jmx=false

I.e. the spring agent goes first followed by the jacoco agent.

In such a case I do not get coverage for the injected (@Autowired) dependencies for my integration tests.

According to

http://stackoverflow.com/questions/17187029/how-to-run-jacoco-with-java-7-and-spring-instrument

the jacoco coverage agent should go first.

I somehow seem to be unable to do this.

Any Help?

Try to wrap your ‘jvmArgs’ line with ‘doFirst { … }’.

PS: Instead of ‘files.iterator.next()’, you can use ‘files.singleFile’.

tried this, but didn’t help :frowning:

task integrationTest(type: Test) {
    useTestNG()
    include '**/*IT.class'
    reports.html.destination = file("$reports.html.destination/integration")
    reports.junitXml.destination = file("$reports.junitXml.destination/integration")
        // listen to events in the test execution lifecycle
    beforeTest { descriptor ->
        logger.lifecycle("Running test: " + descriptor)
    }
    jacoco {
        append = true
        destinationFile = file(jacocoItReportPath)
        classDumpFile = file("$jacocoOutDir/classpathdumps")
    }
    doFirst {
        jvmArgs "-javaagent:${configurations.testAgent.singleFile}"
    }
}

Did you verify that your arg still does not come last?

yup, spring instrument is still first.

BTW singleFile did not work, since gradle reports that there are 3 files in there (odd)

Problem is that the jacoco task (extension) also uses ‘Test#doFirst’ to add its jvm args. I can’t think of a clean way to solve this problem, but you could try a hack such as ‘integrationTest.actions.add(1, { jvmArgs … })’.

IMHO a reasonable solution would be to add a jvmArgs property to the jacoco task or something like that. I don’t really care whether I configure the java agent in the test or in jacoco.

This means that the agent dependency has some transitive deps, which you should probably exclude in the dependency declaration.