Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Code coverage reports misrepresent Kotlin inline functions #5501

Open
Rd4dev opened this issue Aug 21, 2024 · 1 comment
Open

[BUG]: Code coverage reports misrepresent Kotlin inline functions #5501

Rd4dev opened this issue Aug 21, 2024 · 1 comment
Labels
bug End user-perceivable behaviors which are not desirable. Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). Work: Low Solution is clear and broken into good-first-issue-sized chunks.

Comments

@Rd4dev
Copy link
Collaborator

Rd4dev commented Aug 21, 2024

Describe the bug

When evaluating code coverage for files containing Kotlin inline functions, the coverage report inaccurately displays the coverage status. Inline functions may appear as either uninstrumented (highlighted in grey) or not covered (highlighted in red) despite being hit by test cases.

Steps To Reproduce

  1. Identify the Inline Function:

Examine MathExpressionParser.kt, which contains the following inline function:

/**
 * Consumes the next [Token] (which is assumed to be type [T], otherwise the error provided by
 * [missingError] is used) and returns the result.
 */
inline fun <reified T : Token> consumeTokenOfType(
  missingError: () -> MathParsingError = { GenericError }
): MathParsingResult<T> {
  println("In consume Token of type")
  val maybeToken = tokens.expectNextMatches { it is T } as? T
  return maybeToken?.let { token ->
    println("Hit in maybe Token")
    previousToken = token
    MathParsingResult.Success(token)
  } ?: missingError().toFailure()
}

Debug lines are added to assist with verifying coverage.

  1. Run Tests:

Execute tests on MathExpressionParserTest.kt to confirm that the inline function is hit by the test cases:

Running:

bazel test utility/src/test/java/org/oppia/android/util/math:MathExpressionParserTest --test_filter=testParseNumExp_largeRealExponent_optionalErrorsDisabled_doesNotFail

Logged:

INFO: From Testing //utility/src/test/java/org/oppia/android/util/math:MathExpressionParserTest:
==================== Test output for //utility/src/test/java/org/oppia/android/util/math:MathExpressionParserTest:
JUnit4 Test Runner
.In consumer Token of type
Hit in may be Token
In consumer Token of type
Hit in may be Token
In consumer Token of type
Hit in may be Token

Time: 0.086

OK (1 test)
  1. Run code coverage analysis on MathExpressionParser.kt,
bazel run //scripts:run_coverage -- $(pwd) utility/src/main/java/org/oppia/android/util/math/MathExpressionParser.kt
  1. Check Coverage Report:

Review the generated HTML code coverage report for MathExpressionParser.kt.

image

Despite the function being executed during tests, the lines are incorrectly reported as not covered.

Raw coverage info:

To analyze the raw coverage data, run the following bazel coverage command:

bazel coverage utility/src/test/java/org/oppia/android/util/math:MathExpressionParserTest

coverage.dat info for the inline function lines:

Line Coverage:

DA:708,1
DA:716,1
DA:725,0
DA:726,0
DA:728,0
DA:729,1
DA:730,0
DA:731,0
DA:732,0
DA:733,0
DA:734,0
DA:739,1
DA:744,1
DA:748,1

Expected Behavior

The coverage report should highlight the lines in green, indicating that they are covered by the tests.

Additional Context

Most inline functions are marked as uninstrumented in the coverage report.

BundleExtensions.kt

image

Bazel version

6.5.0

rules_kotlin

v1.7.1
sha: fd92a98bd8a8f0e1cdcb490b93f5acef1f1727ed992571232d33de42395ca9b3

What device/emulator are you using?

No response

Which Android version is your device/emulator running?

No response

Which version of the Oppia Android app are you using?

No response

@Rd4dev Rd4dev added bug End user-perceivable behaviors which are not desirable. triage needed labels Aug 21, 2024
@adhiamboperes adhiamboperes added Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). Work: Low Solution is clear and broken into good-first-issue-sized chunks. labels Dec 3, 2024
@akshtshrma
Copy link

akshtshrma commented Dec 3, 2024

To address this issue, here are some potential solutions:

  1. Exclude inline functions from coverage : Configure the coverage tool to exclude inline functions. This keeps the benefits of inlining but leaves their coverage out of reports.
  2. Refactor inline functions to regular ones : This would allow coverage tools to track them accurately but might reduce performance and type safety due to the loss of reified.
  3. Thorough testing at call sites : Rely on the coverage at call sites for inline functions, ensuring all branches are tested.

I'd like to know which approach aligns best with the project's goals and guidelines. Alternatively, if there's another solution the team prefers, I’d be happy to implement that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug End user-perceivable behaviors which are not desirable. Impact: Medium Moderate perceived user impact (non-blocking bugs and general improvements). Work: Low Solution is clear and broken into good-first-issue-sized chunks.
Development

No branches or pull requests

4 participants