0

Recently I upgrade my gradle from 6.5.1 to 7.0 i.e.

distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip

After the upgrade, I notice my test coverage dropped.

After investigation, I found out that in Gradle 6.5.1, my JaCoCo test coverage report shows some of my class has an encode() function, but it no longer exists in Gradle 7.0.

I dig out the simplest example below. The code is as below

enter image description here

In Gradle 6.5, my JaCoCo report is as below (notice there's an additional encode() function.

enter image description here

However, in Gradle 7.0, my JaCoCo report is as below

enter image description here

Because of this missing covered function, hence my coverage dropped. Nonetheless, it looks like in Gradle 7.0, that is more correct, as my real code doesn't have encode().

I'm just trying to understand where encode() function is there in the first place, and why it is no longer in Gradle 7.0? And is it correct that my assumption that Gradle 7.0 result is correct?

Vampire
  • 35,631
  • 4
  • 76
  • 102
Elye
  • 53,639
  • 54
  • 212
  • 474

2 Answers2

1

Different versions of Gradle come with different values of jacoco.toolVersion which you also can change in your build.gradle, and which controls version of JaCoCo to use.

Gradle 6.5 by default uses JaCoCo 0.8.5, and starting from Gradle 6.7 default is 0.8.6.

And here is a list of changes in JaCoCo version 0.8.6 - https://www.jacoco.org/jacoco/trunk/doc/changes.html


Most likely your interface ContextData contains method encode with default implementation.

JVM supports default methods in interfaces starting from version 8, however Kotlin supports compilation into bytecode of version 6. To do so Kotlin compiler does a trick for such methods - it generates method in classes implementing this interface that merely delegates execution to default implementation:

for the following Example.kt

interface ContextData {
  fun encode() = { /* something */ }
}

data class SearchRefinementModalOpenData(
  val userAction: String?
) : ContextData

execution of

kotlin-compiler-1.4.32/bin/kotlinc Example.kt
javap -v -p SearchRefinementModalOpenData.class

shows following bytecode

public final class SearchRefinementModalOpenData implements ContextData
{
  public kotlin.jvm.functions.Function0<kotlin.Unit> encode();
    descriptor: ()Lkotlin/jvm/functions/Function0;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokestatic  #29                 // Method ContextData$DefaultImpls.encode:(LContextData;)Lkotlin/jvm/functions/Function0;
         4: areturn

JaCoCo starting from version 0.8.6 filters out such methods since they are compiler artifacts and not presented in original source code.

Godin
  • 9,801
  • 2
  • 39
  • 76
0

It looks like you are using kotlinx.Serialization.

That generates a few encodeToString and similar functions for your objects. I guess Gradle 7 now ignores those?

CLOVIS
  • 771
  • 8
  • 24