Coverage, the why and the how
Code coverage is an important quality metric that can be imported into SonarQube.
An external tool first computes the coverage report, and then, during the analysis, SonarQube is provided with information from this report.
If there is no coverage report format not covered by Test Coverage Parameters for your specific language, we provide the generic test data format for the coverage and the test execution reports. This is a simple format for gathering tests and coverage information when analyzing with SonarQube, and we recommend using it.
Languages and Their Coverage Reports
Language analyzers also support mainstream tool formats for the coverage reports, especially popular languages:
-
Java: JaCoCo
-
C# and VB.NET: Visual Studio Code Coverage, dotCover, OpenCover
- [Coverage] Troubleshooting guide for .NET code coverage import
- [Coverage & Test Data] Generate Reports for C#, VB.net
- C#/VB.NET: SonarQube and SonarCloud support Branch/Condition Coverage data
- Since SonarQube 8.3, the code coverage for .NET projects now takes into account the branch/condition coverage in addition to the line coverage. The coverage of your projects may decrease to be closer to reality, and it can impact your Quality Gate.
-
PL/SQL: utPLSQL
-
Swift
- [Coverage & Test Data] Generate Reports for Swift
- sonar-scanning-examples/swift-coverage at master · SonarSource/sonar-scanning-examples · GitHub
- GitHub - mysugr/cococo: Code Coverage Converter from Xcode 11 to SonarQube (deprecated tool but alternative provided in README)
-
Apex, C/C++, Objective-C, Go, JS/TS, Python
-
and many other languages
See Test coverage overview for all the available analysis parameters for the various coverage and test execution reports of other languages.
1-to-1 comparison between SonarQube and coverage report is not relevant
We sometimes have users reporting that the code coverage is different between SonarQube and the tool used to gather it.
The reason for this is most often because people are not comparing the same metrics.
SonarQube gets the covered lines from the coverage report given to the analyzer. Then it calculates all its coverage metrics from there and the executable lines also called lines to cover.
What is often compared is the Line Coverage, most often displayed by the external tool used to gather the covered lines, and what we define as Code Coverage, which is computed from the numbers extracted from the coverage report passed to the analyzer.
How to Calculate Code Coverage
We promote the Code Coverage metric because it reflects the best portion of source code covered by unit tests. This is the metric you can see on a project’s home page.
As you can read in the Metric Definitions page, the Code Coverage is computed as follow:
Coverage = (CT + LC) / (B + EL)
where
- CT = conditions that have been evaluated to ‘true’ at least once
- LC = covered lines =
lines_to_cover
-uncovered_lines
- B = total number of conditions
- EL = total number of executable lines (
lines_to_cover
)
Whereas the Line Coverage is computed as follows:
Line coverage = LC / EL
where
- LC = covered lines (
lines_to_cover
-uncovered_lines
)- EL = total number of executable lines (
lines_to_cover
)
By simply looking at the definitions we can already see that the results will be different.
Another way to express the above is
Coverage = (Covered Conditions + Covered Lines) / (Conditions to Cover + Lines to Cover)
where
- Covered Conditions =
conditions_to_cover
-uncovered conditions
- Covered Lines =
lines_to_cover
-uncovered_lines
- Conditions to Cover = total number of conditions (
conditions_to_cover
)- Lines to Cover = total number of executable lines (
lines_to_cover
)
The calculation can be simplified by the metrics themselves:
Coverage = (
conditions_to_cover
-uncovered conditions
+lines_to_cover
-uncovered_lines
) / (conditions_to_cover
+lines_to_cover
)
It can also happen that the Line coverage computed by SonarQube differs slightly from the one calculated by the external tool. This is because the Lines to cover may not be the same according to SonarQube and the tool.
You can find the definition of what SonarQube considers as a line of code on the metric-definitions page.
The main idea of this article is to highlight the fact that comparing the coverage coming from SonarQube and the coverage coming from other tools is often misleading, SonarQube should be the reference point.
FAQ
Q: After migrating from 5.6 to 6.7 my coverage shows 0%, why is that?
A: Since SonarQube 6.2 and the simplification of code coverage support, if no coverage information is found the coverage is then set to zero by default.
Q: Why is my coverage on the new code blank?
A: Either the coverage report is not found by the analyzer or there are no new lines of code. For git users, using shallow clones can also lead to this behavior, simply use regular clones.
Q: My coverage is loaded but my tests do not show up (or vice versa).
A: Yes, coverage and test results are 2 different metrics, make sure you are loading both.
Q: I provided all the information to gather coverage but it is not loaded.
A: First, make sure that the coverage report exists before the analysis is run, check the analysis logs to get more information, and make sure that the coverage report is not empty and contains coverage information that corresponds to the sources you are analyzing (files, paths, etc.).
Q: I see the following error in the coverage sensor java.lang.IllegalStateException: LineXX is out of range in the file XYZ
of my Sonar Scanner logs.
A: The message indicates that the sensor is asked to highlight a line that no longer exists in the code. The coverage report has to be recomputed to align with the existing code.
SonarSource Support team