【问题标题】:How to import nUnit/OpenCover results to SonarQube如何将 nUnit/OpenCover 结果导入 SonarQube
【发布时间】:2020-01-09 03:37:02
【问题描述】:

我们正在运行 SonarQube 社区版版本 7.9.1(内部版本 27448)(当前最新的 docker 映像)

我有一些 nUnit 测试,但我很难将代码覆盖率数据导入 SonarQube。

我已成功使用 SonarScanner.MSBuild (sonar-scanner-msbuild-4.6.2.2108-net46) 使用以下命令将代码分析和 nUnit 测试数量导入 SonarQube:

SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml" 
MSBuild.exe ....sln /t:Rebuild
nunit3-console.exe --result=NUnitResults.xml path\to\tests.dll
SonarScanner.MSBuild.exe end /d:sonar.login="..."

现在我想使用 OpenCover 来获取 SonarQube 的代码覆盖率信息,所以我使用以下命令

SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml" /d:sonar.cs.opencover.reportsPaths="opencover.xml"
MSBuild.exe ....sln /t:Rebuild
nunit3-console.exe --result=NUnitResults.xml path\to\tests.dll
OpenCover.Console.exe -output:opencover.xml -register:user -target:"nunit3-console.exe" -targetargs:"path\to\tests.dll --result=NUnitResults.xml"
SonarScanner.MSBuild.exe end /d:sonar.login="..."

[我认为我可能不必要地运行了两次 nUnit 测试,但是一旦我解决了以下问题,我就会解决这个问题]

问题是我没有在 SonarQube 上获得任何代码覆盖率详细信息。

检查 SonarScanner 日志,我可以看到 OpenCover 的以下输出:

Executing: nunit3-console.exe
NUnit Console Runner 3.10.0 (.NET 2.0)
Copyright (c) 2019 Charlie Poole, Rob Prouse
06 September 2019 09:24:53

Runtime Environment
   OS Version: Microsoft Windows NT 10.0.14393.0
  CLR Version: 4.0.30319.42000

Test Files
    path\to\UnitTests.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: ...
    ImageRuntimeVersion: 4.0.30319
    ImageTargetFrameworkName: .NETFramework,Version=v4.6.1
    ImageRequiresX86: False
    ImageRequiresDefaultAppDomainAssemblyResolver: False
    NumberOfTestWorkers: 8

Test Run Summary
  Overall result: Passed
  Test Count: 35, Passed: 35, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2019-09-06 08:24:54Z
    End time: 2019-09-06 08:24:57Z
    Duration: 3.111 seconds

Results (nunit3) saved as NUnitResults.xml
Committing...
Visited Classes 12 of 12 (100)
Visited Methods 41 of 41 (100)
Visited Points 240 of 240 (100)
Visited Branches 41 of 41 (100)

==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 12 of 12 (100)
Alternative Visited Methods 41 of 53 (77.36)

现在检查目录,我可以看到我创建并填充了 NUnitResults.xmlopencover.xml。 (我真的不知道如何阅读 OpenCover 结果,但它有用于我的单元测试的数据)

SonarScanner.MSBuild.exe end 日志中有这样的花絮:

信息:传感器 C# 测试覆盖报告导入 [csharp]

INFO:解析 OpenCover 报告路径。\opencover.xml

INFO:将此代码覆盖率报告添加到缓存中以供以后重用:path.\opencover.xml

警告:代码覆盖率报告不包含所包含文件的任何覆盖率数据。疑难解答提示请参考https://docs.sonarqube.org/x/CoBh

INFO:传感器 C# 测试覆盖报告导入 [csharp](完成)|时间=14ms

INFO:传感器 C# 单元测试结果导入 [csharp]

INFO:解析 NUnit 测试结果文件路径。\NUnitResults.xml

INFO:传感器 C# 单元测试结果导入 [csharp](完成)|时间=34ms

现在包含单元测试涵盖的类(我可以在 SonarQube 中看到它们被标记为未覆盖),所以我猜 OpenCover 没有收集正确的信息,或者将覆盖的文件与解决方案。

