gradle-cobertura-plugin icon indicating copy to clipboard operation
gradle-cobertura-plugin copied to clipboard

Integration test

Open benzen opened this issue 11 years ago • 12 comments

I'm using jettyRun to execute my webapp on a container to execute some integration test on it.

But the instrumented classes are not used by jetty. SO the cobertura report doesn't include execution made using integration tests

benzen avatar Oct 08 '13 20:10 benzen

I've never used jettyRun before, but I'm guessing the issue is with the classpath. The ${project.buildDir}/instrumented_classes directory needs to be ahead of the normal classes directory for the cobertura report to work.

stevesaliman avatar Oct 10 '13 02:10 stevesaliman

I ve tried to add this directory on front or the class path. But with on sucess.

Le 2013-10-09 à 22:27, "Steven C. Saliman" [email protected] a écrit :

I've never used jettyRun before, but I'm guessing the issue is with the classpath. The ${project.buildDir}/instrumented_classes directory needs to be ahead of the normal classes directory for the cobertura report to work.

— Reply to this email directly or view it on GitHub.

benzen avatar Oct 10 '13 11:10 benzen

Is that possible that integration test covera report, and unit test coverage report are in some kind of conflict. With my setup of integration test i had a similar issue. both report where created and puted on the same folder. The index of the first was destroyed when creating the index of the second.

benzen avatar Oct 10 '13 19:10 benzen

Are the unit and integration tests in the same project, or separate sub-projects? If they are different tasks of the same project, I wouldn't expect a report conflict since the cobertura plugin runs all tests and then generates a coverage report from the combined results - assuming that the instrumented classes are used in all tests.

I'm still thinking it is a classpath issue, but I'm not familiar with how jetty works. I'd have to try using it in a project to see what happens, though I don't know when I'd be able to do that...

Steve

stevesaliman avatar Oct 11 '13 01:10 stevesaliman

In my case, these test are two task of the same project.

In the report i've got, there is some part of the code that is marked as never executed, that i know the integration test will use.

That's the way i'm sure that there is something wrong.

benzen avatar Oct 11 '13 12:10 benzen

I've tried these

task integrationTest(type: Test, dependsOn: test) {
  testClassesDir = sourceSets.integrationTest.output.classesDir
  classpath = files("${project.buildDir}/instrumented_classes") + sourceSets.integrationTest.runtimeClasspath
  reports { html { destination = file("build/reports/integrationTest") } }
}

But without sucess, so i've tried this:

integrationTest.doFirst {
  println 'Start Jetty'
  tasks.jettyRun.daemon=true
  tasks.jettyRun.stopPort=8081
  tasks.jettyRun.stopKey="STOP"
  tasks.jettyRun.jettyConfig= file("config/jetty/jetty.xml")
  tasks.jettyRun.additionalRuntimeJars = configurations.runtime
  tasks.jettyRun.contextPath=""
  tasks.jettyRun.webXml=file("src/integrationTest/webapp/WEB-INF/web.xml")
  tasks.jettyRun.classpath= files("${project.buildDir}/instrumented_classes")+ sourceSets.main.runtimeClasspath
  tasks.jettyRun.execute()
}

Which give me this error:

java.lang.ClassNotFoundException: net.sourceforge.cobertura.coveragedata.TouchCollector

As i understand it, i need to add cobertura in the test runtime.

I'm not quite sure what i need to add

benzen avatar Oct 11 '13 17:10 benzen

I've added the testRuntime( 'net.sourceforge.cobertura:cobertura-runtime:2.0.3') in my dependecies and changed my integration test so

integrationTest.doFirst {
  println 'Start Jetty'
  tasks.jettyRun.daemon=true
  tasks.jettyRun.stopPort=8081
  tasks.jettyRun.stopKey="STOP"
  tasks.jettyRun.jettyConfig= file("config/jetty/jetty.xml")
  tasks.jettyRun.additionalRuntimeJars = configurations.runtime
  tasks.jettyRun.contextPath=""
  tasks.jettyRun.webXml=file("src/integrationTest/webapp/WEB-INF/web.xml")
  tasks.jettyRun.classpath= files("${project.buildDir}/instrumented_classes")+ sourceSets.test.runtimeClasspath+ sourceSets.main.runtimeClasspath
  tasks.jettyRun.execute()
}

Which give me this

failed SpringApplication: java.lang.IncompatibleClassChangeError: Implementing class
failed org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext@1ad5686d{/,/Users/benjaminDreux/depot/McGill/service/src/main/webapp}: java.lang.IncompatibleClassChangeError: Implementing class
failed ContextHandlerCollection@5b71b74: java.lang.IncompatibleClassChangeError: Implementing class
failed HandlerCollection@386b5f9a: java.lang.IncompatibleClassChangeError: Implementing class
Error starting handlers
java.lang.IncompatibleClassChangeError: Implementing class

benzen avatar Oct 11 '13 17:10 benzen

I seem to recall seeing this sort of thing before, and if my memory is correct, it had to do with ASM - Cobertura was using 4.x, and my app (or its dependencies) was using 3.x. In this case, it doesn't look like an ASM issue, but I'm wondering if another library in the stack has in incompatible library?

stevesaliman avatar Oct 12 '13 15:10 stevesaliman

I'm using groovy, jersey, spring and jetty. I've seen lot's of people using GAE that run in the same kind of issue. But they all update gae sdk and everythings was corrected

benzen avatar Oct 15 '13 18:10 benzen

Hi,

Did you get integration tests working with Jetty?

Thanks

x12a1f avatar Mar 14 '16 10:03 x12a1f

Sorry, I never did. I've never worked with jetty before, so this one may be outside my area of expertise.

Hopefully some other kind soul with jetty experience will see this and will have some ides?

stevesaliman avatar Mar 17 '16 01:03 stevesaliman

I think this will help you. It helped with an external deployed tomcat WAR. So it should help with Jetty too.

dependencies {
    integrationTestRuntime files("${project.buildDir}/instrumented_classes")
    // Required for some reason although the plugin has it
    integrationTestRuntime 'net.sourceforge.cobertura:cobertura:2.1.1'
 }

task integrationTomcatRunWar(type: com.bmuschko.gradle.tomcat.tasks.TomcatRunWar) {
    stopPort = tomcatStopPort
    stopKey = tomcatStopKey
    contextPath = "my-context"
    daemon = true
}

task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
    dependsOn integrationTomcatRunWar
    finalizedBy project.tasks.cobertura
}

// **Bug in cobertura/tomcat.**
// Tomcat is not respecting the build/cobertura/cobertura.ser location
// So lets copy the cobertura.ser generated by Tomcat to there
task copyCoberturaSer(type: Copy) {
    from 'cobertura.ser'
    into 'build/cobertura'
}
coberturaReport.dependsOn copyCoberturaSer


war {
    classpath = sourceSets.integrationTest.runtimeClasspath
}

This two helped me understand the issue https://discuss.gradle.org/t/running-junit-tests-with-gradle-built-classes-dependent-on-signed-jars/7585/3 http://stackoverflow.com/questions/1660141/java-measure-code-coverage-for-remote-scripting-tests

daroay avatar May 25 '16 21:05 daroay