We will soon release a new version of our .NET analyzers that finally include Unit test details.
This is a change that has been requested for a long time, so we are very happy to finally be able to make it available. This feature supports MSTest, NUnit and XUnit.
Please note this comes with some warnings :
We now parse the full unit test report files, and map individual tests. However, by default we do not report on generated code. If you tests are generated, they will not be taken into account. This means the number of reported tests may go down. If you have a quality gate condition on this metric you might encounter a failed quality gate because of that.
SonarQube will now calculate the test density metric for .NET tests (which it could not do before). If you had a quality gate condition on this metric, you might encounter a failed Quality Gate (but it is arguably normal, as the value will now be calculated properly for .NET code).
Please review your quality gate conditions and update them appropriately.
This is good news.
Is this feature/functionality currently available?
I’m working with C# and our SonarQube Server (Community Edition Version v9.9.8 (build 100196)) which shows the number of unit tests but when I click on the link there’s no results shown.
It would be good to report which Unit Tests pass and which ones fail.
We look forward to having this feature.
This was released in January, In SonarQube Cloud, SonarQube Server 2025.1 LTA, and SonarQube Community Build 25.1.
Since you are on Community Edition, I would advise to upgrade to a recent Community Build release to benefit from this (and many more new features and improvements since CE 9.9)
Do you have any screens shots of where SonarQube reports the unit tests?
We upgraded our SonarQube to version ‘Developer Edition v2025.2 (105476)’ and re-ran the analysis multiple times and so far there are no unit tests appearing on SonarQube.
We do see the Code Coverage but no unit tests.
The TestResults folder and file do contain the unit tests.
We’re using ‘dotnet sonarscanner…’ processes using nunit.
Here’s the command: dotnet-coverage collect dotnet test -f xml -o ‘coverage.xml’ --results-directory ./TestResults --logger:“nunit”
This is all I see.
There are no test metrics or results shown.
The command I use to generate the TestResults is: dotnet-coverage collect dotnet test -f xml -o ‘coverage.xml’ --results-directory ./TestResults --logger:“nunit”
Test results are captured in the specified folder/file.
I’ve tried specifying only the folder as well as specifying both the folder and file as described in the docs under the sonar.cs.nunit.reportsPaths section.
I’ve tried specifying the parameters in the command line, in the sonar-scanner.properties file and in the SonarQube.Analysis.xml files. No metrics appear on the page.
Under the ‘Measures/Coverage…’ sections of the report it shows 1 Test case even though there are nearly 400.
@boblinn
Since you seem to be using nunit, you also need to pass in the property /d:sonar.cs.nunit.reportsPaths=./TestResults/*.xml (based on what I see in your dotnet test command) in the begin step of the scanner invocation.
Maybe you could give me the (redacted) content of your pipeline?
At first glance this looks right. Could you please add /d:sonar.verbose=true in the begin step, run the pipeline and share the (redacted if need be) logs for the begin step and the end step?
I’m aware of the entries in the ‘sonarDebugEnd.txt’ file that say “…test cannot be mapped to the test source file. The test will not be included.” I’m unsure if this sheds light on the issue or how to address it.
If it’s helpful here’s an image of the folder structure.
One quick thing that I noticed in your begin step, is that you are passing the coverage like so /d:sonar.cs.vscoverage.reportsPaths=./coverage.xml.
However later I see you use the dotnet coverage tool which actually requires that you pass in the begin step the coverage like /d:sonar.cs.vscoveragexml.reportsPaths=./coverage.xml (the only difference is that there’s one xml suffix on the third part of the parameter name, however without this it should not work see docs).
Could you please do a quick test if that solves the problem?
Meanwhile I’ll check also your logs - but it might already be solvable by this small change.
These settings do not match the begin step you posted above.
It looks like both sonar.cs.vscoverage.reportsPaths and sonar.cs.vscoveragexml.reportsPaths are set at the same time.
Same for the test report paths looks likesonar.cs.vstest.reportsPaths=TestResult.trx is set, when you actually need sonar.cs.nunit.reportsPaths.
are these logs maybe not the latest ones?
Also, is it possible that you are inheriting SonarQube server project settings or global settings? Which should not happen, but worth checking (you can check from the SQ Server UI - see docs with more info).
Thank you for those insights.
I updated the sonar.scanner.properties and command line parameters to match as reported, re-ran the begin, build, test and end tasks and the results are the same: the test case metrics are still not shown and under the ‘Measures/Coverage…’ sections of the Sonar report it shows 1 test case even though there are over 380.
I’ve attached the latest ‘begin’ and ‘end’ logs.
Here’s the commands I used:
the property <SonarQubeTestProject>True</SonarQubeTestProject> in the test project is not enough to generate sonar.exclusions=**/Sanmar.Azure.Database.DYNINT*.*, **/LogicApps.Test/**.
There should be exclusions also somewhere else set - in theory in the server directly in the project settings or the server settings. Could you please check?
What I’m suspicious about is that there might be multiple other analysis settings set that are inducing this behavior.
Another peculiar thing I noticed is that although you set /d:sonar.scanner.scanAll=false
in the sonar.scanner.properties it’s true, which should not happen. Where are these properties copied from? The CLI parameters override any other analysis parameter set anywhere - which happens as I see in the end step.
The server does not have any exclusions neither in the project nor in the server settings.
Setting the scanAll property to the same value, true or false, did not resolve the issue of not being able to find the sources.
Your help, as always, is appreciated.
The server does not have any exclusions neither in the project nor in the server settings.
thanks a lot for checking this out.
Would it be possible for you to create a reproducer project?
From my side I created a toy project similar to what you described, using the same commands for analysis and I don’t have an issue with the tests - so maybe if you could create a repro we can go a bit deeper in the problem.