Skip to content

Projectables stops coverlet from being able to collect coverage information #47

@jhartmann123

Description

@jhartmann123

I stumbled upon this issue with Expressionify (issue). I tested it with Projectables, which has the same issue. Thus this report is basically copy pasta from the Expressionify issue.

Source issue

Long story short: coverlet does not generate coverage reports anymore, once Projectables is in use. Briefly explained, coverlet does not detect the source generated by Projectables as generated and won't instrument the assembly, as it doesn't have all the sources.

Why is this an issue with Projectables?
If the generated source files follow a naming convention, coverlet detects the files as auto generated and magically starts working again. (see coverlet-coverage/coverlet#1084 (comment))

Fix

The file names simply have to end in .g.cs or .generated.cs (not _Generated.cs as of now)

Further info

This naming convention isn't something random invented by coverlet, but is also hidden in plain sight in multiple docs. Examples:
https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview#get-started-with-source-generators
In the tip in point 6:

It's common to provide an explicit C# file extension such as ".g.cs" or ".generated.cs" for the name. The file name helps identify the file as being source generated.

https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references#nullable-contexts
In the "Important"-block

[...]
There are four ways a file is marked as generated:
[...]
4. End the file name with .designer.cs, .generated.cs, .g.cs, or .g.i.cs.

Pitfalls

When I provided a fix for Expressionify, a new warning popped up:
CS8669: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.

The hardcoded #nullable disable won't work anymore with expressions that use nullability (like in the repro).

Repro

Projectables.Coverage.zip

Steps:

  • Run test with dotnet test --collect:"XPlat Code Coverage"
  • At the end of the test run it outputs the path to a coverage.cobertura.xml. It is basically an empty XML at this point.
  • Remove [Projectable] in Class1.cs
  • Rerun test
  • The new XML now has coverage info.

Debug output of coverlet can be retrieved with dotnet test --collect:"XPlat Code Coverage" --diag:log.txt
With the current version of Projectables, the datacollector log contains a line
[coverlet]Unable to instrument module: ... Projectable.Coverage.dll, pdb without local source files

This is fixed once the generated source files end with .g.cs or .generated.cs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions