I have a groovy project which I am trying to upload code coverage generated by Cobertura (I’ve also tried jacoco with no luck) to Sonar for.
I’m using gradle as my build framework and I’ve been stumbling over a variety of issues, but I finally have a stable build showing up in Sonar with all desired metrics BUT code coverage.
The Cobertura / Jacoco coverage files are definitely being created in the build directory of the project, but for some reason they never make it to sonar.
I’m using an ant task to generate the code, but anyways here are the relevant portions of my build.gradle file -
apply plugin: "groovy"
apply plugin: "eclipse"
apply plugin: "maven"
apply plugin: "application"
apply plugin: "sonar"
sourceSets {
main {
groovy { srcDir 'src/main/groovy' }
resources { srcDir 'src/main/resources' }
}
test {
groovy {
srcDirs = ['src/test/groovy', 'src/integration-test/groovy']
resources {
srcDir = 'src/test/resources'
}
}
}
}
def cobSerFile="${project.buildDir}/cobertura.ser"
def srcOriginal="${sourceSets.main.output.classesDir}"
def srcCopy="${srcOriginal}-copy"
dependencies {
...
testRuntime 'net.sourceforge.cobertura:cobertura:1.9.3'
...
}
...
test.doFirst
{
ant {
// delete data file for cobertura, otherwise coverage would be added
delete(file:cobSerFile, failonerror:false)
// delete copy of original classes
delete(dir: srcCopy, failonerror:false)
// import cobertura task, so it is available in the script
taskdef(resource:'tasks.properties', classpath: configurations.testRuntime.asPath)
// create copy (backup) of original class files
copy(todir: srcCopy) {
fileset(dir: srcOriginal)
}
// instrument the relevant classes in-place
'cobertura-instrument'(datafile:cobSerFile) {
fileset(dir: srcOriginal,
includes:"**/*.class",
excludes:"**/*Test.class")
}
}
}
test {
systemProperties["net.sourceforge.cobertura.datafile"] = cobSerFile
}
test.doLast {
if (new File(srcCopy).exists()) {
// replace instrumented classes with backup copy again
ant {
delete(file: srcOriginal)
move(file: srcCopy,
tofile: srcOriginal)
}
// create cobertura reports
ant.'cobertura-report'(destdir:"${project.buildDir}/reports/cobertura/coverage",
format:'xml', srcdir:sourceSets.main, datafile:cobSerFile)
ant.'cobertura-report'(destdir:"${project.buildDir.path}/reports/coverage",
format:'html', srcdir:sourceSets.main, datafile:cobSerFile)
}
}
sonar {
server {
url = "http://javawebdev-v1:9000"
}
database {
url = "jdbc:mysql://javawebdev-v1:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true"
driverClassName = "com.mysql.jdbc.Driver"
username = "sonar"
password = "sonar"
}
project {
coberturaReportPath = new File(buildDir, "/reports/cobertura/coverage/coverage.xml")
language = "grvy"
dynamicAnalysis="reuseReports"
}
}
Does anyone have any idea what I’m doing wrong here?
I gave it a shot, but didn’t see anything or even the line ‘Parsing {…xml}’ which is supposed to be indicative of it picking up a cobertura report to parse.
Basically at this point I’m going to fork the sonar plugin, add some more debug information to try to figure out why the report isn’t being parsed, and then I’ll install my own custom verison of the plugin once I figure out why. I’ll reply back here when I have more information later today.
I came up with a fix but it wasn’t easy or pretty.
The groovy sonar plugin is tightly coupled with maven, so if you are using gradle without maven you’re never going to be able to get code coverage to work.
What I had to do was fork the Groovy sonar plugin, and make some modifications to the CoberturaSensor.java file (mainly remove any mention of maven, alter the constructor and any references to the class, etc…)
Once I did that, like magic my code coverage started showing up in Sonar.
It was pretty painful to figure out and it doesn’t sound like many others are having this problem so I won’t go too in depth into the solution, but if anyone needs more info let me know and I’ll be happy to provide it.
Yeah I definitely plan to, I’m constantly frustrated with their lack of gradle support. I already created a comment on their user mailling list since I figured it was a sonar plugin issue. I’ll create a comment on the developer list tonight and see if I can’t get a JIRA created there as well.
I’ll keep on top of it to see if they want my help in implementing a patch but I’m sure they can handle it themselves it the project is still being worked on actively. If not I’ll have to see what other recourse is available.
I don’t have my forked code handy. One of my co-workers took over our gradle / sonar integration effort and I believe she found a new plugin that doesn’t have these issues.
Excellent and thanks for the tip. I was working with sonar runner and hitting the same issue with the cobertura reports, mostly because it appeared to be an issue with the Sonar plugin installed on the server itself. But I wound up taking your code snippet from the JIRA issue and applying it to a fork of sonar-groovy here:
Seems to work from Gradle, Sonar Runner or Maven with this fork installed on the server, but I didn’t test very deeply on the Maven side so I’m not quite ready to issue a pull request back to SonarCommunity.
I am still having the same problem of coverage being shown as a dash. I’m using SonarQube 4.0, Sonar Runner 2.3, and Cobertura 1.9.4.1 (technically I’m using Grails to drive it all through the “code-coverage” plugin v1.2.7, which uses Cobertura). I tried building your latest snapshot for sonar-groovy; I see the “Sensor Groovy CoberturaSensor…” appear in the logs when the runner is going, I see my coverage.xml being referenced, but I don’t see coverage in Sonar web UI.