Testability from a Developer's Perspective
Why should the developer care about testability? Alexander Tarlinder presents the case for testable software and its benefits. The quality attribute testability is broken down into observability, controllability, and smallness and explained further.
Testability means different things to different people depending on the context. From a bird’s eye view, testability is linked to our prior experience of the things we want to test and our tolerance for defects: the commercial web site that we’ve been running for the last five years will require less testing and will be easier to test than the insulin pump that we’re building for the first time. If we run a project, testability would be about obtaining the necessary information, securing resources (such as tools and environments), and having the time to perform various kinds of testing. There’s also a knowledge perspective: How well do we know the product and the technology used to build it? How good are our testing skills? What’s our testing strategy? Yet another take on testability would be developing an understanding of what to build by having reliable specifications and ensuring user involvement. It’s hard to test anything unless we know how it’s supposed to behave.1
Before breaking down what testability means to developers, let’s look at why achieving it for software is an end in itself.
Testable software encourages the existence of tests—be they manual or automatic. The more testable the software, the greater the chance that somebody will test it, that is, verify that it behaves correctly with respect to a specification or some other expectations, or explore its behavior with some specific objective in mind. Generally, people follow the path of least resistance in their work, and if testing isn’t along that path, it’s very likely not going to be performed (Figure 4.1).
Figure 4.1 Is untestable software going to be tested?
That testable software will have a greater chance of undergoing some kind of testing may sound really obvious. Equally apparent is the fact that lack of testability, often combined with time pressure, can and does result in bug-ridden and broken software.
Whereas testable software stands on one side of the scale, The Big Ball of Mud (Foote & Yoder 1999) stands on the other. This is code that makes you suspect that the people who wrote it deliberately booby-trapped it with antitestability constructs to make your life miserable. A very real consequence of working with a system that’s evolved into The Big Ball of Mud architecture is that it’ll prevent you from verifying the effects of your coding efforts. For various reasons, such as convoluted configuration, unnecessary start-up time, or just the difficulty to produce a certain state or data, you may actually have a hard time executing the code you’ve just written, not to mention being able to write any kinds of tests for it!
For example, imagine a system that requires you to log in to a user interface (UI) and then performing a series of steps that require interacting with various graphical components and then navigating through multiple views before being able to reach the functionality you’ve just changed or added and want to verify. To make things more realistic (yes, this is a real-life example), further imagine that arriving at the login screen takes four minutes because of some poor design decisions that ended up having a severe impact on start-up time. As another example, imagine a batch program that has to run for 20 minutes before a certain condition is met and a specific path through the code is taken.
Honestly, how many times will you verify, or even just run, the new code if you have to enter values into a multitude of fields in a UI and click through several screens (to say nothing of waiting for the application to start up), or if you must take a coffee break every time you want to check if your batch program behaves correctly for that special almost-never-occurring edge case?
Testers approaching a system with The Big Ball of Mud architecture also face a daunting task. Their test cases will start with a long sequence of instructions about how to put the system in a state the test expects. This will be the script for how to fill in the values in the UI or how to set the system up for the 20-minute-long batch execution. Not only must the testers author that script and make it detailed enough, they must also follow it ... many times, if they are unlucky. Brrr.