n.b.检查这些测试应该涵盖的项目,在 Project > Build > Advanced 下,Debug Info 设置为 full 以进行调试配置,一些资源似乎表明这是必需的。

知道我错过了什么/哪里出错了吗?

更新

检查opencode.xml的底部有以下内容:

<Module skippedDueTo="MissingPdb" hash="DD-83-09-69-9F-A7-11-FF-F5-BC-43-7C-87-B2-54-99-0D-A5-D5-61">
  <ModulePath>C:\Windows\Microsoft.Net\assembly\GAC_MSIL\MyCompany.Common.Utility\v4.0_1.0.0.0__bf95fa7f15863c9f\MyCompany.Common.Utility.dll</ModulePath>
  <ModuleTime>2019-09-05T16:07:28.6111533Z</ModuleTime>
  <ModuleName>MyCompany.Common.Utility</ModuleName>
  <Classes />
</Module>

这个解决方案的原作者似乎喜欢把所有东西都推到 GAC 中,所以我猜 OpenCover 是在 GAC 中而不是在本地寻找 dll,而 GAC 不保存 pdb。

我尝试按照手册中的建议设置 OpenCover -targetdir 设置:

目标目录的路径;如果目标参数已包含路径,则此参数可用于提供可以找到 PDB 文件的备用路径。

我还尝试使用 -searchdirs(寻找 PDB 的替代位置。)

但他们都没有解决它。

我可以告诉 OpenCover 使用 bin\Debug pdbs 吗?

【问题讨论】:

  • Open Cover 是一个 XML 文件,您可以使用记事本查看。 xml 可能正在使用 XML 序列化,它使用项目中的类来生成文件。 Xml 数据只会出现在 PUBLIC 的属性上。因此,如果 xml 缺少数据,请检查以确保缺少的属性是公开的。
  • 嗨@jdweng,我应该更清楚我知道如何读取 XML 文件,只是不知道如何解释 OpenCover 数据。话虽如此,仔细观察会发现我更新中的数据,所以感谢您让我仔细观察!
  • SonarQube 似乎只是在报告 VS 项目和数据库之间的数据。请参阅以下图表:docs.sonarqube.org/latest/architecture/architecture-integration
  • 是的,我想我已经缩小了问题范围以排除 SonarQube。我认为它在 GAC 中查找时没有找到 PDB 文件是公开的。现在我是编辑问题还是打开一个新问题? ??????
  • 可能会打开一个新的,因为标签 sonaqube 不适用。

标签: c# sonarqube opencover


【解决方案1】:
Step1 : SonarScanner.MSBuild.exe begin /k:"Project-Name" /d:sonar.cs.opencover.reportsPaths=%cd%\TestCoverResult.xml /d:sonar.exclusions="**/*.css,**/*.js,**/*.cshtml" /d:sonar.verbose="true" /d:sonar.host.url="https://host-url.com/" /d:sonar.login="Login-Token"

Step2 :  "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" /t:Rebuild  

Step3 : ".\packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe" "-target:.\packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe"  "-targetargs:.\Test-Project\bin\Debug\Test-Project.dll" "-output:.\TestCoverResult.xml" -register:user

Step4 :  SonarScanner.MSBuild.exe end   

解释:

1:reportsPath:指定代码覆盖结果文件的路径。

2 : ".\packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe" : 是"OpenCover.Console.exe"的系统路径

3 : ".\packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe" : 为“nunit3-console.exe”的系统路径

【讨论】:

    【解决方案2】:

    https://github.com/OpenCover/opencover/wiki/Usage#notes-on-spaces-in-arguments

    在 targetargs 中使用 \" 来表示 nunit3-console 的引号

    SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml" /d:sonar.cs.opencover.reportsPaths="opencover.xml"
    MSBuild.exe ....sln /t:Rebuild
    OpenCover.Console.exe -output:opencover.xml -register:user -target:"nunit3-console.exe" -targetargs:"\"path\to\tests.dll\" --result=NUnitResults.xml"
    SonarScanner.MSBuild.exe end /d:sonar.login="..."
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      • 2014-11-30
      • 1970-01-01
      相关资源
      最近更新 更多