Feb 16, 2016
As the concept of technical debt gains some visibility and momentum, we witness a tendency to put all forms of quality issues, and even plain old defects under the umbrella of ‘technical debt.’
In this memo, I argue that this is wrong for several reasons:
- Relabelling defects as technical debt does not help, it weakens the concept of technical debt, and give some unnecessary glamour to defects.
- If all defects are technical debt, then the concept of technical debt becomes pretty useless.
- We can establish some objective criteria to distinguish both, right from the definition of technical debt; and yes, detractors will always find some (sometimes convoluted) marginal cases.
- The decisions we have to make about technical debt and defects are similar but not identical, and do not use the same criteria
The root of the problem — definitions
To ground the debate, let me give definitions for some of the terms I’ll use:
- Software quality: the degree to which a system, component or process meets customer or users needs and expectation. (Source: IEEE std 610)
- Defect: a condition in a software product that does not meet a stated requirement, or users’ or customers’ expectation, in other words: an error, flaw, fault in a computer program or system that causes it to produce an incorrect or unexpected result, that may lead to a failure, or to behave in unintended ways. We often call most of them “bugs” (Sources: RUP and IEEE std 1044).
- Technical debt: A design or construction approach that’s expedient in the short term but that creates a technical context in which the same work will cost more to do later than it would cost to do now. (Source: Steve McConnell).
Defect and technical debt share some characteristics: they both deal with quality affecting the value of the product; they have a cost associated with it: the cost to fix, therefore some immediate or long term financial impact.
But there are some key difference. Technical debt deals with Internal quality, whereas defect deals more with External quality and Quality-in-use (as defined by ISO 9126 or ISO 25000). The impact of technical debt is not a loss of functionality (the system works), nor a loss of external quality, but a loss in maintainability and evolvability. The cost of future development is higher because of technical debt.
Defects are mistakes. They should not be there. Technical debt is the result of a compromise, a trade off, made explicitly, consciously, or not.
Condition Y in the system is technical debt if the cost of doing X now is higher because of Y.
Sorting them out
There are clear cut cases:
1) if an input out of bounds cause your program to crash, it is hard to argue that this is just a case of technical debt, making the system more costly to evolve. This fall squarely in the definition of a defect.
2) if your choice of database technology make the addition of new features to the system very costly, but everything works fine and is correct from the user perspective, the fact that you could have used another one is hard to label as a defect or a bug. It does a perfect job now and in the future.
There are some marginal “boundary” cases, where it is actually hard to distinguish, but in the majority of cases, it is better to separate defects from technical debt. So we can apply a simple criterion: are you paying some for of interest because of this condition as you evolve the system?
Let us use a 3rd example:
Your static analyzer detects a place of the code where there is a potential for SQL injection, leading to a security breach.
Is this a defect or a technical debt item?
You could argue that the system works perfectly like this (so it sounds like technical debt like the example number 2) above with your sub-optimal choice of database), but there is a high risk of a failure. Furthermore you do not have a higher cost of evolving the system because of this potential vulnerability.
So this is just a defect. Indeed it is a defect associated with a high risk. If there is an attack , there may be some huge liability down the road, but this is not interest. if your house burn because of some bad electrical wiring, you will incur some high cost, but it is not additional interest on some mortgage debt.
It is likely that a static analyser would detect both: high risks defects and technical debt items, and maybe in some organizations this is where the confusion defect-tech debt comes from.
There are cases where a technical debt item can lead eventually to a defect. Let us illustrate this with a 4th example: You have some code clones: a developer did some “cut-and-paste-and-modify” of a fragment of code, about 20 times throughout the system. But the software works fine. This is technical debt, because a) the system is working fine, but b) each evolution of the system that affect this particular snippet has to be done 20 times, instead of a single point of maintenance, so there is some form of constant interest.
Now the day a developer makes an update and carries the update only in 18 of the 20 occurrences, you may have introduced a defect or two.
Interestingly, because code clones are mostly found by static analysers, most of our community would say that code clones are a typical example of code-level technical debt.
We can construct convoluted example of a clear defect, that remains for a long time in the system and incurs some form of interest, and therefore could also be labelled at technical debt.
Let me throw one: the caching mechanism does not recover properly after a loss of communication with a remote server. So rather than fixing it, developers used a workaround, they created a simple local log file where they write things, and use this log file to restore the remote server in proper state after communication is reestablished. As more occurrences of this happen, the workaround gets used more often and becomes refined, as some cost. The original defect in the caching mechanism is still there. And fixing it will be more and more costly as the workaround takes root. We have here something that is both a defect (ignored) and technical debt (the workaround to the defect).
I’ve argued elsewhere (Kruchten 2010) that:
- new functionality
- technical debt
- and architectural or infrastructure improvements
should be handled together when it come to make decisions about what to do next: for the next development cycle, the next release. They all four bring value to the system, but all four have a cost.
The cost of a defect may be immediate and hurting the product, the value of a new feature may be obvious from a sales perspective. So defects and and new features tend to have priority over technical debt reduction and architectural improvements, which have a value much harder to articulate, and require some analysis of cost and opportunity over a longer time period.
But the notion of risk needs to come into play, too. A latent defect like the SQL code injection case above may not affect the system right now (it works), but there is a risk of severe losses in the future. Labeling this defect ‘technical debt’ does not quite do it credit. There is another term for such defects: vulnerabilities. They are latent defects with a high risk of significant future loss.
Similarly, I advocate that we do not confuse vulnerabilities with technical debt.
Then there is the extension of the notion of debt to a large amount of defects not fixed: defect debt due to accumulation (Akabarinasaji 2015), and and to debt-prone bugs (Xuan 2012).
While I understand that there is some loss of productivity (akin to interest of technical debt), I remain convinced that if there are defects, affecting some external quality or quality-in-use of the software product, and are not included in our definition of technical debt, we should not call them debt.
For “debt-prone bugs” having them in a bug tracking system does not make them bugs or defect. For example: Something identified with a tag “Fix me” or “to do, either has currently no impact on the external quality, and therefore it is technical debt, rt has some impact on the system, and is a defect. These are just identified technical debt item, stored and managed in the bug tracking system (which is a good thing).
It may be the case that high level of technical debt are correlated with high level of defects and vulnerabilities. But while we may have some intuition of this based on a few anecdotal evidence, this is not a clear case.
- IEEE (1990). IEEE Std 610 – IEEE Standard Glossary of Software Engineering Terminology.
- ISO/IEC (2004), ISO 9126:2004 Software engineering– Product Quality. Geneva: ISO, 2004.
- McConnell, S. (2007). Technical debt. Retrieved from http://blogs.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx
- Kruchten, Ph. (2010). What colours is your backlog? http://www.infoq.com/news/2010/05/what-color-backlog
- Kruchten, Ph. R. L. Nord, and I. Ozkaya (2012), “Technical debt: from metaphor to theory and practice,” IEEE Software 29(6), pp.18-21, November 2012. DOI: 10.1109/MS.2012.167
- Xuan, J., Hu, Y., & Jiang, H. (2012). Debt-Prone Bugs: Technical Debt in Software Maintenance. International Journal of Advancements in Computing Technology(IJACT), 4(19), 453-461.
- Akbarinasaji, S. (2015). Toward Measuring Defect Debt and Developing a Recommender system for their prioritization. Ryerson University. Montréal, Canada. (unpublished work)