Ulf has written about technical debt before, saying that essentially, poor planning and bad implementation of system changes will increase technical debt.
Basically, technical debt is work that will have to be done before a job can be considered complete and has to be managed after the deadline, for example updating documentation after deployment.
Technical debt tends to grow
If you work on code without constantly making efforts to reduce technical debt, it will grow.
Technical debt grows even if you make no changes to your code. In fact, don’t touch a single line of code, not a single character: and just wait. Debt will still grow because frameworks, libraries and other third-party dependencies will become outdated. The very programming language you use will age and grow out of date.
Depending on your application and your design choices, this ageing of the system can be slow or fast; noticeable or not so much.
Modern applications, especially web applications, are often dependent on many third-party libraries, frameworks and services. Some applications barely have any code at all: they are just “a bit of glue” between existing services. This is a great example of just that.
In addition to dependencies within your code, the application is also dependent on things outside of it: tools and systems for building, deploying, automated tests etc.
These dependencies are central to the application. Therefore managing dependencies and keeping them up-to-date becomes an important part of maintaining your application.
One of the worst scenarios you could end up with is a dependency that turns on you and makes you, your team, and your entire application dance to its tune. It could be a library that is essential to some feature in your application. It starts out great: using the library saves you a lot of work and lets you deliver awesome features quickly. But then you discover a bug in the library. The developers of the library cannot or will not fix that bug for some reason. You develop your own fixes and workarounds. When you try to upgrade the library, your workarounds break, so you spend a lot of time re-fixing that bug. If, however, you don’t upgrade, you also cannot upgrade other things because of interdependencies. You’re stuck in quicksand.
Despite our best efforts, we’ve ended up in this situation twice at ReQtest, but luckily we are now wrestling our way out of both of these messes.
Case 1 – Technical Dependency Goes Wrong
Case 1 was a UI control library from a major vendor. We found a few bugs in one of the controls. The bug was low priority for the vendor and stayed in their backlog. But for us these were “must fix” bugs. So we developed our own workarounds. At some point in the future the vendor released the next version of the library, fixing the bug.
Now, our fix conflicted with theirs, so we got new bugs! It turned into an endless cycle of fixing and re-fixing and re-re-fixing the same annoying issues.
This took up enough development time that we decided to freeze this library and not upgrade it. We knew that this would cause more problems in the future (for example when the controls need adjustments to work with newer web browsers). So after a while we decided that our best course of action was to ditch this library, even though it was quite central to some parts of ReQtest.
Managing the dependency was simply too painful.
Case 2 – Technical Dependency Goes Wrong, over and over
Case 2 was the .NET framework. When we upgraded from .NET 4.0 to .NET 4.5, our testers noticed that in some scenarios, if the user was accessing ReQtest using Internet Explorer 9, ReQtest could freeze up the user’s entire browser. Nothing short of killing the browser would let the user continue.
We spent days trying to figure this out, but eventually we gave up because it was taking way too much time. So for several years now we have been stuck with .NET 4.0, which has blocked us from using some libraries that require a newer version.
We re-tested when .NET 4.5.1 was released, but the bug was still present. Now with .NET 4.5.2 our first tests indicate that the bug may have resolved itself, so we are hopeful that this upgrade path has now finally been unblocked.
I’ll be talking a lot more about what your actual plan to manage dependencies should be in the next piece.