Plastering over the cracks of technical debt in software development

This Computer Weekly Developer Network blog is a guest post written by Michael Vessey, a senior consultant with software quality provider SQS.

If you do just enough to keep your car running — i.e. you just check the oil and tyre pressures but never take it in for a proper service — eventually, something bad will happen and your car will break down or become very expensive to run.

Similarly, with Agile methodologies like SCRUM, if you only ever do ‘just enough’ to build software that is ready for market, you are probably building up a technical debt that will need to be paid.

What is technical debt?

Technical debt is not a new idea in computing circles; it does however seem to have come into fashion lately. To understand technical debt better, consider how your house may have been affected by the high winds across most of the United Kingdom in January. Many houses may have suffered structural damage such as cracked brickwork and fallen chimneys due to structural movement. Let’s consider these cracks as technical debt; the building still performs its intended purpose, however we know we will have to fix them at some point

The right thing to do is to have the damage inspected and the structure of the building repaired before any damage spreads and the cost of repair increases. Instead, if we often chose to cover over the ugly cracks and render the outside of the house so that we lose all visibility of how the cracks are developing underneath the rendering.

In 1992 Ward Cunningham summarised this issue for software engineers:

“Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organisations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.”

With more and more companies switching development from traditional waterfall methods to Agile and SCRUM we are seeing development team leads focusing more intensely on technical debt.

The main benefit of Agile to these companies is that you can release small portions of the product at early stages of the lifecycle by doing “just enough” to get the component ready for market.

But — by doing “just enough”, the risk of technical debt is increased.

Static analysis can help development leads monitor some aspects of technical debt. Microsoft has recognised this and incorporates static analysis in its development tools. It is incredibly easy to run code analysis within Visual Studio 2010, however understanding the results can be more complex.

The results of even a basic code analysis can be very noisy, with lots of warnings making it difficult to spot the most important issues. Even simple sections of code can generate results from a “basic correctness” analysis.

Take the following snippet of designer generated code:

private void InitializeComponent()




// Form1


this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = new System.Drawing.Size(284, 262);

this.Name = “Form1”;

this.Text = “My First Form”;



The basic correctness rule set throws up the following warning:

Warning – CA1303 : Microsoft.Globalization : Method ‘Form1.InitializeComponent()’ passes a literal string as parameter ‘value’ of a call to ‘Control.Text.set(string)’. Retrieve the following string(s) from a resource table instead

While this is valuable information, it’s all too easy for anyone with the correct knowledge to suppress the warning, hiding it from your automated static analysis. The line of code below will do this.

[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Globalization”, “CA1303:Do not pass literals as localized parameters”)]

Some developers might be tempted to ‘paper over the crack’ by suppressing for valid reasons, for example: to focus on other messages, there may be SQL injection warning but the developer seeing the warning is not a SQL developer or there may be an internationalisation issue and the developer is unaware that the company will later be launching a multi-language.

Suppressing warnings does, however introduce two major risks. The first of these is that a developer can choose to hide issues from a code inspection, the second is that the scope of the suppression does not extend to just a single line of code.

If a new instance of the same warning is introduced into the same section of code then you have two instances of technical debt and yet no new warnings; new cracks can appear and you would not be aware of them because they are hidden beneath the paper.

When managing technical debt issues in code, just as with cracks beneath the rendering of a house, we need to carefully consider the implications before suppressing errors. If we fail to take the proper steps and care, we won’t know the extent of the problem — until something as disastrous as a wall falling down occurs.

These tools are provided for a reason. Make sure you don’t plaster and paper over the cracks and hide your technical debt.