Technical Debt

In this article I want to talk about a term that I think is just brilliant: technical debt! The term technical debt makes an analogy: it considers the use of quick, but poor, technical solutions to store up a form of debt. As with more conventional forms of debt, the immediate problem is solved, but trouble can be stored up for the future. The reason I like the term so much is because, by its use of analogy, it makes it much easier to communicate a concept that is, otherwise, rather tricky to explain.

All too frequently in software development, technical/design problems are solved sub-optimally in the interests of speed. Actually that is putting it too nicely. Such problems are often solved using quick and dirty hacks. This is usually done in the belief that it will get a solution in place quickly. Often the belief is actually correct, and this approach does indeed get a solution in place quickly. However, there is a price to be paid. The price manifests itself in the form of code being difficult to work with in the future, and therefore the risk to future deliveries is much increased.

Here lies the importance of the debt analogy: there is nothing wrong in principle with technical debt, but like any other kind of debt it must be managed, and it must be managed effectively. If debt is to be entered into then it is imperative that the debtor is in control of the debt - the debt must not be allowed to control the debtor!

The need to make a delivery in time, typically so as not to miss a market window, may make it necessary to accept a "quick hack" solution. However, such a solution can not be allowed to remain in place; if it is, then soon it will become difficult - and even practically impossible - to meet deadlines. For this reason, some planning is necessary; time must be made factored into the development schedule for solutions carrying such a technical debt to be reworked with more enduring solutions. Failure to do this leads to developers being unable to work with the code base, and ultimately the code base needing to be rewritten from scratch.

Typically, such rework is not carried out because (non-technical) management decide to spend the development time on new features - after all, the code works so why spend time rewriting any of it? Software developers then become frustrated because they perceive this as incompetence on the part of their management. This attitude is wrong on the part of developers! Technical debt is in the technical domain, and therefore it is not something non-technical management should be expected to understand - at least, not without it being explained to them in such a way that they, as non-technical people, can understand it. The responsibility here lies with the senior software developers, who have a responsibility do learn to communicate this issue to their management.

Object Characteristics

In this article I want to look at the essential characteristics that objects have, namely those of state, behaviour and identity. This article follows on from my my What is an Object? article of a while ago, when I offered the following definition of what an object is:

An object is a physical manifestation of a type, that executes the responsibilities of that type

That definition is just the first step and isn’t very useful by itself. This article continues a miniseries that began with my What is an Object? article. In this miniseries, I want to dig deeper, so that the above definition makes sense and thus becomes useful. I will write future articles about each of state, behaviour and identity individually, and in more detail. For now though, in order to get started, I will give just a short summary on which to build later:

State is the informational content of an object. An object’s client (usage) code perceives the object’s state as the values of its publicly exposed properties.

Identity refers to the properties of an object that make it unique; that is, the properties that distinguish it from all other objects. An object’s identity is expressed through a subset of its state.

Behaviour is the activity of an object, that is to say it is the way the object responds in interactions with its client code. Such interactions may be in the form of how the object responds to requests other objects make of it, and the notifications of changes to its state that it sends out to other objects.

That builds a little bit more on the above definition of an object, and, as I said above, I will build on it with more articles in the future in order to give a more complete picture. Unfortunately, like many aspects of software development, object oriented design and programming is not a simple topic.

Why Unit Test?

I’ve written a few articles about unit testing on this blog, but so far they’ve been about how to go about doing so and what supporting libraries/frameworks are available. Now I want to look at why unit testing is a good idea. In particular, this article will focus on the business perspective.

Many software developers embrace the unit testing of code with enthusiasm. Unfortunately though, there are many who see it as something that will just hinder them in getting their work done - after all, they will have to write significantly more code, won’t they? It is even more unfortunate that many managers see things the same way. So, why unit test, given that developers will indeed have to write significantly more code?

The fact is that, from a business perspective, unit testing earns its keep on the cost/benefit scale. The 1988 paper "Understanding and Controlling Software Costs" by Barry Boehm and Philip Papaccio states:

…the cost of fixing or reworking software is much smaller (by factors of 50 to 200) in the earlier phases of the software life cycle than in the later phases

The authors also provide references in support of this statement. Now look at the numbers: assuming the least worst case, catching an error early make it cheaper to fix by a factor of fifty. Compare this with the amount of effort needed to write a unit test - and remember this is the least worst case. It seems that unit testing is definitely earning its keep! Unfortunately, my research suggests there is a lack of recent data published on the web in this field. However, although the paper I have cited is quite old, it is hard to imagine that things have improved in the light of today’s technology. In fact, things are likely to be worse because computer systems are much more complex, as they attempt to solve much more complex problems.

