I have a .runsettings file which excludes autogenerated methods that are typically associated with async/await code, i.e. MoveNext()
in my case. This is my .runsettings file:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<Functions>
<Exclude>
<Function>.*MoveNext.*</Function>
</Exclude>
</Functions>
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<CollectAspDotNet>False</CollectAspDotNet>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
This is the command I use to run my tests:
dotnet test --collect:"XPlat Code Coverage" --results-directory .coverage --settings tests.runsettings
If I enable logging I can see that it definitely finds the .runsettings file. However, all the generated coverage files include MoveNext() methods, e.g.
<class name="MyProject.Domain.Services.BackgroundService/<CreateMessages>d__10" filename="MyProject.Domain\Services\BackgroundService.cs" line-rate="0" branch-rate="0" complexity="2">
<methods>
<method name="MoveNext" signature="()" line-rate="0" branch-rate="0" complexity="2">
<lines>
<line number="71" hits="0" branch="False" />
<line number="72" hits="0" branch="False" />
<line number="73" hits="0" branch="True" condition-coverage="0% (0/2)">
<conditions>
<condition number="318" type="jump" coverage="0%" />
</conditions>
</line>
</lines>
</method>
</methods>
After the coverage reports are generated, I merge them using:
dotnet-coverage merge .coverage\*.xml --remove-input-files --recursive -f xml -o coverage.xml
The problem is that these methods are included in the coverage file, and our SonarQube scan job will occasionally fail with the error
[07:43:57]W: [Step 1/1] ERROR: Error during SonarQube Scanner execution
[07:43:57]W: [Step 1/1] ERROR: Line 132 is out of range in the file [...]
We traced this problem to one of those the auto-generated MoveNext()
methods. Interestingly enough, when I merge the files using ReportGenerator it doesn't include these methods:
reportgenerator -reports:.coverage/**/*.cobertura.xml -reporttypes:Cobertura -targetdir:.
I can then "merge" the files to get into the correct format using:
dotnet-coverage merge .\Cobertura.xml -f xml -o coverage.xml
This gives me a coverage file with the MoveNext()
methods excluded, and SonarQube is happy. This is a needless complexity though, and I would prefer just to have them excluded by Coverlet.
Is there any way to achieve this?