How do I get a jacoco coverage report using Android gradle plugin 0.10.0 or higher?
Over the hundreds of times searching the answer to getting a coverage report, I finally found an exact answer what I want.
From the this blog post, I found that gradlew createDebugCoverageReport
creates the jacoco coverage report.
Also, from the gradle plugin source code, the plugin uses jacoco 0.6.2.201302030002 by default. (therefore, jacoco version definition is not required if you are going to use a default version)
In summary, the ESSENTIAL steps to get a jacoco
coverage report with Android gradle plugin are:
- Android gradle plugin version 0.10.0 or higher (typically in your project's
build.gradle
) - add
testCoverageEnabled true
to the build type you want (i.e.debug
) - run
$ gradlew createDebugCoverageReport
orgradlew connectedCheck
to get ajacoco
coverage report.
You can find your coverage report at the build/reports/coverage/{buildType}
. (i.e. build/reports/coverage/debug
for debug build)
(Add multi-flavor case from @odiggity's comment)
If your project uses multi-flavor configuration, use create{flavorName}CoverageReport
instead. The coverage report will be generated at build/reports/coverage/{flavorName}/{buildType}
.
Example for flavor krInternal with debug build type:
- Command:
./gradlew createKrInternalDebugCoverageReport
- Report is genarated at:
build/reports/coverage/krInternal/debug
Tip :
Since you can only get a coverage report with the emulator
and device with root permission
, you'll get following error after running a command on the regular(non-rooted) device:
05:48:33 E/Device: Error during Sync: Permission denied
java.io.IOException: com.android.ddmlib.SyncException: Permission denied
at com.android.builder.testing.ConnectedDevice.pullFile(ConnectedDevice.java:114)
at com.android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.java:158)
at com.android.builder.internal.testing.SimpleTestCallable.call(SimpleTestCallable.java:42)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:695)
Caused by: com.android.ddmlib.SyncException: Permission denied
at com.android.ddmlib.SyncService.doPullFile(SyncService.java:511)
at com.android.ddmlib.SyncService.pullFile(SyncService.java:320)
at com.android.ddmlib.Device.pullFile(Device.java:849)
at com.android.builder.testing.ConnectedDevice.pullFile(ConnectedDevice.java:107)
... 10 more
:myDirections:connectedAndroidTest FAILED
FAILURE: Build failed with an exception.
Travis-CI build script to get code coverage
Include this block in build.gradle, for all modules (library, sample, etc)
android {
lintOptions {
abortOnError false
}
}
Below is the .travis-ci.yml
file
language: android
jdk: oraclejdk8
sudo: required
android:
components:
# Uncomment the lines below if you want to
# use the latest revision of Android SDK Tools
- tools
- platform-tools
# The BuildTools version used by your project
- build-tools-28.0.3
# The SDK version used to compile your project
- android-28
- android-22
- add-on
# Additional components
- extra-google-google_play_services
- extra-android-support
- extra-google-m2repository
- extra-android-m2repository
# Specify at least one system image,
# if you need to run emulator(s) during your tests
- sys-img-armeabi-v7a-android-22
licenses:
- 'android-sdk-preview-license-52d11cd2'
- 'android-sdk-license-.+'
- 'google-gdk-license-.+'
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
before_install:
- yes | sdkmanager "build-tools;28.0.3"
before_script:
- echo no | android create avd --force -n test -t android-22 --abi armeabi-v7a -c 100M
- emulator -avd test -no-audio -no-window &
- android-wait-for-emulator
- sleep 180
- adb devices
- adb shell input keyevent 82 &
script:
- ./gradlew build connectedCheck
after_success:
- bash <(curl -s https://codecov.io/bash)
android jacoco coverage shows 0% with gradle however there are 95% tests covering code
Generation of coverage for your project using command
./gradlew clean createDebugCoverageReport
works just fine:
The only thing that I changed - is compileSdkVersion
from 23
to 25
and buildToolsVersion
from 23.0.1
to 25.0.2
, because this is the versions that I have.
Jacoco Code Coverage in android studio
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.
How to get code coverage using Android Studio?
With the new Android Studio 1.2, you are able to run your unit tests and see the coverage all within the IDE.
First, you'll need to get your unit tests running in the IDE. (if you already can, then skip this step)
This guide and demo will help you.
Secondly, you'll need to create a JUnit Run configuration
Inside this configuraiton, you'll be able to choose
- Test Kind: "All in Package"
- Package: [the package where your tests reside, eg: "com.myapp.tests"]
- Search for tests: Across Module Dependencies (could be diff for your
setup) - VM -options: -ea
- Working Directory: [your project's directory]
- Use classpath of mod: [select your module]
If you have any issue creating your JUnit Run Configuration, you should visit this guide for help.
Lastly, in the latest Android Studio, you should be able to run your JUnit-Run Configuration by clicking on the 'Run with Coverage' button.
In Android Studio 2.1.3 the is label Run Unit tests with Coverage
where Unit test
is the name of your test configuration as shown in the following screenshot:
Related Topics
How to Select Multiple Images from Gallery in Android
How Get Permission for Camera in Android.(Specifically Marshmallow)
"Gps" Location Provider Requires Access_Fine_Location Permission for Android 6.0
Which Can Replace Capturepicture Function
Android Webview - Intercept Clicks
Broadcastreceiver for Location
Android Studio Build.Gradle Warning Message
How Can Write Code to Make Sharedpreferences for Array in Android
How to Show and Hide Actionbar with Appcompat V.7
Applying Colorfilter to Imageview with Shapeddrawable
Using Adb Logcat with a Real Phone (And Not the Emulator)
Why Getspeed() Always Return 0 on Android
Android Listview Row Delete Animation
How to Monitor Sim State Change