1
votes

We are running SonarQube Community Edition Version 7.9.1 (build 27448) (the currently latest docker image)

I have some nUnit tests but I'm struggling to get the code coverage data imported to SonarQube.

I have successfully used SonarScanner.MSBuild (sonar-scanner-msbuild-4.6.2.2108-net46) to import the code analysis and number of nUnit tests to SonarQube using the following commands:

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="..."

Now I want to use OpenCover to get the code coverage info to SonarQube so I'm using the following commands

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="..."

[I think I'm probably unnecessarily running the nUnit tests twice, but I'll sort that out once I've resolved the following issue]

The problem is I'm not getting any code coverage details on SonarQube.

Checking the SonarScanner log I can see the following output from 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)

Now checking the dir I can see I have NUnitResults.xml and opencover.xml created and populated. (I don't really know how to read OpenCover results but it has data for my unit tests)

The SonarScanner.MSBuild.exe end log has this tidbit:

INFO: Sensor C# Tests Coverage Report Import [csharp]

INFO: Parsing the OpenCover report path.\opencover.xml

INFO: Adding this code coverage report to the cache for later reuse: path.\opencover.xml

WARN: The Code Coverage report doesn't contain any coverage data for the included files. For troubleshooting hints, please refer to https://docs.sonarqube.org/x/CoBh

INFO: Sensor C# Tests Coverage Report Import [csharp] (done) | time=14ms

INFO: Sensor C# Unit Test Results Import [csharp]

INFO: Parsing the NUnit Test Results file path.\NUnitResults.xml

INFO: Sensor C# Unit Test Results Import [csharp] (done) | time=34ms

Now the classes that the unit tests cover are included (I can see them in SonarQube marked as uncovered) so I guess either OpenCover isn't collecting the correct info or something is going wrong matching the covered files with the file in the solution.

n.b. Checking the project that should be covered by these tests, under Project > Build > Advanced the Debug Info is set to full for Debug configuration, which some resources seem to suggest is required.

Any idea what I'm missing/where I'm going wrong?

UPDATE

Checking the bottom of opencode.xml it has the following:

<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>

The original authors of this solution seemed to like shoving everything in the GAC, so I'm guessing OpenCover is looking in the GAC rather than locally for the dll, and the GAC doesn't hold pdbs.

I tried setting the OpenCover -targetdir setting as suggested in the manual:

The path to the target directory; if the target argument already contains a path then this argument can be used to provide an alternate path where PDB files may be found.

I also tried to use -searchdirs (Alternative locations to look for PDBs.)

but neither of them resolved it.

Can I tell OpenCover to use the bin\Debug pdbs?

1
Open Cover is an XML file and you can view with Notepad. The xml is probably using XML Serialization which is use classes from your project to generate the file. Xml data will only appear on properties that are PUBLIC. So if the xml is missing data then check to make sure the missing properties are public.jdweng
Hi @jdweng, I should have been clearer I know how to read XML files, just don't know how to interpret the OpenCover data. That being said a closer look revealed the data in my update, so thanks for making me take a closer look!mattumotu
It looks like SonarQube is just reporting the data going between the VS project and the database. See idagram on following : docs.sonarqube.org/latest/architecture/architecture-integrationjdweng
Yeah I think I've narrowed down the problem to exclude SonarQube. I think it's open cover not finding the PDB file as it's looking in the GAC. Now do I edit the question or open a new one? 🤔mattumotu
probably open a new one since the tag sonaqube doesn't apply.jdweng

1 Answers

0
votes

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

Using \" in targetargs to represent quotes to 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="..."