0

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/&lt;CreateMessages&gt;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?

ilitirit
  • 16,016
  • 18
  • 72
  • 111

0 Answers0