I have SonarQube setup and the development team are complaining that the Cyclomatic Complexity scoring is not accurate as it seems to be missing the fact that there are indeed tests present. Does Code Coverage need to be implemented in order for Code Complexity to be accurate? It seems to make sense logically but wanted to check here. Thanks!
which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension)
SonarQube 8.0 Developer Edition
what are you trying to achieve
Cyclomatic Complexity scoring
I guess I’m just confused by this feature in SonarQube.
In the SonarQube documentation, Cyclomatic Complexity is defined as: Calculated based on the number of paths through the code.
However in SonarQube it’s described as: Cyclomatic Complexity measures the minimum number of test cases required for full test coverage.
Here’s an example:
The maroon lines on the side when hovered over say "Not covered by tests." There’s also no way to whitelist, comment, label, etc on any of this. Any clarification on this would be greatly appreciated.
As always, your quick response is greatly appreciated @ganncamp. But I am still perplexed. In order for SonarQube to understand test coverage doesn’t it need to understand the code coverage? I’m not seeing how or why those things are unrelated.
“Test coverage” and “code coverage” are two terms for the same thing. I guess you meant to ask about Cyclomatic Complexity versus coverage. For that the answer is “no”. SonarQube calculates your Cyclomatic Complexity and trusts the reports you feed into analysis regarding test coverage.
I haven’t fed anything into the code coverage. That goes to my original question on whether or not code coverage is required for an accurate cyclomatic complexity score.
Allow me to refactor my question . How should a dev team go about using SonarQube to address Cyclomatic Complexity? That’s the goal I wish to conquer.
Cyclomatic complexity is about the number of paths through your code. Every method in a class adds “a path”. Obviously, conditionals and loops add paths too. Given that a certain number of conditionals and loops are required to meet the business needs, then “addressing” the Cyclomatic Complexity of an application as a whole may not be productive. That said, when the complexity of a single method gets too high, then you can start splitting the methods up so that each one is manageable. However, it’s worth noting that splitting one complex method into two less-complex methods does add Cyclomatic Complexity to the class/project as a whole. You only reduce Cyclomatic Complexity by eliminating logic or combining methods, neither of which is necessarily helpful.
Which brings me to Cognitive Complexity.
But first, let me back up and ask what the ultimate goal is here. I’m going to guess (hope!) that it’s not about the scores themselves but about what they purport to represent. Cyclomatic Complexity gives you the minimum number of test cases you need. Cognitive Complexity is about estimating the difficulty to understand how a method works, and it is possible to reduce Cognitive Complexity without simply eliminating logic. The details are laid out in this white paper.
But in either case, whether you decide to target Cyclomatic Complexity or Cognitive Complexity, you should look not at the overall project values, but at methods where issues are raised because the complexity scores are higher than the allowed thresholds. So your first step is to make sure the relevant rules are enabled in your Quality Profiles (for each language).
After the very detailed answer of Ann, I hesitate to bring my own reply. However, a slightly different view may help.
As already said, cyclomatic complexity (CC) represents the number of different possible paths through the code. Incidentally, it also tells how many different test cases should be implemented if you wanted to achieve full test coverage.
Test coverage is obtained by analysing the actual paths followed during unit tests. This requires code execution.
This is where CC and code coverage are unrelated: CC is measured purely passively by scanning code, while test coverage requires code execution. CC provides a theoretical value, while test coverage provides an actual value.
Thank you @ganncamp and @pmjroth for taking the time to explain this. My main gripe with CC in SonarQube is that it doesn’t seem to have any clear actionable things to tackle it. Cognitive Complexity doesn’t have this issue, it’s clearly marked, defined and actionable whereas Cyclomatic Complexity has a bunch of highlights with the message Not covered by tests. I don’t know how this translates to paths through code.