Search code examples
.netunit-testingcode-coveragexunitcoverlet

Code Coverage file contains coverage of Irrelevant assemblies does not exclude even exclude with runsettings?


The project I am working on has a test project. As part of the test run, It generates a code coverage file. It used the below command to test and generate coverage XML.

dotnet test --collect:"XPlat Code Coverage" --settings .\CodeCoverage.runsettings

The issue is coverage file contains code coverage about Microsoft.IdentityModel.Clients.ActiveDirectory and HtmlAgilityPack other than the project assemblies. So I want to exclude those coverage data from the report and change .runsetting files as below. ( ) But it doesn't work. Here one other things is in Include I only include to have coverage for XXX.Search.dll but coverage include other project assemblies as well.

One other interesting thing I noticed is If I run the dotnet test without having --settings .\CodeCoverage.runsettings It would generate the same report.

I refer all possible options in here but did work for me. Using .runsettings to exclude assemblies from code coverage

    <?xml version="1.0" encoding="utf-8"?>
<RunSettings>
    <DataCollectionRunSettings>
        <DataCollectors>
            <DataCollector friendlyName="XPlat code coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
                <Configuration>
                    <CodeCoverage>
                        <!-- Match assembly file paths: -->
                        <ModulePaths>
                            <Include>
                                <ModulePath>.*\\XXX\.Search\.dll$</ModulePath>
                            </Include>
                            <Exclude>
                                <ModulePath>.*\\[^\\]*microsoft[^\\]*\.dll</ModulePath>
                                <ModulePath>.*\\Microsoft\.IdentityModel\.Clients\.ActiveDirectory\.dll$</ModulePath>
                                <ModulePath>.*\\HtmlAgilityPack\.dll$</ModulePath>
                            </Exclude>
                        </ModulePaths>
                        <!-- Match the company name property in the assembly: -->
                        <!-- Match fully qualified names of functions: -->
                        <!-- (Use "\." to delimit namespaces in C# or Visual Basic, "::" in C++.) -->
                        <Functions>
                            <Exclude>
                                <Function>^Fabrikam\.UnitTest\..*</Function>
                                <Function>^std::.*</Function>
                                <Function>^ATL::.*</Function>
                                <Function>.*::__GetTestMethodInfo.*</Function>
                                <Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
                                <Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
                            </Exclude>
                        </Functions>
                        <!-- Match attributes on any code element: -->
                        <Attributes>
                            <Exclude>
                                <!-- Don't forget "Attribute" at the end of the name -->
                                <Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
                                <Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
                                <Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
                                <Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
                            </Exclude>
                        </Attributes>
                        <!-- Match the path of the source files in which each method is defined: -->
                        <Sources>
                            <Exclude>
                                <Source>.*\\atlmfc\\.*</Source>
                                <Source>.*\\vctools\\.*</Source>
                                <Source>.*\\public\\sdk\\.*</Source>
                                <Source>.*\\microsoft sdks\\.*</Source>
                                <Source>.*\\vc\\include\\.*</Source>
                            </Exclude>
                        </Sources>
                        <!-- Match the company name property in the assembly: -->
                        <CompanyNames>
                            <Exclude>
                                <CompanyName>.*microsoft.*</CompanyName>
                            </Exclude>
                        </CompanyNames>
                        <!-- Match the public key token of a signed assembly: -->
                        <PublicKeyTokens>
                            <!-- Exclude Visual Studio extensions: -->
                            <Exclude>
                                <PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
                                <PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
                                <PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
                                <PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
                                <PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
                                <PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
                                <PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
                            </Exclude>
                        </PublicKeyTokens>
                        <!-- We recommend you do not change the following values: -->
                        <!-- Set this to True to collect coverage information for functions marked with the "SecuritySafeCritical" attribute. Instead of writing directly into a memory location from such functions, code coverage inserts a probe that redirects to another function, which in turns writes into memory. -->
                        <UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
                        <!-- When set to True, collects coverage information from child processes that are launched with low-level ACLs, for example, UWP apps. -->
                        <AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
                        <!-- When set to True, collects coverage information from child processes that are launched by test or production code. -->
                        <CollectFromChildProcesses>True</CollectFromChildProcesses>
                        <!-- When set to True, restarts the IIS process and collects coverage information from it. -->
                        <CollectAspDotNet>False</CollectAspDotNet>
                        <!-- When set to True, static native instrumentation will be enabled. -->
                        <EnableStaticNativeInstrumentation>True</EnableStaticNativeInstrumentation>
                        <!-- When set to True, dynamic native instrumentation will be enabled. -->
                        <EnableDynamicNativeInstrumentation>True</EnableDynamicNativeInstrumentation>
                        <!-- When set to True, instrumented binaries on disk are removed and original files are restored. -->
                        <EnableStaticNativeInstrumentationRestore>True</EnableStaticNativeInstrumentationRestore>
                    </CodeCoverage>
                </Configuration>
            </DataCollector>
        </DataCollectors>
    </DataCollectionRunSettings>
</RunSettings>

Solution

  • As with the comment of jessehouwing It hints to me the setting file varies based on datacollector which is specifying with --collect option in dotnet test command. In my case I used XPlat Code Coverage collector option whereas other collector option exist like Code Coverage

    https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test

    In my scenario I used XPlat Code Coverage option which is Coverlet so As runsettings I should used Coverlet settings instead of what I used which is used for Code Coverage options. How to write coverlet setting file can be found in here. https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/VSTestIntegration.md

    enter image description here