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

MS Coverage output isn't cleaning compiler generated methods/types #663

Open
erichiller opened this issue Apr 12, 2024 · 3 comments
Open

Comments

@erichiller
Copy link

Describe the bug
When using Microsoft CodeCoverage (aka dotnet-coverage) which can now export in Cobertura format, the Cobertura is not cleaned up for compiler generated types and methods where the names are mangled.

A real example, for a single class, the following classes are present in the CodeCoverage output Cobertura file:

<class line-rate="0.7832167832167832" branch-rate="0.75" complexity="58" name="RequestState.RequestStateManager&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="1" branch-rate="1" complexity="4" name="RequestState.RequestStateManager.&lt;&lt;GetChannelForRequestAsync&gt;g__addDbStorageAsync|14_0&gt;d&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="1" branch-rate="1" complexity="2" name="RequestState.RequestStateManager.&lt;&gt;c&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="1" branch-rate="1" complexity="1" name="RequestState.RequestStateManager.&lt;&gt;c__DisplayClass19_0&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="0.6153846153846154" branch-rate="0.5" complexity="4" name="RequestState.RequestStateManager.&lt;ClearRequestStateAsync&gt;d__17&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="0.84" branch-rate="0.8" complexity="10" name="RequestState.RequestStateManager.&lt;CompleteRequestAsync&gt;d__19&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="1" branch-rate="1" complexity="1" name="RequestState.RequestStateManager.&lt;DisposeAsync&gt;d__33&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="0.8888888888888888" branch-rate="0.9166666666666666" complexity="12" name="RequestState.RequestStateManager.&lt;DisposeAsyncCore&gt;d__34&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">
<class line-rate="1" branch-rate="1" complexity="4" name="RequestState.RequestStateManager.&lt;mkmrk-DataSource-Ibkr-RequestState-IMessageStateManager-MarkSentAsync&gt;d__30&lt;TRequestMessage, TResponseMessage, TChannelOutput&gt;" filename="RequestState/RequestStateManager.cs">

Which results in the following classes being reported:

Name Line Branch Method
RequestState.RequestStateManager.<>c<TRequestMessage,
TResponseMessage, TChannelOutput>
100%
RequestState.RequestStateManager<TRequestMessage, TRe
sponseMessage, TChannelOutput>
77.3% 75% 85.7%
RequestState.RequestStateManager<TRequestMessage, TRe
sponseMessage, TChannelOutput>
87.3% 85.2% 100%
RequestState.RequestStateManager<TRequestMessage, TRe
sponseMessage>
65.3% 66.6% 100%

To Reproduce
Any use of Microsoft CodeCoverage on any codebase with constructs such as async methods, local functions, etc. causes these same issues.

@danielpalme
Copy link
Owner

Probably Microsoft CodeCoverage uses a slightly different formatting that other tools (e.g. coverlet).
I will look into this within the next days and try to handle this format as well.

@danielpalme
Copy link
Owner

My assumption is correct. The format is different:

dotnet-test
Test.ClassWithLocalFunctions.MyNestedClass<T1, T2>
Test.ClassWithLocalFunctions.MyNestedClass.<MyAsyncMethod>d__4<T1, T2, T3>
Test.ClassWithLocalFunctions.MyNestedClass.<>c__DisplayClass4_0.<<MyAsyncMethod>g__MyAsyncLocalFunction|0>d<T1, T2, T3, T4>

coverlet
Test.ClassWithLocalFunctions1/MyNestedClass1
Test.ClassWithLocalFunctions1/MyNestedClass1/<MyAsyncMethod>d__41 Test.ClassWithLocalFunctions1/MyNestedClass1/&lt;&gt;c__DisplayClass4_01/<<MyAsyncMethod>g__MyAsyncLocalFunction|0>d`1

Will have to adjust in ReportGenerator

@danielpalme
Copy link
Owner

I invested several hours, but I have not yet found a way filter out those classes and at the same time don't miss any relevant coverage results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants