We have been using SonarQube for inspecting code quality of our applications for a long time now. We have integrated SonarQube with our CI/CD Pipeline and configured Quality Gates — hence with every code check in we perform a static code analysis of the changes. This provides developers an early feedback of their code changes. If the code changes does not meet quality standards, the code check-in is rejected.
In this blog, we will look at an issue with using Cyclomatic Complexity metric which we bumped into earlier this week and the action plan for resolution.
In our SonarQube Quality Gate, we have added the Cyclomatic Complexity metric to throw a ‘warning’ if it is greater than 20 and ‘error’ if it is greater than 1000.
The problem is all my projects started throwing a Warning because of Cyclomatic Complexity.
SonarQube looks at various keywords like – if, while, for, switch, case, throw, return etc and increments the counter for each of the occurrence – and comes up with a final value for Cyclomatic Complexity. This metric is nice to have since it identifies the classes which have too much of business logic going on – and probably are good candidate to be broken down and even rigorously unit tested.
My project is throwing a warning since Cyclomatic Complexity>20. When I look at the details, I have few classes with CC value of 5,4,3. However there is no scope of refactoring here! Another problem is that there is no indication which methods in the classes have higher complexity.
I think the Cyclomatic Complexity metric should be working on a Method level and not on a Project level to be more effective. This would allow developers to focus more on methods which have relatively high Cyclomatic Complexity value – and look at opportunities to decouple logic & break down the methods further. Generally a class/method with high CC value indicates violation to the ‘Single Responsibility Principle’.
I reached out to the SonarQube Team for some general guidance around recommended value of Cyclomatic Complexity for an application.
I also wanted to check if there a way in which this metric can be looked up at a Method level? For example — If I set the CC value as 20, it displays methods/classes which have CC greater than 20.
For handling the Complexity metric more effectively, we made the below changes to our existing SonarQube Quality Gate and Quality Profile –
Quality Gate Changes –
Remove the Cyclomatic Complexity metric entirely which is currently throwing a warning for all our projects when the value is greater than 20.
Quality Profile Changes –
Add 5 new rules to our Quality Profile which will scan the projects and raise code smells when a specific class/method breaches the defined Cognitive Complexity threshold.
Please see the last screenshot in this article for the tags/filters you want to use to get these rules.
Why do we want to make this change?
1. We want to handle the complexity issues at a method level and not at the overall application level. With this change, SonarQube will raise a code smell when an individual method complexity is greater than 15. Teams will be able to see the exact methods for which the code smell for complexity is being thrown. Resolution will be to break down & simplify methods to follow ‘Single Responsibility Principle’.
2. Cyclomatic Complexity metric seems to have multiple issues. By using Cognitive Complexity metric at a method level instead, we should be able to address the concerns —
Problem Scenario 1
Every method in your application gets a Cyclomatic Complexity count of 1, and hence if you have 20 simple methods in your application – you have already reached the threshold of 20!
Also for every case in your switch statement, the Cyclomatic Complexity gets incremented by 1. This is not something we would like to throw a warning on.
Cognitive Complexity handles these scenarios perfectly.
Problem Scenario 2
For the getters and setters in your Domain classes, you don’t want to increase your complexity count.
To add the new rules, please use the ‘complex’ filter with the ‘brain-overload’ tag —
You can read more about Cognitive Complexity here —
Measuring Cyclomatic Complexity Metrics —
Calling a method does not increase CC..