I am attempting to revive using Jacoco in a Kotlin...
# gradle
p
I am attempting to revive using Jacoco in a Kotlin multiplatform project. It is worse than pulling teeth, given that 1) there is no Java or Application plugin in use that defines “jacocoTestReport”, 2) I am using Kotlin DSL so creating the task “jacocoTestReport” is non-trivial (for me anyway), 3) I am using Kotlin test (not Junit) which I’m guessing does not support Jacoco, and 4) the GooglePlex, Stack Overflow, Medium, etc. all are coming up empty for a simple example that illustrates what needs to be done. I would not be surprised at all to learn that it is even more complicated. In any case, a link to a project that has worked around the constraints I described would be much appreciated. Additional insight will also likely be invaluable.
Please post responses to this thread. Thanks.
g
2. What do you mean? Could you share some sample?
Just to be clear, do you try to configure it for JVM part of your MPP project, right?
p
I did not do anything specific to configure Jacoco for the JVM (only part right now other than common).
This example, taken from an old Groovy script I found, was my starting point:
Copy code
task jacocoJVMTestReport(type: JacocoReport) {
    //dependsOn = test
    group = “Reporting”
    description = “Generate Jacoco coverage report.”
    classDirectories = fileTree(dir: “$buildDir/classes/kotlin/jvm/main”)
    def coverageSourceDirs = [“src/commonMain/kotlin”, “src/jvmMain/kotlin”]
    additionalSourceDirs = files(coverageSourceDirs)
    sourceDirectories = files(coverageSourceDirs)
    executionData = files(“$buildDir/jacoco/jvmTest.exec”)
    reports {
        html.enabled = true
        xml.enabled = true
        csv.enabled = false
    }
}
Mapping that to use Kotlin DSL and a multiplatform project has been difficult to say the least. But I am still at it while trying to find a version already converted and using MPP.
@gildor do you have any insight into 3)?
g
Why do you convert it to Kotlin DSL if you not familiar with it? You can continue to use groovy, even move it to groovy script
I did some super fast test using kmath project and it works for me
But it uses standard kotlin
org.jebrains.kotlin.test
and
org.jebrains.kotlin.test-junit
and this task above works for me
if you have some sampe project that uses kotlin.test, please share, I never used it, maybe it really has some problems, but as I understand how Jacoco works it shouldn’t be related
Also, check that you applied
jacoco
plugin, without it code instrumentation will not be applied so you cannot get reports
But again, this sample uses
org.jebrains.kotlin.test
+
org.jebrains.kotlin.test-junit
, but most probably it will work with kotlintest
l
I use Kotlintest and Jacoco, and they work correctly. I didn't try it with MPP, however
I don't think jacoco depends on how it's being executed, but KT uses JUnit to execute tests
p
@LeoColman do you have a public repo where I can look at your build script?
@gildor your kmath-core directory is helpful. However, jvmTest is unresolved in my build.gradle.kts when I copy the tasks {…} block from your kmath-core project. This makes no sense to me. Here’s my build script:
g
@pajatopmr Maybe you just share some sample that doesn’t work for you, because JVM only and MPP configs are pretty differnt, not sure how this would help you, especially if kotlintest uses Junit 5
p
g
However, jvmTest is unresolved in my build.gradle.kts
Because I use type safe accessors which available because I have custom plugin with basic config Just use dynamic syntax:
Copy code
named("jvmTest") {
  finalizeBy(coverage)
}
@pajatopmr Your config will not work, because you didn’t apply
jacoco
plugin https://kotlinlang.slack.com/archives/C19FD9681/p1556503441047200?thread_ts=1556478196.043900&cid=C19FD9681
Also to configure finalizeBy you can do the same syntax as on line 68,
named
just does this lazy
p
Hmmm I thought that apply happened automagically via using the plugins block.
g
I don’t see jacoco plugin in your plugins block
p
My bad. I took it out and did not put it back. 😞
Can you elaborate on fixing ‘finalizeBy’
g
replace:
Copy code
jvmTest {
   finalizedBy(coverage)
}
With:
Copy code
named("jvmTest") {
  finalizeBy(coverage)
}
you don’t need this line, if you don’t want to run coverage each time after test run
p
That I did but now ‘finalizedBy’ is not resolved.
got it now.
g
there is just a typo,
finalizeBy
->
finalizedBy
but as I said, it the same what you do in line 68, just using eager syntax:
Copy code
tasks.get(name = "jvmTest").dependsOn += tasks.get(name = "copyTestResources")
you can combine those 2 configs
named(“jvmTest”) { dependsOn(named(“copyTestResources”)) finalizedBy(coverage) }
p
And now I get coverage! Awesome. Thanks for the help.
👍 1
m
Hello i'm interested about this topic since i'm trying to also launch some test coverage for my commonTest module but couldn't get your solution to work since i'm having Task with name 'jvmTest' not found in project
l
I think jvmTest must be inside a
kotlin
block, isn't it?
m
Nope my kotlin block looks like this
so i have no clue on how to make it work
g
Of course you don't have jvmTest, because you don't have jvm as target platform, instead you have Android test tasks
m
i'm not that good on gradle configuration and neither test coverage so if you could enlighten me i would be thankful
my all build.gradle look like this it work well i can generate and use framework with cocoapods plugin and all my tests are inside a commonTest folder and now i wanted to try test coverage with jacoco that i never used before
g
Do you understand that jacoco is JVM only tool? There is also experimental K/N coverage tool
m
l
nothing for MPP yet, I suppose?
g
Yes, this is coverage tool for K/N