kotlinx-kover icon indicating copy to clipboard operation
kotlinx-kover copied to clipboard

0.7.0-Beta - KoverTool coverage issue

Open glureau opened this issue 2 years ago • 3 comments

Describe the bug Given this 2 pieces of code, and given this code is covered by 2 unit tests that check for null and non-null values, the branch coverage is different:

val nullableField: String? = ...
val name = (nullableField
    ?.let { "Hello : " + it.toString() }) 
    ?: "Nobody?"

image

Branch = 3/4 (75%)

val fooBar = nullableField?.let { "Hello : $it" }
val name = fooBar ?: "Nobody?"

image

Branch = 4/4 (100%) (Same coverage when using parenthesis to help disambiguate.)

I'm using Kover by default, but Jacoco provides the same behaviour.

Errors If present, stacktraces or files from build/kover/errors directory

Expected behavior

I expect to have 100% coverage on both implementation.

I'd even count only 2 branches here: with this implementation let will return String (not null) when nullableField is not null, so either we have the let branch, or we have the "else" branch (default value, being "Nobody?" in this example). It's an if/else pattern after all.

I presume it's limited to patterns like ?.let { [A] } ?: [B] where [A] is non-null. With the current implementation it's counting a branch when [A] and [B] are both executed, but this is an impossible case, leading to a bad coverage computation.

I'd also be fine with 4 branches if the 4 branches would be considered as covered, like with the local variable, as soon as I've a perfect coverage. (This coverage issue can lead to developers changing code production for no good reasons.)

Reproducer No open-source project, but this code should reproduce the problem easily:

fun greeting(nullableField: String?) {
    val name = (nullableField?.let { "Hello : " + it.toString() }) 
      ?: "Nobody?"
}

Reports If applicable, report files or screenshots.

Environment

  • Kover Gradle Plugin version: 0.7.0-Beta
  • Gradle version: 7.6
  • Kotlin project type: Kotlin/Multiplatform (Android & iOS)
  • Coverage Engine version (if customized in build script): kover or default jacoco
  • Other context important for this bug: MacBook Pro Ventura 13.3.1

glureau avatar May 11 '23 09:05 glureau

For cross-reference, slack discussion: https://kotlinlang.slack.com/archives/CDLD3845Q/p1683793061561869

glureau avatar May 11 '23 09:05 glureau

Same issue for version 0.7.1 Any updates about this bug?

Borlehandro avatar Jun 06 '23 10:06 Borlehandro

@Borlehandro, unfortunately, this issue is difficult to fix in Kover, because it only works with the bytecode of already compiled classes. Related feature in Kotlin compiler https://youtrack.jetbrains.com/issue/KT-52472

shanshin avatar Jun 07 '23 13:06 shanshin