【问题标题】:dotnet cli - specified .runsettings file not used in code coverage rundotnet cli - 代码覆盖运行中未使用指定的 .runsettings 文件
【发布时间】:2019-01-18 18:57:35
【问题描述】:

我有一个包含两个 dotnet core 2.1 项目 (c#) 的解决方案。

  1. 第一个是控制台应用程序

  2. 秒是一个带有单元测试的测试项目

我在使用以下命令在项目 2 中执行测试时生成关于项目 1 的代码覆盖率统计信息:

dotnet test C:\tempDir\SampleApp\Tests\SampleApp.Tests.csproj 
/p:CollectCoverage=true /p:CoverletOutputFormat=cobertura 
/p:CoverletOutput=C:\tempDir\Coverage\coverage 
/p:settings=CodeCoverage.runsettings --filter Category=Unit --logger trx 
--results-directory C:\tempDir\output

您可以在这里看到我将 CodeCoverage.runsettings 指定为 settings 参数 - /p:settings=CodeCoverage.runsettings。在我的运行设置文件中,我要求将 Program.csStartup.cs 排除在覆盖范围之外,但它们仍包含在输出 coverage.cobertura.xml 文件中。

从下面的输出报告中摘录:

<classes>
    <class name="SampleApp.Startup" filename="SampleApp\Startup.cs" line-rate="1" branch-rate="0" complexity="2">
      <methods>
        <method name="ConfigureAppConfiguration" signature="(Microsoft.Extensions.Configuration.IConfigurationBuilder)" line-rate="1" branch-rate="0">
          <lines>
            <line number="18" hits="1" branch="False" />
            <line number="19" hits="1" branch="False" />
            <line number="20" hits="1" branch="False" />
          </lines>
        </method>
        <method name="ConfigureLogging" signature="(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILoggingBuilder)" line-rate="1" branch-rate="0">
          <lines>
            <line number="23" hits="1" branch="False" />
            <line number="24" hits="1" branch="False" />
            <line number="25" hits="1" branch="False" />
            <line number="26" hits="1" branch="False" />
            <line number="27" hits="1" branch="False" />
          </lines>
        </method>
      </methods>
      <lines>
        <line number="18" hits="1" branch="False" />
        <line number="19" hits="1" branch="False" />
        <line number="20" hits="1" branch="False" />
        <line number="23" hits="1" branch="False" />
        <line number="24" hits="1" branch="False" />
        <line number="25" hits="1" branch="False" />
        <line number="26" hits="1" branch="False" />
        <line number="27" hits="1" branch="False" />
      </lines>
    </class>
</classes>

我想知道我在runsettings 文件中做错了什么? (文件内容如下)

<?xml version="1.0" encoding="utf-8"?>

<RunSettings>
    <!-- Configurations for data collectors -->
    <DataCollectionRunSettings>
        <DataCollectors>
            <DataCollector friendlyName="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>

                        <ModulePaths>
                            <Include>
                                <ModulePath>.*dll$</ModulePath>
                            </Include>
                            <Exclude>
                                <ModulePath>.*microsoft.*</ModulePath>
                                <ModulePath>.*moq.*</ModulePath>
                                <ModulePath>.*polly.*</ModulePath>
                                <ModulePath>.*fluentassertions.*</ModulePath>
                                <ModulePath>.*newtonsoft.*</ModulePath>
                                <ModulePath>.*SampleApp.Tests.*</ModulePath>
                                <ModulePath>.*\\[^\\]*DocumentManagement[^\\]*\.dll</ModulePath>
                            </Exclude>
                        </ModulePaths>

                        <Functions>
                            <Exclude>
                                <Function>.*\.Program\..*</Function>
                                <Function>.*\.Startup\..*</Function>
                                <Function>.*\.SomeOtherClass\..*</Function>
                            </Exclude>
                        </Functions>

                        <Attributes>
                            <Exclude>
                                <Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
                                <Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
                                <Attribute>^System\.Runtime\.CompilerServices.CompilerGeneratedAttribute$</Attribute>
                                <Attribute>^System\.CodeDom\.Compiler.GeneratedCodeAttribute$</Attribute>
                                <Attribute>^System\.Diagnostics\.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
                            </Exclude>
                        </Attributes>

                        <!-- We recommend you do not change the following values: -->
                        <UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
                        <AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
                        <CollectFromChildProcesses>True</CollectFromChildProcesses>
                        <CollectAspDotNet>False</CollectAspDotNet>

                    </CodeCoverage>
                </Configuration>
            </DataCollector>

        </DataCollectors>
    </DataCollectionRunSettings>
</RunSettings>

当我在 runsettings 文件中指定跳过此部分时,不确定为什么此部分仍在此输出报告中。

注意:我试图避免在我的代码中添加[ExcludeFromCodeCoverage] 属性,并且我不想在构建时将/p:ExcludeByFile=Program.cs/p:ExcludeByFile=Startup.cs 添加到我的测试命令中,因此使用runsettings 文件.

【问题讨论】:

  • 您尝试从包含部分删除 dll 吗?
  • 但我想要 dll,而不是 dll 中的两个类...

标签: c# .net testing code-coverage cobertura


【解决方案1】:

您不能使用运行设置文件仅通过提供类名来排除类。

运行设置中的 Function 元素与函数/方法的全名匹配,例如

YourNamespace.YourClass.Method(parameters);

只有以下设置是可能的from the documentation

包含或排除元素的其他方式 ModulePath - 匹配 程序集文件路径指定的程序集。

CompanyName - 按 Company 属性匹配程序集。

PublicKeyToken - 通过公钥令牌匹配签名的程序集。

Source - 通过源文件的路径名匹配元素 它们被定义了。

Attribute - 匹配具有特定属性的元素 随附的。指定属性的全名,并包括 名称末尾的“属性”。

Function - 完全匹配过程、函数或方法 限定名称。要匹配函数名,正则表达式必须 匹配函数的完全限定名,包括命名空间, 类名、方法名和参数列表。

你有什么选择:

选项 1:使用以 OR 开头的方法名

        <Functions>
          <Exclude>

            <!-- Exclude all methods in SampleApp.Program : -->
            <Function>^SampleApp\.Program\..*</Function>

            <!-- Exclude all methods named Main: -->
            <Function>.*\.Main\(.*</Function>
          </Exclude>
        </Functions>

在第一个函数中,请注意你的命名空间和类名是指定的,它以 ^ 字符开头。

在第二个函数元素中,请注意它是通过检查字符串是否以左括号'('结尾来检查方法名称。

选项 2:您可以在类上使用属性并将它们从运行设置文件中排除。

这类似于 ExcludeFromCodeCoverate 属性。

请注意完整的runsettings file at the end of this documentation page.

【讨论】:

  • 你能解释一下 ^ 和 (.* 字符在正则表达式示例中的作用吗?你给出的例子是包含 - 你有一个等价的排除吗?一个示例函数可能是SampleApp.Program.Main (这是我的应用程序的主要方法) - 我怎么能排除它?感谢您的帮助!
  • ^ 暗示完全限定名称应以此字符串开头。 ( 如果要指定排除特定方法,则需要。我已经更新了排除示例。
  • 当我在 runsettings 文件中使用它时,仍然对我不起作用。我从命令行使用以下命令(这并不优雅)。这确实可以从命令行工作:dotnet test C:\tempDir\SampleApp\Tests\SampleApp.Tests.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=C:\tempDir\Coverage\coverage /p:Exclude="[*]*Startup%2c[*]*Program" /p:ExcludeByAttribute="Obsolete%2cExcludeFromCodeCoverage" --filter "Category=Unit"
  • @RobMcCabe,请添加您的提示作为答案。有用! /p:Exclude="[*]*Startup%2c[*]*Program"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多