jacoco icon indicating copy to clipboard operation
jacoco copied to clipboard

Should ignore `kotlin.KotlinNothingValueException` throwing code, that is generated code (by Kotlin compiler)

Open saiya opened this issue 11 months ago • 0 comments

Scenario

  • JaCoCo version: 0.8.11.202310140853
  • Operating system: Any (confirmed with Linux and Mac)
  • Tool integration: Any (confirmed with Gradle)
  • Description of your use case:
    1. Write a Kotlin method that throws exception always and has Nothing return type
    • e.g. fun throwSomeException(): Nothing { throw RuntimeException("this method never returns and always throws") }
    • Kotlin Nothing means it never returns (always throws an exception), and Kotlin compiler ensure the method always throws
    1. Call the method and measure coverage of the caller-side code
    2. JaCoCo test report marks the row with yellow "1 or 2 branch missed"

Example:

// Code in /src/main/kotlin

fun fail(): Nothing {
  throw RuntimeException("Nothing means this method always throws and never returns")
}

fun doSomething(flag: Boolean) {
  if(flag) {
    fail() // For this code line, even if test code covers both flag == true and false cases, JaCoCo test report says "1 or 2 branch missed"
  }
}
// Code in /src/test/kotlin

/** Test code should yield 100% coverage of the doSomething method */
@Test
fun test() {
   doSomething(false)
   Assertions.assertThrows(RuntimeException::class.java) { doSomething(true) }
}

Current Behaviour

For every code lines calling Kotlin Nothing returning method, JaCoCo reports "1 or 2 branch missed".

This looks caused by Kotlin compiler generated safety-guard code, that throws kotlin.KotlinNothingValueException in case of if the Nothing returning method haven't thrown exception.

As looking JVM bytecode of the caller-side, the bytecode looks like this:

    INVOKESTATIC ...my method that always throws and returns Nothing...
    NEW kotlin/KotlinNothingValueException
    DUP
    INVOKESPECIAL kotlin/KotlinNothingValueException.<init> ()V
    ATHROW

The NEW kotlin/KotlinNothingValueException and following code lines never runs practically because the codes follows Nothing returning method call that always throws exception.

Wanted Behaviour

For every code lines calling Kotlin Nothing returning method, JaCoCo should ignore kotlin.KotlinNothingValueException related compiler-generated codes.

Possible Workarounds

  • tolerate poor coverage percentage of generated report
  • avoid using Nothing language feature of Kotlin

saiya avatar Mar 09 '24 08:03 saiya