Every developer wants clean code that is easy to read and maintain, with few issues and bugs. And there’s no magic solution to achieve this goal: each company has its own best practices and coding rules and tries to define a process for keeping its code clean.
Measuring the code quality of a project is not an easy task; many tools provide their own algorithms to evaluate it, based on many factors:
- Issues detected by the static analysis tools.
- Code coverage.
- Code duplication.
- Documentation.
- Lack of design.
There’s a metric that gives us an estimate that provides an approximate overall view of our codebase quality: the technical debt metric.
Wikipedia provides a brief explanation of technical debt:
Technical debt (also known as design debt or code debt) is “a concept in programming that reflects the extra development work that arises when code that is easy to implement in the short run is used instead of applying the best overall solution”.Technical debt can be compared to monetary debt. If technical debt is not repaid, it can accumulate ‘interest’, making it harder to implement changes later on. Unaddressed technical debt increases software entropy. Technical debt is not necessarily a bad thing, and sometimes (e.g., as a proof-of-concept) technical debt is required to move projects forward. On the other hand, some experts claim that the “technical debt” metaphor tends to minimize the impact, which results in insufficient prioritization of the necessary work to correct it.
In theory, addressing technical debt is a promising way to improve software quality, but in practice, it is not easy to apply. The main challenge is how to evaluate technical debt.
Whatever tool or method is used to evaluate it must be flexible and easy to customize. The company must be able to calibrate its algorithm depending on its context. For example, one team might tolerate a method with more than 50 lines of code, while another could choose 30 as the maximum.
An agile algorithm to the rescue
There are two ways to make technical-debt calculations flexible:
- Define a specific algorithm and make it possible to change its parameters depending on the development team’s context.
- Don’t define a specific algorithm, and give the user a way to customize the calculation formulas.
With CppDepend we chose to make the algorithm flexible; it can be adjusted for each rule depending on the project context.
For example, here’s a formula for the debt introduced by overly large types:

And here’s another formula for a Cppcheck issue:

This way, each team can configure their debt calculation based on the project context, which helps reduce estimation errors in the debt calculation.
The comparison with a baseline
Evaluating technical debt is difficult: every algorithm introduces estimation errors, and calibrating it can be time-consuming because the result depends on many factors.
However, if we compare the technical debt of two iterations of a code base, we can get a good sense of how its code quality is evolving.
The difference between the debt metrics of two versions minimizes the estimation errors and gives a more accurate debt metric.

Using Trends to Track Quality Evolution
Concepts like technical debt help quite a bit. But nothing hits home like a visual.

For instance, you might want to look at average cyclomatic complexity and lines of code per method. Generally speaking, you would expect these figures to remain relatively flat (and low) in a codebase. You could use a trend chart to confirm this and keep tabs.
Does the trend line stay pretty much flat, with a little uptick or downtick here and there? Or does it trend slowly but steadily upward? Observing a trend like this can help you catch an issue much earlier than you otherwise might. Whenever I see a codebase with heinous method complexity, I understand that nobody went in and made it that way in an afternoon. It took years of not noticing a general, gradual trend.
Conclusion
The technical debt metric is a powerful way to monitor codebase quality. However, users need an easy way to calibrate it and reduce estimation errors. And it is more useful to focus on how technical debt evolves than on the absolute debt value itself.
