.NET SonarScanner Coverage Not Reported in SonarQube

Must-share information (formatted with Markdown):

  • Which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension):
    SonarQube: Community Edition - Version 9.9.3 (build 79811)
    Scanner: SonarScanner for MSBuild 5.15

  • How is SonarQube deployed: zip, Docker, Helm:
    SonarQube is deployed via a zip

  • What are you trying to achieve:
    I want the code coverage report to show up in the project’s page in the SonarQube UI.

  • What have you tried so far to achieve this:

  1. I’ve tried the steps listed in the troubleshooting guides scattered around the community pages
  2. I have tried the Visual Studio Code Coverage and dotnet-coverage Code Coverage options from this page: https://docs.sonarsource.com/sonarqube/9.8/analyzing-source-code/test-coverage/dotnet-test-coverage/

When I use the dotnet-coverage option the scanner logs say that the coverage file has been picked up and is being cached for later use but when I navigate to the projects page the coverage is still 0%. The “Last analysis…” time is accurate, so the scan is being published to SonarQube.

The scan is run using the following commands:

dotnet-sonarscanner begin \
    -k:<project_name> \
    -d:sonar.host.url=<sonar_host_url> \
    -d:sonar.token=<sonar_token> \
    -d:sonar.cs.vscoverage.reportsPaths=./coverage.xml

dotnet build --no-incremental
dotnet-coverage collect 'dotnet test' -f xml  -o 'coverage.xml'

dotnet-sonarscanner end -d:sonar.token=<sonar_token>

Do not share screenshots of logs – share the text itself (bonus points for being well-formatted)!

12:56:08  INFO: Found 2 MSBuild C# projects: 1 MAIN project. 1 TEST project.
12:56:08  INFO: Sensor C# [csharp] (done) | time=826ms
12:56:08  INFO: Sensor Analysis Warnings import [csharp]
12:56:08  INFO: Sensor Analysis Warnings import [csharp] (done) | time=2ms
12:56:08  INFO: Sensor C# File Caching Sensor [csharp]
12:56:08  INFO: Sensor C# File Caching Sensor [csharp] (done) | time=37ms
12:56:08  INFO: Sensor C# Tests Coverage Report Import [csharp]
12:56:08  INFO: Parsing the Visual Studio coverage XML report /src/././coverage.xml
12:56:08  INFO: Adding this code coverage report to the cache for later reuse: /src/././coverage.xml
12:56:08  INFO: Sensor C# Tests Coverage Report Import [csharp] (done) | time=147ms
12:56:08  INFO: Sensor Zero Coverage Sensor
12:56:08  INFO: Sensor Zero Coverage Sensor (done) | time=41ms
12:56:08  INFO: SCM Publisher No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.
12:56:08  INFO: CPD Executor 42 files had no CPD blocks
12:56:08  INFO: CPD Executor Calculating CPD for 84 files
12:56:08  INFO: CPD Executor CPD calculation finished (done) | time=105ms
12:56:08  INFO: Analysis report generated in 182ms, dir size=1.0 MB
12:56:11  INFO: Analysis report compressed in 2821ms, zip size=420.8 kB
12:56:11  INFO: Analysis report uploaded in 252ms
12:56:11  INFO: ANALYSIS SUCCESSFUL, you can find the results at: https://<ip>/sonarqube/dashboard?id=<project_name>

I should also mention that the coverage.xml file is correctly populated and reports non-zero coverage.

Also, the coverage is reported as 0% for both new and overall code.

Hi,

I notice a couple of things here. First there’s the difference between the paths:

Now. ./coverage.xml translates to coverage.xml but /src/././coverage.xml translates to [box root]/src/coverage.xml

And TBH, I’m not quite sure where that extra pathing comes from. But could you try to simplify this by dropping the ./ in front of coverage.xml in your begin step?

Also - and I’m honestly asking - will the single quotes you used be interpreted the same as the double quotes in the docs?

And finally, if simplifying the path doesn’t work (and I’m not actually optimistic there) could you provide a full debug analysis log?

The analysis / scanner log is what’s output from the analysis command. Hopefully, the log you provide - redacted as necessary - will include that command as well.

This guide will help you find them.

 
Thx,
Ann

1 Like

Hi Ann,

Thanks for looking into this. This community is super active, which is great! Turns out my coverage reports were being picked up by SonarQube properly, but the paths described in the coverage report were different than the paths that SonarQube was looking for, so SonarQube naturally reported zero coverage.

I know you can view Task info for a scan in the projects top-level page. I wonder if an enhancement request to view more details on how coverage reports are processed would be helpful.

Thanks,
Ethan

1 Like

Hi Ethan,

That’s usually called out pretty clearly in the analysis logs. Are you saying it wasn’t this time?

 
Thx,
Ann

No, the analysis logs indicated that it found the coverage report but didn’t mention anything else.

Hi,

Thanks for the followup. I’m going to flag this for the product team.

 
Ann

Hello @ethantanen

Sorry for the delay.

I would expect in your case that the debug logs would have contained, when running in verbose mode, something like:

DEBUG: Did not find deterministic source path in ‘C:\_\some\path\file.cs’. Will skip this coverage entry. Verify sonar.sources in .sonarqube\out\sonar-project.properties."

Did you run your analysis in verbose mode, to diagnose the issue? Or is your expectation, in such cases, to output a warning message in the log?

I’ve opened Should align logging for not indexed files · Issue #8503 · SonarSource/sonar-dotnet · GitHub to improve the message in the logging.

For reference, how to share the Scanner for .NET verbose logs

  • Add /d:"sonar.verbose=true" to the…
    • SonarScanner.MSBuild.exe or dotnet sonarscanner begin command to get more detailed logs
      • For example: SonarScanner.MSBuild.exe begin /k:"MyProject" /d:"sonar.verbose=true"
    • “SonarQubePrepare” or “SonarCloudPrepare” task’s extraProperties argument if you are using Azure DevOps
      • For example:
        - task: SonarCloudPrepare@1
            inputs:
              SonarCloud: 'sonarcloud'
              organization: 'foo'
              scannerMode: 'MSBuild'
              projectKey: 'foo_sonar-scanning-someconsoleapp'
              projectName: 'sonar-scanning-someconsoleapp'
              extraProperties: |
                sonar.verbose=true
        
  • The important logs are in the END step (i.e. SonarQubeAnalyze / SonarCloudAnalyze / “Run Code Analysis”)

Hi @ethantanen - did you have time to read my question? I would help me better understand what your expectation is.