Reputation: 383
I am trying to generate Jacoco code coverage report. I have used AndroidTestCase for my test classes.
I have found using testCoverageEnabled true and using default android -studio default jacoco, ./gradlew connectedCheck or createDebugCoverageReport create the percentage of successfull/fail test cases, but no coverage report.
Then I have tried jacoco {toolVersion "0.7.1.201405082137"}, and task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug"). I have tried to change the dependsOn value with various task. The report shows 0 (zero) test coverage, which is impossible because at least half of all classes are tested.
I have followed various accepted answer of stack overflow in last couple of days. The result is negative.
My gradle file:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
}
}
apply plugin: 'com.android.application'
apply plugin: 'jacoco'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "test.gradle.com.myapplicationtestgradle"
minSdkVersion 21
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile(
'proguard-android.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled true
}
}
jacoco {
version "0.7.1.201405082137"
}
packagingOptions {
exclude 'LICENSE.txt'
}
}
jacoco {
toolVersion "0.7.1.201405082137"
}
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
// exclude auto-generated classes and tests
def fileFilter = ['**/R.class', '**/R$*.class',
'**/BuildConfig.*', '**/Manifest*.*',
'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])
additionalSourceDirs = files([
"${buildDir}/generated/source/buildConfig/debug",
"${buildDir}/generated/source/r/debug"
])
executionData = fileTree(dir: project.projectDir, includes:
['**/*.exec', '**/*.ec'])
reports {
xml.enabled = true
xml.destination = "${buildDir}/jacocoTestReport.xml"
csv.enabled = false
html.enabled = true
html.destination = "${buildDir}/reports/jacoco"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('junit:junit:4.11') {
exclude module: 'hamcrest-core'
}
}
Upvotes: 29
Views: 59067
Reputation: 11726
I had the same problem too, but I made a mistake in the process which took a few days to track down. Here's my technique and the gotcha that caused the 0% coverage.
Install jacoco. I used the technique described in great detail here with a few modifications because of my project's structure. Thank you Ashish Uniyal!
Run jacoco. Open the Gradle window in Android Studio (View -> Tool Windows -> Gradle), click on the elephant icon to "Execute Gradle Task."
If a pop-up to your settings occurs, go ahead and disable the "Do not build Gradle task list during Gradle sync."
In the text window that pops up after clicking the elephant icon, type in: gradle app:createDebugUnitTestCoverageReport
and hit [Enter].
If you want to do AndroidTests, type
gradle app:createDebugAndroidTestCoverageReport
.
It'll take several seconds to a few minutes to execute jacoco.
./app/build/reports/coverage/test/debug/index.html
.My big gotcha was that I typed in the AndroidTest instead of the UnitTest (thank you auto-complete, sigh). Since I only did unit testing all jacoco could see was a big fat 0%.
Upvotes: 0
Reputation: 383
Today I did completely removed android studio, android sdk, gradle. Then reinstall everything. After that, I just added inside the app build.gradle.
debug {
testCoverageEnabled true
}
Then I run ./gradlew connectedChec. Everything is working perfectly. Android studio default Jacoco working fine for me. I think it is also possible to create a jacocoTestReport Task and then create code coverage.I don't know why gradle and android studio was not working previously.
Upvotes: 3
Reputation: 3922
Gradle already has built-in support for generating test coverage reports and we don't need to create any additional configurations or add any plugins to generate test coverage report. Basically, the only thing we need to do is to set testCoverageEnabled
parameter to true
in build.gradle
file as follows:
android {
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
Next, we can execute the following Gradle task from CLI:
./gradlew createDebugCoverageReport
On Windows, we can execute it like this:
gradlew.bat createDebugCoverageReport
Task will analyze code of our project in /src/main/java/
directory and unit tests placed in /src/androidTest/java/
directory.
After executing this task, we can find test coverage report in the following directory of the module:
/build/outputs/reports/coverage/debug/
When we open index.html
file, we can see a visual report from test coverage, which can be viewed in a web browser.
It looks as on the image below.
I've written an article about test coverage report in Android application and published it on my blog some time ago. If you are interested in that topic, you can read it at:
Update (Unit test coverage for Robolectric tests)
If you would like to create test coverage report from unit tests written with Robolectric and generate test coverage report with Jacoco, Travis CI and Codecov.io, please take a look at the new article on my blog:
Upvotes: 50
Reputation: 988
I see that you already got it working, however, there's a simpler method for getting Unit Test execution data. I recently was looking into this as well, I actually made a full write up earlier today.
In my situation, I didn't want to create an additional Gradle task as I wanted the report to be generated as a part of the existing workflow. I also didn't want to explicitly add the Jacoco plugin, as Google already dups the Jacoco Ant tasks for the coverage reports for Instrumentation Tests.
In addition to setting the properties android.jacoco.version
and buildTypes.debug.testCoverageEnabled
, I added the following to the testDebug
JVM arguments to generate execution data:
project.afterEvaluate {
def append = "append=true"
def destFile = "destfile=$buildDir/outputs/code-coverage/connected/coverage.ec"
testDebug.jvmArgs "-javaagent:$buildDir/intermediates/jacoco/jacocoagent.jar=$append,$destFile"
createDebugCoverageReport.dependsOn testDebug
}
This appends the Unit Test execution data to the coverage file generated by connectedAndroidTest
, so your report reflects both Instrumentation Tests and Unit Tests, rather than each variant individually.
Note that connectedAndroidTest
overwrites the coverage file, take this into account when creating your report. If the task testDebug
doesn't have any changes, and you run createDebugCoverageReport
, it will only reflect your Instrumentation Test coverage. So, make a change to your Unit Tests. The Linux command touch
may be useful here, although I haven't tried yet.
Upvotes: 15
Reputation: 2400
i investigated correct way to get merged code coverage report with Jacoco, you can check it here: https://gist.github.com/ultraon/54cca81ca159ed0a4a9ebf62e89c26ba
I used AndroidStudio 2.2.2 with Gradle 3.2 and Android Gradle Plugin 2.2.2
Upvotes: 1