My android app is multi module project:
include (android-app/kotlin-android)':application', (pure kotlin)':presentation', (pure kotlin)':domain', (android-library/kotin-android)':dataproviders'
I'm using Junit/Mockito for tests and I have issue with generating code coverage for kotlin android modules only.
Tested lines are visible for android studio.
tested class in ui.viewmodel package:
But, for pure kotlin (eg. domain, presentation) test coverage works fine:
I'm using Android Studio 3.0 Canary 8
You can look at my build.gradle files at github:
build.gradle
dependencies.gradle
application.build.gradle
presentation.build.gradle
Example test in android application module:
MostPopularViewModelTest
Example test in pure kotlin module:
MostPopularPresenterTest
Can someone help me with my problem? I tried generate code coverage via Jacoco but it also did not show code coverage.
Solution is to add this this gradle task in build.gradle for module:
task copyTestClasses(type: Copy) {
from "build/tmp/kotlin-classes/debugUnitTest"
into "build/intermediates/classes/debug"
}
And run:
gradlew copyTestClasses
Then generate code coverage report without problems.
Although the solution from @Hype works, it also messes a bit the environment as you end up with kotlin class files and META-INF in the same directory as the class files from java. This might give you some issues running the compilation for a second time.
Another solution would be to just add the path for kotlin classes to jacoco configuration parameter classDirectories
.
This solution would simply tell jacoco that it needs to evaluate files from two different file trees. The upside is that it does not change your environment.
Here's a sample of how you could combine class files from multiple directories, excluding any unwanted files (this is depending on your project setup, you might use dagger and have to exclude dagger generated files):
def javaAndKotlinClassFiles = files(fileTree(dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
'**/*_Provide*Factory*.*',
'**/*$*$*.*', // Anonymous classes generated by kotlin
'**/*Test*.*', // Test files
'**/*Spec*.*' // Test files
]
).files)
.from(files(fileTree(dir: "${project.buildDir}/tmp/kotlin-classes/${sourcePath}",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
'**/*_Provide*Factory*.*',
'**/*$*$*.*', // Anonymous classes generated by kotlin
'**/*Test*.*', // Test files
'**/*Spec*.*' // Test files
]).files)
)
classDirectories = javaAndKotlinClassFiles
Here's a nice guide for how to set it up for Java.