Gradle & Robolectric & Jacoco & Dagger
As a few have, I stumbled into this $$ jacoco bug. To be fair this is not so much a GradlePlugin bug as more Jacoco/Dagger.
Semantics aside, we wanted to know about our unit test coverage with Robolectric.
Implimentations vary, I based alot of my work off of this template.
Unlike the template I decided to embed Jacoco into my main project. (Maybe a jacoco.gradle
file might be better, but thats trivial).
At time of writing we use:
- Gradle 1.12
- Android Gradle Plugin 0.11.+
- Robolectric plugin 0.11.+
/build.gradle:
// ^^^ Other build stuff up here ^^^
apply plugin: "jacoco"
jacoco {
// I have only tried 0.7.x
toolVersion = "0.7.1.201405082137"
}
// Define coverage source.
// If you have rs/aidl etc... add them here.
def coverageSourceDirs = [
'src/main/java',
'src/gen'
]
// This differs per what flavors buildTypes etc.
// But this example shows the 'testDebug'
// which is standard for Robolectric
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true // coveralls plugin depends on xml format report
html.enabled = true
}
// class R is used, but usage will not be covered, so ignore this class from report
// This differs per plugin version (0.10 -> 0.11)
// have very different fileTrees.
// I have added rules to Ignore Dagger/Butterknife
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['com/myapp/R*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class'
])
sourceDirectories = files(coverageSourceDirs)
executionData = files('build/jacoco/testDebug.exec')
// Bit hacky but fixes https://code.google.com/p/android/issues/detail?id=69174.
// We iterate through the compiled .class tree and rename $$ to $.
doFirst {
new File('myapp/build/intermediates/classes/').eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
afterEvaluate {
// just clean up coveralls dashboard, following reports are not of interest
testDebug.reports.junitXml.enabled = false
}
}
Run: $ ./gradlew jacocoTestReport
Caveat:
I recommend you clean
then assemble
if you are going to build an app after testing.
The $$ -> $
shouldn't break anything, but it's better to be safe than sorry especialy as Dagger and Butterknife use partial reflection to look up some of the generated classes.
Thoughts:
By no means is this script 100% but its about as concise as I could get it for my use case. As the $$ bug has been around since 2011, no one seems to want to fix it. Until then, I can't see any detrimental effect of just renaming the files.
Also I don't care so much about Android Studio / Intelij intergration, we use CI and build stats.
Push & forgot, CI tests and warns.
Follow up
I will add to this when I get (http://coveralls.io)[http://coveralls.io] up and running.