使用runsettings无法排除代码覆盖率文件中无关程序集的问题
问题解决:XPlat Code Coverage配置不生效的处理方案
问题场景
我负责的项目包含测试项目,执行测试生成代码覆盖率文件的命令为:
dotnet test --collect:"XPlat Code Coverage" --settings .\CodeCoverage.runsettings
遇到的问题:
- 覆盖率报告中除了目标项目
XXX.Search.dll的程序集,还混入了Microsoft.IdentityModel.Clients.ActiveDirectory和HtmlAgilityPack的覆盖率数据 - 修改
.runsettings文件尝试排除第三方程序集,但完全无效 - 仅在Include节点指定
XXX.Search.dll,报告仍包含其他项目程序集 - 不带
--settings .\CodeCoverage.runsettings参数执行dotnet test,生成的报告和带参数时完全一致
当前.runsettings配置:
<?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>
修复方案
1. 确保配置文件被正确加载
不带参数报告完全一致,说明配置未被读取:
- 检查命令执行的工作目录是否与
.runsettings所在目录一致,或改用绝对路径指定配置文件:dotnet test --collect:"XPlat Code Coverage" --settings "C:\Projects\YourProject\CodeCoverage.runsettings" - 确认文件名拼写正确,跨平台环境注意大小写。
2. 修正正则匹配规则
XPlat Code Coverage的正则基于程序集完整路径,调整规则兼容不同路径分隔符:
<ModulePaths> <Include> <ModulePath>.*[\\/]XXX\.Search\.dll$</ModulePath> </Include> <Exclude> <ModulePath>.*[\\/]Microsoft\.IdentityModel\.Clients\.ActiveDirectory\.dll$</ModulePath> <ModulePath>.*[\\/]HtmlAgilityPack\.dll$</ModulePath> <!-- 一键排除NuGet包目录下所有程序集 --> <ModulePath>.*[\\/]packages[\\/].*</ModulePath> </Exclude> </ModulePaths>
3. 补充强排除规则
在CodeCoverage节点下新增以下配置,强化排除逻辑:
<CodeCoverage> <!-- 原有配置保留 --> <!-- 强制排除自动生成代码 --> <ExcludeByAttribute> <Attribute>System.CodeDom.Compiler.GeneratedCodeAttribute</Attribute> <Attribute>System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute</Attribute> </ExcludeByAttribute> <!-- 排除NuGet包目录下的源文件 --> <ExcludeByFile> <File>.*packages.*</File> </ExcludeByFile> </CodeCoverage>
4. 清理缓存后重新执行
旧缓存可能导致配置不生效:
- 删除测试项目的
bin、obj目录 - 删除
TestResults覆盖率报告目录 - 重新运行测试命令
5. 更新coverlet.collector版本
旧版本存在配置解析bug,在测试项目.csproj中更新包版本:
<PackageReference Include="coverlet.collector" Version="6.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference>
内容的提问来源于stack exchange,提问作者Amal Shalika
相关产品推荐
相关产品推荐

