如何使Sonarqube排除.NET(C#)项目的覆盖率统计

36
Sonarqube允许通过在sonar.coverage.exclusions关键字中添加模式来排除单个文件的代码覆盖率。这可以通过在UI中添加它们甚至在.csproj文件中指定一个SonarQubeSetting元素来在项目级别完成。例如:

<SonarQubeSetting Include="sonar.coverage.exclusions"> <Value>**/*.cs</Value> </SonarQubeSetting>

然而,这两种方法似乎都不起作用。根据SonarQube文档中指定的模式,无法获得期望的结果。我也知道SonarQubeExclude MSBuild属性的存在,但我不想走这条路,因为这会将我的项目从所有其他分析中排除。

还有其他可能性吗?或者说不可能排除项目中的所有类的代码覆盖率?


你是否尝试过像这样在命令行中传递参数: SonarQube.Scanner.MSBuild.exe" begin /d:sonar.coverage.exclusions=**\MyLib1\MyPath1*,**\MyLib2\MyPath2* 在我的情况下非常有效。 - Peska
@Peska,你使用的是哪个版本的SonarQube/MSBuild扫描器?在我的情况下,这并不能按照预期工作。 - mvandevy
SonarQube版本6.7.1.35068。SonarScanner MSBuild 4.0.2.892。这是一个完整示例:"C:\PathToSonarQubeScanner\SonarQube.Scanner.MSBuild.exe" begin /k:"ProjectKey" /n:"ProjectName" /v:"1.0.0" /d:sonar.coverage.exclusions=**\PathToExclude\**,**\PathToExlude2\** "C:\PathToMSBuild\MSBuild.exe" SolutionFile.sln /t:Rebuild "C:\PathToSonarQubeScanner\SonarQube.Scanner.MSBuild.exe" end - Peska
6个回答

52

总结以上提到的答案并补充一个要点。

  1. 从csproj中排除一个项目,我们可以通过在该项目的.csproj文件中添加以下代码来实现

    <PropertyGroup>
    <!-- Exclude the project from analysis -->
    <SonarQubeExclude>true</SonarQubeExclude>
    </PropertyGroup>
    
  2. 排除项目中的一个文件

  3.  <ItemGroup>
     <SonarQubeSetting Include="sonar.coverage.exclusions">
     <Value>**/FileName.cs</Value>
     </SonarQubeSetting>
     </ItemGroup>
    
  4. 而对于多个文件

  5. <ItemGroup>
    <SonarQubeSetting Include="sonar.coverage.exclusions">
    <Value>**/FileName1.cs, **/FileName2.cs</Value>
    </SonarQubeSetting>
    </ItemGroup>
    

还可以参考此处使用的正则表达式模式


12

声望不够,无法发表评论,但如果你将这两个答案结合起来应用,你可以简单地添加:

<PropertyGroup>
    <!-- Exclude the project from analysis -->
    <SonarQubeExclude>true</SonarQubeExclude>
</PropertyGroup>

可以在.csproj文件中排除整个项目而不是单个文件,或者依赖于SonarQube筛选器。


6

一些概念:

.NET解决方案是SonarQube项目。 .NET解决方案的项目是SonarQube项目的模块。

特定的SonarQube MsBuild分析器将找到所有csproj / vbproj。 对于每个.NET项目,分析器应用SonarQube项目的设置。

如果你的代码库是:

MyApp.sln
MyApp.Shell\
    MyApp.Shell.csproj
    Windows\MainWindows.cs
MyApp.Core\
    MyApp.Core.csproj
    FooService.cs

要忽略MyApp.Shell项目的代码覆盖率,您需要直观地添加设置sonar.coverage.exclusions=MyApp.Shell\*。但是,MsBuild分析器会单独分析每个.NET项目,并且根目录直接位于csproj/vbproj目录中。当分析MyApp.Shell.csproj时,忽略模式MyApp.Shell\*将应用于Windows\MainWindows.cs
要从代码覆盖率中排除特定项目,我们需要在SonarQube的模块(.NET项目)级别应用此设置。我找到了两种解决方案。 1)在csproj中添加属性“sonar.coverage.exclusions” 在您的<.NET项目>.csproj中添加以下内容:
<Project ...>
  ...
    <ItemGroup>
      <SonarQubeSetting Include="sonar.coverage.exclusions">
        <Value>**</Value>
      </SonarQubeSetting>
    </ItemGroup>
  ...
</Project>

2) 配置Sonarqube Web界面中的排除选项

从更新到SonarQube 8.*版本后,我无法在界面中检索到该选项。

参考:SonarQube MSBuild Scanner doesn't exclude files from analysis

  • 打开Sonarqube项目 -> Code(在顶部菜单)
  • 打开Sonarqube模块(左侧图标“打开组件页面”) -> Administration(在顶部菜单) -> General Settings
  • 在Codecoverage exclusion中添加 **:

