My Android app contains both Unit and Instrumental tests, and I'd like to generate a coverage report using the JaCoCo plugin (and then finally porting to coveralls.io ) . But I cannot seem to run gradlew jacocoTestReport on my local machine, because I don't have a emulator or device that connects to Android Studio. The error and complete log is up at https://pastebin.com/c7vcwseF .
Here's the portion of my app's build.gradle that contains the task definition:
# ...
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
def debugTree = fileTree(dir: "$project.buildDir/intermediates/classes/debug", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec'
])
}
coveralls {
jacocoReportPath 'build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml'
}
# ...
I am using the org.jacoco:org.jacoco.core:0.8.2 plugin in my Android project.
So how would one run gradlew jacocoTestReport and generate the report locally?
Related
I have been using the Jacoco plugin to get code coverage for my android project. Currently on executing the test using this command,
gradlew test jacocoTestReport
It runs only the robolectric and UI test. I want to run the Unit test and the robolectric test instead.
Following is the task for Jacoco created inside build.gradle,
task jacocoTestReport(type: JacocoReport, dependsOn: ['test', 'createDebugCoverageReport']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = [ '**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*' ]
def debugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/test.exec', 'outputs/code-coverage/connected/*coverage.ec'
])
}
Is there any way we can achieve the code coverage for unit and robolectric test using Jacoco. Please help if you have any idea regarding this
In Android Studio, I didn't find the option "Run with Code coverage" option for the instrumentation tests which are written under androidTest folder. But whereas I can see it for JUnit test cases which are written in test folder.
Can anyone tell me how to get the coverage for that?
Thanks in advance.
So by your comment i assumed that you setup successfully jacoco in your gradle. Now please change or add below material in your app gradle:
coveralls {
jacocoReportPath = "${buildDir}/reports/coverage/debug/report.xml"
}
The above code make your coverage report in app/build/report/.. And you will get two folder including other. AndroidTest and tests folders. In AndroidTest folder you get coverage folder and browse index.html you will get coverage report of instrumentation test result. Same as tests folder explore it and browse index.html.
Now the main part. You have to write below code in your app gradle
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest','connectedAndroidTest']) {
reports {
xml.enabled = true
html.enabled = true
}
// The lines below make sure we can report against Kotlin and exclude some Android Stuff
def fileFilter = [
'**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
'**/*Test*.*', 'android/**/*.*'
]
def debugTree = fileTree(dir: "$project.buildDir/intermediates/javac/debug/compileDebugJavaWithJavac/classes/", excludes: fileFilter)
def mainSrc = "$project.projectDir/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec'
])
}
After successfully sync you will see a play button beside task jacocoTestRepor... Hit it and select first one like Run yourProject [jacoco]
I am trying to generate jacoco reports, but I keep getting an error when I set the testCoverageEnabled property to true.
java.lang.NoSuchMethodError: No static method $jacocoInit()[Z in class L...
Removing the testCoverageEnabled property I can run the tests but I can not generate reports.
I am using standard Jacoco configurations. Unit tests and integration tests run properly when run independently.
All online references to this issue seem to be specific configuration issues within projects. Any help is appreciated.
Update
apply plugin: 'jacoco'
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: "$buildDir", includes: [
"jacoco/testDebugUnitTest.exec",
"outputs/code-coverage/connected/*coverage.ec"
])
}
I am trying to use the code coverage tools of Jacoco on a Jenkins server for my Android library.
The builds are successful, and the code coverage stats are shown in the report :
However, when I want the details of which lines are covered or not, the page is totally empty:
As this is the thing I need the most, this is pretty annoying...
Here is the part of the gradle file I have for Jacoco:
apply plugin: 'jacoco'
jacoco {
// Use this version for upper ones are broken (with Gradle)
// https://github.com/jacoco/jacoco/issues/288
toolVersion = "0.7.1.201405082137"
}
// Edit covered scope if needed
def coverageSourceDirs = [
'../s3papiandroidclient/src'
]
task jacocoTestReport(type: JacocoReport, dependsOn: "test") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: '../s3papiandroidclient/build/intermediates/classes',
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files('../app/build/jacoco/testUnitTestDebug.exec')
reports {
xml.enabled = true
html.enabled = true
}
}
jacocoTestReport.doFirst{
delete fileTree (dir: "../s3papiandroidclient/build/intermediates/classes", include: "**/*Test.class")
}
Anyone encountered something similar ?
Regards,
Gyoo.
I've been trying to run Jacoco test coverage for quiet some time now. I've tried several possible solutions reported in these topics:
Android test code coverage with JaCoCo Gradle plugin
How do I get a jacoco coverage report using Android gradle plugin 0.10.0 or higher?
Im running the tests in a emulatated device using genymotion.
Here is what i added to build.gradle:
apply plugin: 'jacoco'
android{
jacoco {
version "0.7.1.201405082137"
}
buildTypes{
debug{
testCoverageEnabled = true
}
}
}
jacoco {
toolVersion "0.7.1.201405082137"
}
To run it i use something like
./gradlew clean
./gradlew createFLAVOR_NAMEDebugCoverageReport
The relevant generated files/folder are:
/build/intermediates/coverage-instrumented-classes
/build/intermediates/jacoco
/build/outputs/code-coverage/connected/flavors/MyFlavor/coverage.ec
However, there is nothing # build/reports/jacoco/test/html/index.html or any html page/code coverage report # /build/outputs.
I've also tried to create a dedicated task to build a coverage report:
def coverageSourceDirs = [
'src/main/java',
]
task jacocoTestReport(type: JacocoReport, dependsOn: "connectedAndroidTestFLAVOR_NAMEDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['**/R*.class',
'**/*$InjectAdapter.class',
'**/*$ModuleAdapter.class',
'**/*$ViewInjector*.class'
])
sourceDirectories = files(coverageSourceDirs)
executionData = files("$buildDir/jacoco/connectedAndroidTestMyFlavorDebug.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("$buildDir/intermediates/classes/").eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
}
Then ./gradlew clean and ./gradlew jacocoTestReport. The output is the same as above, so, no html page with coverage report or any other coverage file.
I'm currently using Android Studio v1.0.2 with the latest gradle version.
Im fairly new to gradle, so it is possible im missing something basic here.
Thanks
After spending the whole day chasing this issue i found out what's the problem. Contrary to the examples i've seen the file generated by the testDebug build is not the .exec file #$buildDir/jacoco/testDebug.exec.
With my gradle and studio version the file generated is a .ec #build/outputs/code-coverage/connected/flavors/myFlavor/coverage.ec
I didn't found any relevant information related to this. It may be a recent change, however, by creating a custom JacocoReport task and changing the executionData variable accordingly i've solved the problem.
Here is my implementation:
task jacocoTestReport(type: JacocoReport) {
def coverageSourceDirs = [
'src/main/java'
]
group = "Reporting"
description = "Generates Jacoco coverage reports"
reports {
xml{
enabled = true
destination "${buildDir}/reports/jacoco/jacoco.xml"
}
csv.enabled false
html{
enabled true
destination "${buildDir}/jacocoHtml"
}
}
classDirectories = fileTree(
dir: 'build/intermediates/classes',
excludes: ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Activity*.*',
'**/*Fragment*.*'
]
)
sourceDirectories = files(coverageSourceDirs)
additionalSourceDirs = files(coverageSourceDirs)
executionData = files('build/outputs/code-coverage/connected/flavors/smartcompanion/coverage.ec')
}