Skip to content

[BUG] Nondeterministic variance in OpenCover offset/offsetend #1814

@sharpjs

Description

@sharpjs

Describe the bug
I am seeing intermittent, nondeterministic variance in the OpenCover offset and offsetend attributes for the same BranchPoint across different test runs, when neither the code nor the build environment have changed. To illustrate, here is a diff of branch coverage data for a pair of if statements. These images come from subsequent CI pipeline runs for the same commit, using the same CI agent image. The left side shows the expected offset and offsetend values, while the right side shows a case of variance.

Image

This variance creates a problem when merging coverage data from multiple test runs (e.g. a unit test run and an integration test run) using ReportGenerator. ReportGenerator interprets BranchPoints with differing offset/offsetend as different branch cases. The variance inflates total coverable branch count, which decreases branch coverage. Here are excerpts from the coverage reports for the above two builds:

The left build, with no variance:
Image

The right build, where variance inflated the branch count:
Image

The CI pipeline for this product is configured to fail if coverage decreases. Thus the intermittent variance tends to cause failed CI builds, even when no code has changed.

I have tried the following workarounds thus far:

  • Changed the pipeline to have a static minimum coverage instead of using the most recent production-quality build as baseline.
  • Changed Coverlet from OpenCover to lcov output to see if that would help. Will know after a day.

To Reproduce

  • Magically gain access to my team's CI system.
  • Undo the workarounds we added for this problem.
  • Run the main build-and-test CI pipeline ten times for the same commit.

Expected behavior

  • The pipeline runs generate identical coverage data.
  • None of the runs fail due to false-negative coverage decrease.

Actual behavior

  • One pipeline run has its unit tests and its integration tests (two separate dotnet test invocations) disagree on the offset/offsetend for a particular if statement.
  • ReportGenerator thinks that if statement has four branch points instead of two.
  • The pipeline run fails due to false-negative coverage decrease.

Configuration (please complete the following information):

  • .NET: Framework 4.8.1, SDK 6.0.428, SDK 8.0.417
  • Coverlet: collector 6.0.4 and 8.0.0-gbc66628323
  • OS: Azure DevOps Pipelines windows-2022 image, version 20260127.11
  • Architecture: x64
  • Specific to that config? don't know

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs reproNeeds repro to be investigated, cannot repro in localquestionThis issue is a question

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions