Search code examples
c#entity-framework-corenunitcode-coveragecoverlet

exclude code coverage for ef core migration files


I want to exclude all auto generated migration files from code coverage caculation. I can't change the dotnet test command in the build pipeline so I guess my only friend is the [ExcludeFromCodeCoverage] attribute.

The tricky part is that everytime I add a new migration, I need to manually review all generated files and ensure I have [ExcludeFromCodeCoverage] attribtute on all generated classes, this is fine but I am wondering is there a better solution that I can do it once and for all?

The migration file

[ExcludeFromCodeCoverage] // Manually added everytime
partial class Initial : Migration

And the ModelSnapshot file

[ExcludeFromCodeCoverage] // This gets removed everytime snapshot is updated
[DbContext(typeof(MyContext))]
partial class MyContextModelSnapshot : ModelSnapshot

For the snapshot file, since the class name is always the same I can creat a sperate file MyContextModelSnapshot.CodeCoverage.cs file and put the attribute on the partial class, but is there a solution for the Migration files?

I am working with coverlet.msbuild if it matters.


Solution

  • First of all make sure the problem is not the detection of the .runsettings file.

    Apparently for dotnet test the relative path "./" doesn't work. So you should use the full path (I was not able to make it work with this)

    [refer to this article] https://alexanderontesting.com/2019/03/12/applying-a-runsettings-file-file-from-the-command-line-in-net-core/

    But if you are using coverlet.

    You can use the param excludeByFile

    If I try running using .runsettings file (relative path)

    <?xml version="1.0" encoding="utf-8"?>
    <RunSettings>
      <DataCollectionRunSettings>
        <DataCollectors>
          <DataCollector friendlyName="XPlat code coverage">
            <Configuration>
              <Format>cobertura</Format>                              
              <ExcludeByFile>"**/*Migrations/*.cs"</ExcludeByFile>       
            </Configuration>
          </DataCollector>
        </DataCollectors>
      </DataCollectionRunSettings>
    </RunSettings>
    

    With the -s param to use your .runsettings file

    dotnet test /p:CollectCoverage=true -s .\coverlet.runsettings

    The result is not the excpected (1% line coverage due migrations files)

    +---------+------+--------+--------+
    |         | Line | Branch | Method |
    +---------+------+--------+--------+
    | Total   | 1.3% | 25.03% | 23.93% |
    +---------+------+--------+--------+
    | Average | 1.3% | 25.03% | 23.93% |
    +---------+------+--------+--------+
    

    But if I add the param from command line (like this)

     dotnet test /p:CollectCoverage=true /p:ExcludeByFile="**/*Migrations/*.cs"
    

    The result is the expected (38% line coverage)

    +---------+--------+--------+--------+
    |         | Line   | Branch | Method |
    +---------+--------+--------+--------+
    | Total   | 38.83% | 25.03% | 27.24% |
    +---------+--------+--------+--------+
    | Average | 38.83% | 25.03% | 27.24% |
    +---------+--------+--------+--------+
    

    The available params going to depend on your test tool (For coverlet you can refer to):

    https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/VSTestIntegration.md

    Hope this help