Get coverage info from a coverage.ec file - android

I was using a tool for mobile testing that produces coverage reports on a file called coverage.ec (using EMMA). The file is not readable but I would like to know how to access the info it contains. I just need to read the coverage percentage in general.

I was on a very similar situation. I had a coverage.ec file and I had no idea how to convert it into a readable report. This article was very helpful for me.
There is a lot more information there than you may need, but for me the important part was adding this to build.gradle:
apply plugin: 'jacoco'
def coverageSourceDirs = [
'src/main/java',
'src/debug/java']
task jacocoTestReport(type : JacocoReport, dependsOn : 'testDebugUnitTest') {
group = 'Reporting'
description = 'Generate JaCoCo coverage reports'
reports {
xml.enabled = true
html.enabled = true
}
classDirectories = fileTree(
dir : 'build/intermediates/classes/debug',
excludes : [
'**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*RealmProxy.*',
'**/*ColumnInfo.*',
'**/*RealmModule*.*',
'**/AutoValue_*.*',
'**/Dagger*.*',
'**/*Module_Provide*Factory.*',
'**/*_Factory.*',
'**/*_MembersInjector.*',
'**/*_LifecycleAdapter.*'
]
)
sourceDirectories = files(coverageSourceDirs)
executionData = fileTree(
dir : "$buildDir",
include : [ 'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec' ]
)
doFirst {
files('build/intermediates/classes/debug').getFiles().each { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}}
From here, I placed my coverage.ec file in my app/build/outputs/code-coverage/connected/coverage.ec.
After that, I ran the jacocoTestReport gradle task and it generates a merged report for my unit tests and the reports from the coverage.ec file located in app/build/reports/jacoco/jacocoTestReport/html/index.html
Hope this helps!

Related

How to get code coverage for instrumentation tests in Android

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]

How to run jacocoTestReport when including Android instrumental tests?

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?

How to exclude Fragment from Jacoco code coverage

I have used below code to exclude fragment but I unable to exlcude fragment from jacoco code coverage kindly help me on this.
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/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Fragment*.*'
]
)
sourceDirectories = files(coverageSourceDirs)
additionalSourceDirs = files(coverageSourceDirs)
executionData = files('build/outputs/code - coverage/connected/flavors/smartcompanion/coverage.ec')
}
We used command below :-
gradlew connectedCheck
gradlew connectedAndroidTest
gradlew connectedDubugAndroidTest
Everytime in coverage report we able to see fragment.
There is another way to exclude files, you can filter them out:
classDirectories = fileTree(
dir: 'build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Fragment*.*'
]
).filter ({file -> !file.name.contains('Fragment')})
For some reason I was also unable to exclude fragments. I couldn't find out what went wrong. Filtering them out by name worked though. So it kinda feels like a workaround, but at least I could move on and get my work done.
I also noticed that on Android, the different versions of Gradle and the jacoco plugin are not always very compatible. So it might help to experiment with downgrading (or upgrading) too.

Jacoco code coverage details missing on Jenkins

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.

Jacoco code coverage in Android Studio with flavors

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')
}

Categories

Resources