I have an Android project which is a library and this library comes with its own demo project, as usual.
The library is not developed by me, but I have the code.
If I compile the demo project, with the build.gradle of the library with:
debug {
testCoverageEnabled true
}
Everything works perfectly, the demo project runs and the library works normally, but if I change to:
debug {
testCoverageEnabled false
}
When running the demo project I get the following error:
java.lang.NoClassDefFoundError: Failed resolution of: lorg/jacoco/agent/rt/internal_8ff85ea/Offline;
My problem is that I integrate this library (aar) in my own project and when I execute it, I always get the same error that the library gives when indicating testCoverageEnabled false.
I have tried to create the aar with testCoverageEnabled false even if it does not compile, I have changed the testCoverageEnabled in my project, etc... but I always get the same error.
It is important to say that jacoco is not implemented neither in the library nor in my project... No implementations, no plugin… nothing, I think this is very strange.
Updating gradle to the latest versions I don't get positive results.
How can I fix this?
I hope I have explained myself well.
Thanks in advance.
Have you tried adding jacoco to your project? It may just be that this library is looking for it, and is erroring out when it can't find it.
To add jacoco to your project, you can do the following:
in your app-level build.gradle add the following to the top:
apply plugin: 'jacoco'
apply from: '../app/jacoco.gradle' // the path to your jacoco.gradle file
Create a jacoco.gradle file. This is what mine looks like, update yours as needed
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.6"
reportsDir = file("$buildDir/reports")
}
task jacocoTestReportDebug(type: JacocoReport, dependsOn: ['testDevDebugUnitTest']) {
// "debug" build type for test coverage
group = "reporting"
description = "Generate unified Jacoco code coverage report"
reports {
xml.enabled false
csv.enabled false
}
// update this to include any areas we don't need or cannot test
def fileFilter = []
def javaDebugTree = fileTree(dir: "${buildDir}/intermediates/javac/devDebug", excludes: fileFilter)
def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/devDebug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories.from = files([mainSrc])
classDirectories.from = files([javaDebugTree, kotlinDebugTree])
// Target both java and kotlin build folder
executionData.from = fileTree(dir: "$buildDir", includes: [
"jacoco/testDevDebugUnitTest.exec",
"outputs/code-coverage/connected/*coverage.ec"
])
}
Hopefully this solves the issue! Otherwise, please post the full stack trace to help us debug further.
Related
I am in the process of modularising the app I am working on and my coverage has dropped over 20% since splitting my instrumentation tests into the app module.
The app is being split into app, core, custom, where core is an android library and the other 2 modules are apps. The majority of the app's functionality will live in core and it is currently mostly tested through instrumentation tests which now reside in app.
Is there a way that instrumentation tests in an application module can generate a coverage report that will include library module sources?
I looked at this question here which bears great similarity to my dilemma but this seems outdated as publishNonDefault is deprecated and does nothing as libraries now publish all variants
My efforts are ongoing on this PR
It will be difficult to complete modularisation with such a drop of coverage, I would expect the coverage to be unchanged post modularisation.
EDIT: I have created a repro project here
Eventual answer came from here so all credit to them. Posting the contents of the file here for anybody looking in the future
apply plugin: 'jacoco'
jacoco {
toolVersion = "$jacocoVersion"
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) {
group "Reporting"
description "Generate Jacoco coverage reports."
reports {
xml.enabled = true
html.enabled = true
html.destination file("${rootProject.buildDir}/coverage-report")
}
def javaClasses = []
def kotlinClasses = []
def javaSrc = []
def kotlinSrc = []
def execution = []
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*']
rootProject.subprojects.each { proj ->
javaClasses << fileTree(dir: "$proj.buildDir/intermediates/javac/debug", excludes: fileFilter)
kotlinClasses << fileTree(dir: "$proj.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
javaSrc << "$proj.projectDir/src/main/java"
kotlinSrc << "$proj.projectDir/src/main/kotlin"
execution << fileTree(dir: proj.buildDir,
includes: ['jacoco/testDebugUnitTest.exec',
'outputs/code_coverage/debugAndroidTest/connected/**/*.ec'])
}
sourceDirectories = files([javaSrc, kotlinSrc])
classDirectories = files([javaClasses, kotlinClasses])
print execution
executionData = files(execution)
doLast() {
print "file://${reports.html.destination}/index.html"
}
}
FileFilter probably needs some improvement for a modern Android application eg Dagger/ViewBinding.
I applied this in my app/build.gradle and after running gradlew jacocoTestReport the report with full coverage was present in [projRoot]/build/coverage-report.
Repro project has been updated with the solution.
See the JacocoMerge task which can merge multiple jacoco execution files into a single file. You can then generate a JacocoReport from the merged exec file
No.
Just add your instrumentation tests to the module that has the code under test.
Was under a misconception that instrumentation tests could not be run on a library project due to this SO answer, I have proposed an edit to reflect the up to date documentation.
EDIT: I later found a solution but honestly it probably should not be used and this is the path you should go down. Instrumentation tests probably shouldn't be used for coverage to begin with and unless you are stuck with legacy do not use the solution presented on this page.
See the JaCoCo plugin docs which show that a task named "jacocoTestReport" is added by the JaCoCo plugin. And you can see there's an "additionalSourceDirs" property on the JacocoReport task
So you can do something like
apply plugin: 'java-library'
apply plugin: 'jacoco'
evaluationDependsOn ':another-project'
tasks.withType(JacocoReport) {
def otherSourceSet = project(':another-project').sourceSets.main
additionalSourceDirs.from otherSourceSet.allJava
additionalClassDirs.from otherSourceSet.output
}
I'm trying to do Sonar Setup with Jacoco for Kotlin to generate Code Coverage report but it's not showing any code coverage. While checking Sonar Console it showing following error. Anyone has faced this issue before, any suggestion what could be miss.
Meta info
plugin using sonarqube version "2.6.1"
gradleVersion = '3.0.1'
kotlinVersion = '1.2.21'
Sonarqube version = Version 6.7.1 (build 35068) - LGPL v3
Frustrating part is, my setup project generating blank code coverage report :(. PFA.
Edit : Please find project structure snap.
I'm adding sonar & Jacoco gradle file setup I'm using to generate sonar-matrix report.
Here is sonar.gradle file:
sonarqube {
properties {
property "sonar.projectKey", "jacoco.sonar.test"
property "sonar.projectName", "Sonar Jacoco Test"
property "sonar.projectVersion", "1.1"
property "sonar.java.source", "7"
property "sonar.android.lint.report", "build/outputs/lint-results.xml"
property "sonar.java.binaries", "build/tmp/kotlin-classes"
property "sonar.java.test.binaries", "build/intermediates/classes/test/,build/tmp/kotlin-classes/devDebugUnitTest"
property "sonar.tests","src/test/java"
property "sonar.sources","src/main/java"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.jacoco.reportPaths","build/jacoco/testDevDebugUnitTest.exec"
property "sonar.junit.reportsPath","build/test-results/testDevDebugUnitTest"
}
}
and here is jacoco.gradle file
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7.9"
reportsDir = file("${project.projectDir}/app/build/reports")
}
task jacocoTestReport(type: JacocoReport, dependsOn: "app:testDevDebugUnitTest") {
group = "Reporting"
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ['**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/*$MembersInjector*.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*']
classDirectories = fileTree(
dir: "${project.projectDir}/app/build/intermediates/classes/dev",
excludes: fileFilter
) + fileTree(
dir: "${project.projectDir}/app/build/tmp/kotlin-classes/devDebug",
excludes: fileFilter
)
// sources
sourceDirectories = files(["${project.projectDir}/app/src/main/java"])
executionData = files("${project.projectDir}/app/build/jacoco/testDevDebugUnitTest.exec")
}
Following gradle commands I'm using to generate Jacobo report & then soar report.
./gradlew clean jacocoTestReport sonarqube
I observed following I'm getting, must be issue some path.
Coverage information was not collected. Perhaps you forget to include
debug information into compiled classes?
I'm sorry, if this is looking bit length; but this is best I found to summaries in one place. Please also note I tried similar setup with Java class instead Kotlin it's generating report with code coverage.
If you're using the android test orchestrator this is likely the problem.
I had the same issue today and after disabling the android test orchestrator the coverage is working again.
Bug report: https://issuetracker.google.com/issues/72758547
I'm not sure how Android Kotlin builds are configured, but in my Android Java build.gradle I had to comment out the test orchestrator like so:
android {
...
testOptions {
// temporarily disable the orchestrator as this breaks coverage: https://issuetracker.google.com/issues/72758547
//execution 'ANDROID_TEST_ORCHESTRATOR'
...
}
}
There are few things you need to do to make it work for kotlin.
Ensure your sonarqube > 7.5
If your sonarqube ver < 7.5, have the admin install sonar-jacoco plugin. Check the plugin compatibility version if sonarqube < 5.5.
plugins {
id "jacoco"
id "org.sonarqube" version "2.7.1"
}
Follow this url: https://community.sonarsource.com/t/coverage-test-data-importing-jacoco-coverage-report-in-xml-format/12151
Add properties in your build.gradle for it to search for jacoco results.
property 'sonar.coverage.jacoco.xmlReportPaths', "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
Follow this url for properties: https://docs.sonarqube.org/7.5/analysis/analysis-parameters/
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'
}
}
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:
https://web.archive.org/web/20171210224809/http://blog.wittchen.biz.pl/test-coverage-report-for-android-application (Old blog, with user comments)
http://wittchen.io/test-coverage-in-android-applications/ (New blog, without user comments)
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:
https://web.archive.org/web/20171013015925/http://blog.wittchen.biz.pl/test-coverage-report-with-travis-ci-for-robolectric-tests-on-android/ (Old blog)
http://wittchen.io/unit-test-coverage-report-with-travis-ci-for-robolectric-on-android/ (New blog, without user comments)
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.
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.
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
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.
Find the results. This can vary depending on your settings in the jacoco.gradle file. But generally you can find the results an index.html file here: ./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%.
I recently started integrating android-gradle-plugin 1.1.0 in one of my projects. The project uses robolectric 2.4 to run unit tests.
It's a multi module project with very complex dependencies (Some modules depend on other modules). Something like that:
--> application-module (dependsOn: module1, module2, module-core)
--> module1 (dependsOn: module-core)
--> module2 (dependsOn: module-core)
--> module-core (dependsOn: module3, module4)
--> module3 (library dependencies)
--> module4 (library dependencies)
For a more cleared picture please see jacoco-example project.
I tried to integrate JaCoCo to generate reports for the unit tests, but it seems to me that it runs only androidTests which are basically instrumentation tests.
After some google'ing I've come across a few projects on GitHub and other articles, but they mainly are focused on previous versions of the android-gradle-plugin or are using other third party plugins like android-unit-test for example here.
May be I've lost my ability to google. But can somebody point me in a direction where I can find some documentations regarding the new stuff in android gradle plugin and how to run the jacoco task only for unit tests?
UPDATE
Adopted the script from nenick's example:
apply plugin: "jacoco"
configurations {
jacocoReport
}
task jacocoReport(dependsOn: 'testDebug') << {
ant {
taskdef(name:'jacocoreport',
classname: 'org.jacoco.ant.ReportTask',
classpath: configurations.jacocoReport.asPath)
mkdir dir: "${buildDir}/test-coverage-report"
mkdir dir: "${buildDir}/reports/jacoco/test/"
jacocoreport {
executiondata = files("${buildDir}/jacoco/testDebug.exec")
structure(name: "${rootProject.name}") {
classfiles {
fileset (dir: "${buildDir}/intermediates/classes/debug") {
//exclude(name: '**/*_*.class')
exclude(name: '**/R.class')
exclude(name: '**/R$*.class')
exclude(name: '**/BuildConfig.class')
}
}
sourcefiles {
fileset dir: "src/main/java"
fileset dir: "${buildDir}/generated/source/buildConfig/debug"
fileset dir: "${buildDir}/generated/source/r/debug"
}
}
xml destfile: "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"
html destdir: "${buildDir}/test-coverage-report/"
}
}
}
dependencies {
jacocoReport 'org.jacoco:org.jacoco.ant:0.7.2.201409121644'
}
After that the ./gradlew jacocoReport executes and generates the report, but it shows 0 (zero) test coverage, which is impossible because at least half of all classes are tested.
UPDATE_2
Tried out this example. Adding the next task to one of my gradle build files:
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: "${buildDir}/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files("${buildDir.parent}/src/main/java")
additionalSourceDirs = files([
"${buildDir}/generated/source/buildConfig/debug",
"${buildDir}/generated/source/r/debug"
])
executionData = files("${buildDir}/jacoco/testDebug.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
Same issue, the reports are generated, but the code coverage is still zero.
UPDATE_3
It seams that the task from UPDATE_2 worked but only for the module with apply plugin: 'com.android.application' (The reports a generated correctly). But for modules that are android libraries (apply plugin: 'com.android.library') the reports show zero coverage, although the modules contain more tests then the application module.
UPDATE_4
Created a simple example project that demonstrates my issue. Currently if you run ./gradlew jacocoReport the report is generated, but no test coverage is displayed for the module projects. See this link
Short note: When the tests were AndroidUnitTests (whiteout JUnit 4 and Robolectric) JaCoCo reports showed coverage for all the modules.
Any ideas?
After the hassle, I decided to create an open source Gradle plugin for that.
Root build.gradle
buildscript {
repositories {
mavenCentral() // optional if you have this one already
}
dependencies {
classpath 'com.vanniktech:gradle-android-junit-jacoco-plugin:0.16.0'
}
}
apply plugin: 'com.vanniktech.android.junit.jacoco'
Then simply execute
./gradlew jacocoTestReportDebug
It'll run the JUnit tests in Debug Mode and then give you the Jacoco output in XML and HTML form in the corresponding build directory.
It also supports flavors. Having 2 flavors red and blue those tasks would be created
jacocoTestReportRedDebug
jacocoTestReportBlueDebug
jacocoTestReportRedRelease
jacocoTestReportBlueRelease
After some additional search I've stumbled upon this project
I had to make some modifications so that there solution can work for my type of project, but now the test coverage reports are generated properly.
I've pushed the adopted changes to my example github repo in case someone will have a similar problem in the future.
Warning: This is a hack! Using your configuration above, I put together a hack to switch the android plugin between application and library depending on the build tasks chosen. This works well for me because I don't end up committing code with the application mode set.
// dynamically change the android plugin to application if we are running unit tests or test reports.
project.ext.androidPlugin = 'com.android.library'
for (String taskName : project.gradle.startParameter.taskNames) {
if (taskName.contains('UnitTest') || taskName.contains('jacocoTestReport')) {
project.ext.androidPlugin = 'com.android.application'
break
}
}
logger.lifecycle("Setting android pluging to ${project.ext.androidPlugin}")
apply plugin: project.ext.androidPlugin
...
apply plugin: 'jacoco'
configurations {
jacocoReport
}
task jacocoTestReport(type:JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: "${buildDir}/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files("${buildDir.parent}/src/main/java")
additionalSourceDirs = files([
"${buildDir}/generated/source/buildConfig/debug",
"${buildDir}/generated/source/r/debug"
])
executionData = files("${buildDir}/jacoco/testDebug.exec")
reports {
xml.enabled = true
html.enabled = true
}
}
Let's hope the android tools team fixes this soon.
I setup my unit tests for gradle 1.2 using this blog post. Then I pieced together information I found here and elsewhere to add code coverage to independent modules instead of the whole project. In my library module build.gradle file, I added the following:
apply plugin: 'jacoco'
def jacocoExcludes = [
'com/mylibrary/excludedpackage/**'
]
android {
...
}
android.libraryVariants.all { variant ->
task("test${variant.name.capitalize()}WithCoverage", type: JacocoReport, dependsOn: "test${variant.name.capitalize()}") {
group = 'verification'
description = "Run unit test for the ${variant.name} build with Jacoco code coverage reports."
classDirectories = fileTree(
dir: variant.javaCompile.destinationDir,
excludes: rootProject.ext.jacocoExcludes.plus(jacocoExcludes)
)
sourceDirectories = files(variant.javaCompile.source)
executionData = files("${buildDir}/jacoco/test${variant.name.capitalize()}.exec")
reports {
xml.enabled true
xml.destination "${buildDir}/reports/jacoco/${variant.name}/${variant.name}.xml"
html.destination "${buildDir}/reports/jacoco/${variant.name}/html"
}
}
}
And in my project build.gradle file, I added common excludes:
ext.jacocoExcludes = [
'android/**',
'**/*$$*',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Service.*'
]
Also, it looks like code coverage for unit tests may be coming built in in the future Issue 144664
I was finally able to see my code coverage of JUnit tests with Android Studio 1.1.
jacoco.gradle
apply plugin: 'jacoco'
jacoco {
toolVersion "0.7.1.201405082137"
}
def coverageSourceDirs = [
"$projectDir/src/main/java",
]
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
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/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("$buildDir/intermediates/classes/").eachFileRecurse { file ->
if (file.name.contains('$$')) {
file.renameTo(file.path.replace('$$', '$'))
}
}
}
}
and then within the build.gradle file of the module (I put it between android and dependencies):
apply from: '../jacoco.gradle'
Also in the defaultConfig block of android. I've added this (don't know if it is necessary, but I've got this from this blog):
android {
defaultConfig {
testHandleProfiling true
testFunctionalTest true
}
}
Enjoy.
You can try to use this Gradle plugin:
https://github.com/arturdm/jacoco-android-gradle-plugin
Basically, all you need to do is apply it like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
}
}
apply plugin: 'com.android.library' // or 'com.android.application'
apply plugin: 'jacoco-android'
As a result you should get a JacocoReport task for each variant. Run the command below to generate code coverage reports for all of them.
$ ./gradlew jacocoTestReport
I resolve issues with JaCoCo and make it work with latest gradle android plugin 1.1.3
Project with latest gradle scripts: https://github.com/OleksandrKucherenko/meter
References:
How to attach own implementation instead of Mocks in Android Studio Unit Tests?
https://plus.google.com/117981280628062796190/posts/8jWV22mnqUB
Small hint for everyone who try to use JaCoCo coverage in android builds... unexpected finding!!!
https://plus.google.com/117981280628062796190/posts/RreU44qmeuP
JaCoCo XML/HTML Report for Unit Tests https://plus.google.com/u/0/+OleksandrKucherenko/posts/6vNWkkLed3b
I was facing exactly the same problem like you. 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.
Please create an example and I can take a look. I guess it's some missing path configuration.
include all coverage files (*.exec)
add all your source paths (module/src/main/java)
add all class paths (module/build/intermediates/classes/debug)
here two examples how it could be look
https://github.com/nenick/AndroidAppDevelopment/blob/master/Scripts/jacoco-support-app-module.gradle
https://github.com/nenick/AndroidAppDevelopment/blob/master/Scripts/jacoco-coveralls-support.gradle
I have a simple android project with test cases.
ProjNameProject
--build.gradle
--ProjName
----build.gradle
I see that by default android's new build system provides basic test results by default. (Hooray!)
Now I want to see code coverage as well. I know how to set this up using Emma and Ant scripts, however I don't want to run Ant scripts here. I feel that would defeat the purpose of me using the new build system.
I've tried a few Cobertura plugins that were found on Github. One in particular:
https://github.com/stevesaliman/gradle-cobertura-plugin
However if I try to use the plugin in the ProjName build file then I get errors about the java plugin. I read on tools.android.com that adding the java plugin will generate this behavior. I'm not applying it so the cobertura plugin must be.If I try to use the plugin in the main build file then I don't see the java errors but now i see:
Could not find net.sourceforge.cobertura:cobertura:1.9.4.1.
Required by:
:ProjNameProject:unspecified
What do I do??
JaCoCo support was added to the Android gradle plugin v0.10 (http://tools.android.com/tech-docs/new-build-system).
Enable in the tested Build Type with testCoverageEnabled = true
android {
jacoco {
version = '0.6.2.201302030002'
}
}
I was able to get JaCoCo coverage working with Robolectric by following http://chrisjenx.com/gradle-robolectric-jacoco-dagger/.
apply plugin: 'android'
apply plugin: 'robolectric'
apply plugin: 'jacoco'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:appcompat-v7:19.1.+'
androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')
androidTestCompile 'junit:junit:4.11'
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'com.squareup:fest-android:1.0.+'
}
robolectric {
// Configure the set of classes for JUnit tests
include '**/*Test.class'
exclude '**/*AbstractRobolectricTestCase.class'
// Configure max heap size of the test JVM
maxHeapSize = "2048m"
}
jacoco {
toolVersion = "0.7.1.201405082137"
}
//Define coverage source.
//If you have rs/aidl etc... add them here.
def coverageSourceDirs = [
'src/main/java',
'src/gen'
]
...
// Add JaCoCo test reporting to the test task
// http://chrisjenx.com/gradle-robolectric-jacoco-dagger/
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
reports {
xml.enabled = true
html.enabled = true
}
// Class R is used, but usage will not be covered, so ignore this class from report
classDirectories = fileTree(
dir: './build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class'
])
sourceDirectories = files(coverageSourceDirs)
executionData = files('build/jacoco/testDebug.exec')
}
Emma support is planned to be released soon within the new Android build system : http://tools.android.com/tech-docs/new-build-system/roadmap
Up to now there is no official way to run emma with android via gradle. I guess instrumenting can be achieved pretty easily but then, you will miss a way to tell Android to run tests with coverage on. Moreover, there is currently no way (to the best of my knowledge) to pull down emma runtime coverage data from the device.
This project can interest you : https://github.com/stephanenicolas/Quality-Tools-for-Android. It will be updated as soon as emma will make it into Android Gradle plugin.
----UPDATE
This plugin has no chance to work with Android has it uses the Java plugin which is incompatible with Android plugin.