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?