Evaluate your technical debt with Sonar
The technical debt is a well-known concept that was invented by Ward Cunningham in 1992 and that he’s recently talked about in this video. Since then, it has been discussed and developed numerous times in blogs and articles. I am not going to describe it in great details here, I rather recommend that you read what it is considered as the reference article on the subject, by Martin Fowler. Here is an extract of this article that gives a synthetic view of the metaphor :
In this metaphor, doing things the quick and dirty way sets us up with a technical debt, which is similar to a financial debt. Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design. Although it costs to pay down the principal, we gain by reduced interest payments in the future.
This metaphor seems to be accepted by many developers already and every day someone tweets about the urgent need to pay back his technical debt. But beyond the concept, when time comes to evaluate the amount to be repaid, there is simply no literature on how to calculate the debt or at least approach it. It’s like borrowing money to buy a house but 2 years later having no way to know what is the remaining debt and how much interest are being paid each month :-).
As stated by Martin Fowler, developers are good and sometimes make deliberate choice to borrow in order to buy time. That’s true when starting a new development as you know exactly the amount of technical debt… that is to say 0. But when extending or maintaining a legacy application, that’s another story as nobody knows exactly how bad it is. Further more you might even not be aware that you are borrowing money, when a developer simply does not follow best practices. That is why, evaluating even roughly the technical debt is very useful.
Before introducing this Sonar plugin, here are few funny and relevant quotes on the concept :
- Maintaining an application without any unit tests is like borrowing money each time you add or change a line of code
- Skipping design phase is like borrowing money to get a very “quick” and “predictable” return of investment
- Refactoring is like paying down the principal
- Development productivity decreases when interests grow up
- Managers don’t care about code quality, just ask them to pay the debt in order get their attention
- Bankruptcy is logical extension of technical debt uncontrolled… we call it a system rewrite
When discussing source code quality, I like to say that there are seven deadly sins, each one representing a major axis of quality analysis : bad distribution of the complexity, duplications, lack of comments, coding rules violations, potential bugs, no unit tests or useless ones and bad design. As you know already, Sonar actually covers 6 of them but the seventh one (bad design) should probably start shaking :-) as it is a matter of time it gets covered as well.
From this observation, we decided to build new metrics that reflect how much effort is required in order to get a perfect score on the various axes. In other words, what is the cost of reimbursing each of the debts in the project. By combining the results, we obtain a global indicator that we report in $$ to keep it fun ! Along with this indicator comes the repartition of each axis, i.e. how much did each axis participated to the technical debt.
The current version of the plugin is 0.2 and uses the following formula to calculate the debt :
|Debt(in man days) =||cost_to_fix_duplications + cost_to_fix_violations +|
|cost_to_comment_public_API + cost_to_fix_uncovered_complexity +|
|Duplications||=||cost_to_fix_one_block * duplicated_blocks|
|Violations||=||cost_to fix_one_violation * mandatory_violations|
|Comments||=||cost_to_comment_one_API * public_undocumented_api|
|Coverage||=||cost_to_cover_one_of_complexity * uncovered_complexity_by_tests (80% of coverage is the objective)|
|Complexity||=||cost_to_split_a_method * (function_complexity_distribution >= 8) + cost_to_split_a_class * (class_complexity_distribution >= 60)|
Beyond the calculation that is a broad approximation of the reality, the technical debt measure is precious as :
- it is a consolidated metric on projects, modules…
- it can be followed in the TimeMachine (historical data, trend)
- it enables to compare projects
- it is possible to drill down on it even to… the class
As a first version, you probably noticed that we took some options, however most of the values for costs can be adjusted in the plugin configuration.
The plugin has been installed on Nemo, the public instance of Sonar, that now calculates the debt of more than 80 Open Source projects. The plugin relies only on the available Sonar extension points and is good example of advanced metrics that can be computed with Sonar.
I am going to stop here on the technical debt for today, but would like to simply mention what we plan to add to it next : interests, debt ratio and project risk profile. I let you now go back to Sonar to install this new plugin as I am sure you want to know what is the technical debt of your project…