Unfortunately, unit testing will not guarantee completely bug free code. Somewhere, something will get missed. It is likely, for example, that unit test coverage will miss some aspects - corner cases in particular - of the code. Despite this, the evidence suggests that it does contribute significantly.

Unit Test Frameworks

At the end of my previous article Pros and Cons of Using the C assert Macro for Unit Testing in C/C++ I promised to follow up with an article summarising the popular unit testing libraries/frameworks. In this article I will give that summary:

  • For the .NET languages there is NUnit. Although the source code is written in C# it can be used to unit test any .NET language. Sample code is supplied for C#, .NET C++ extensions (both managed and CLR) and J#
  • JUnit was developed for the unit testing of Java code and was the inspiration for many unit test frameworks that were to follow. JUnit is Java specific
  • For Python there is the Python Unit Testing Framework or PyUnit for short. PyUnit is part of the Python standard library as of Python version 2.1
  • For ISO standard C++ there are several unit test frameworks/libraries around. Probably the most popular are CPPUnit, The Boost Test Library and Aeryn. CPPUnit was an attempt to “port” JUnit to C++, whereas The Boost Test Library and Aeryn are in keeping with idiomatic modern C++

That concludes my roundup. Please comment if you feel I’ve missed a library that should have been included. Note that all the above libraries are open source (and in the case of Python, Python itself is open source).

Update

(Wed 11th Feb, 2009)

Thanks to Alan (see comments, below) for drawing my attention to SUnit - the unit testing tool for Smalltalk.

Pros and Cons of Using the C assert Macro for Unit Testing in C/C++

This is a short follow-up to my recent article A Very Simple Introduction to Unit Testing. In that article I described the development of a very simple unit test for a very simple C++ class. To do this I used the C/C++ assert() macro, saying the following about it:

"…although assert wasn’t originally intended for unit testing, it makes a simple but effective tool for doing so without the need to look outside the language’s standard library."

I’d like to thank John Crickett for - in an offline conversation - pointing out that there are some things that I should have made clearer. Although - as I said - assert is very effective for unit testing without the need to look outside the C/C++ standard library, it does have its shortcomings. Let me summarise the points for and against.

Points for:

  1. There is no need to look outside the language’s standard library, so programmers can start unit testing without the overhead of having to set anything up
  2. If an assert fails, the program stops running. Therefore, the programmer must fix the problem before continuing. Note this is also a point against (below), but the reasoning is different

Points against:

  1. It is only available to programmers working in C and/or C++ (obviously)
  2. You can only test the debug version of your code
  3. If an assert fails, the program stops running. This makes assert unsuitable for unit tests that are run in any kind of automated mode - for example, some automated build systems run the unit tests immediately after the applicable unit of code has been built

Therefore, based on the above, I suggest the use of assert is suitable for programmers unit testing in the following situations:

  • Learning to write unit tests (see 1, under points for), either as part of a formal training course or otherwise
  • Unit testing in a development environment which has no unit testing culture (again, see 1, under points for). Programmers can develop their own unit tests without the need for support from their development environment. For example, they may not be allowed to - or even able to - install libraries other than those officially used by the development group

Thinking about it now, my original assertion (pun intended) was over zealous, in that I didn’t qualify it with the context I was thinking in at the time. This article should serve to set the record straight.

The question remains: what should be used in those situations where assert is not sufficient? I was going to summarise some of the alternatives available in C++, but it now occurs to me that such a summary would really be out of place in this article. This is because - going back to its predecessor A Very Simple Introduction to Unit Testing - I only used C++ in the first place so I could use assert, and I wanted to use assert in the first place for simplicity. That is to say, the discussion here is about the suitability of assert. Therefore, I’ll take the approach of coming back to this topic soon, and write a summary of the available unit testing libraries/frameworks for several popular programming languages. When I’ve done so, I’ll post an update here with a link to it.

?>iMaleSpectrumPass Mobile Milf Videos diflucan online All Girl Mobile Flomax online iMuscleMen Asian Parade Milf Seeker cartoonreality His First Huge Cock Rookie Guys justcartoondicks kamagra portugal Pure Anime hot muscle dudes Tranny Seducers Gay College Sex Parties Ebony Shemale Mobile Shes My Ex PV Trannies Housewife Porn Videos PV Strips 3DS Max 8 OEM3Q 3GP Video Converterdownload acdsee manager 2009 oemred eye remover pro 1.2cheapest windows vistacheapest windows vista ultimatecheap AutoCAD 2009Vision Backup Enterprisecheap Macromedia ColdFusionnero photoshow 5 downloadadobe photoshop cs oemcoldfusion mx 7 downloadkamagra sildenafil citratekamagra generic viagraorder caverta onlinecaverta 100buy cavertatadaliscasodex 50 mg tablet