(屏幕截图为法语,但您可以看出来) Sonarqube Web UI

这两个解决方案对我都有效,但我更希望能够设置一个全局选项来排除.NET解决方案中的文件。


1
只有在删除“<Target Name =”BeforeBuild“>”标签时,它才对我起作用... - FrankyHollywood
@FrankyHollywood,我之前使用的是一个旧版的SonarQube 6.*,升级到8.*后我还需要删除目标部分。我已经编辑了我的回答。 - vernou

5

经过尝试了无数方法,我终于找到了解决方案。需要在 .csproj 中添加一个项组。

<ItemGroup>
    <Compile Update="ClassToExclude.cs">
      <!-- Exclude the file from analysis -->
      <SonarQubeExclude>true</SonarQubeExclude>
    </Compile>
  </ItemGroup>

在WebForms中工作对我来说,排除一个文件。谢谢。 - Pramesh

1

这是一个老问题,但更准确的答案在这里发布:https://dev59.com/PFUL5IYBdhLWcg3wx6hw#49904805

基本上,代码选项卡允许深入到项目的设置中,我们可以在管理(项目)->常规设置->分析范围->覆盖排除中使用 **。


1
我曾经遇到过同样的问题,花费了一些时间才解决了它:
在解决方案目录下设置一个名为Directory.Build.props的文件,并将其内容设置为以下内容:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

  <!-- This target customises the SonarQube MSBuild runner targets to limit the projects that are analysed.

       Projects whose full path and file name match the specified filter will be marked as "excluded".

       Note that this targets file does not ever set $(SonarQubeExclude) to "false". This is to allow other
       targets to exclude projects for other reasons (e.g. a Fakes projects should always be excluded, regardless
       of whether or not they match the project filter).

       Also, this project will do nothing if $(SonarQubeExclude) has already been set.

       The regular expression uses the normal .NET regular expression syntax.

       Usage:
       (1) include the target in the projects being built, either by directly importing it or by
           dropping it in the one of the standard "ImportBefore" folders.

       (2) set $(SQExclusionFilter) to the desired regular expression
           e.g. the following example matches all projects with "CodeSense\Services" in the path:  .*\\CodeSense\\Services\\.*

  -->
  <PropertyGroup Condition=" $(SonarQubeExclude) == '' AND $(SQExclusionFilter) != '' ">

      <MatchesSQExclusionFilter Condition="$([System.Text.RegularExpressions.Regex]::IsMatch($(MSBuildProjectFullPath), $(SQExclusionFilter), System.Text.RegularExpressions.RegexOptions.IgnoreCase)) ">true</MatchesSQExclusionFilter>
      <SonarQubeExclude Condition="$(MatchesSQExclusionFilter) == 'true' " >true</SonarQubeExclude>

  </PropertyGroup>

  <!-- This target is not required: it simply writes out additional information to simplify debugging -->
  <Target Name="AnalysisProjectInfoExclude_DEBUG" BeforeTargets="CoreCompile"
          Condition="$(SQExclusionFilter) != '' ">

    <Message Importance="high" Text="ExclusionFilter: filter has been set.  Filter= $(SQExclusionFilter)" />
    <Message Importance="high" Text="ExclusionFilter: current project = $(MSBuildProjectFullPath)" />
    <Message Importance="high" Text="ExclusionFilter: match result = $(MatchesSQExclusionFilter)" />

    <Message Importance="high" Condition="$(MatchesSQExclusionFilter) == 'true' "
       Text="ExclusionFilter: project is excluded" />

    <Message Importance="high" Condition="$(MatchesSQExclusionFilter) != 'true' "
       Text="ExclusionFilter: project has not been excluded by the exclusion filter" />

  </Target>

</Project>

https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build 所述,此片段将被包含在所有项目文件中。

相应地,在环境变量SQExclusionFilter中设置正则表达式。使用双反斜杠进行路径分隔。在Windows shell中,用插入符转义管道字符:例如

set SQExclusionFilter=(path1\\project)^|(path2\\project)

感谢来自SQ/MS的Duncan Pocklington!


我已经查看了您的解决方案,但是我无法看出这些MSBuild变量与SonarQube之间的关系。这些变量是在SonarQube中预定义的吗?这也可能意味着您正在尝试排除整个项目,而我只想排除代码覆盖率。 - mvandevy
@mvandevy,你是对的,该解决方案将从所有分析中排除一个项目。 如果过滤器命中一个项目,则会向该项目添加XML片段<SonarQubeExclude>true</SonarQubeExclude>, 从而抑制该项目的SonarQube。 - Reinhard Mayr
4
在SonarQube中,仅为了将文件排除在代码覆盖率分析之外,就需要这种复杂性,这实在太糟糕了。 - Paul Siersma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接