Testing

The Relationship Between Testability and Good Design

Recently, the profile of unit testing has risen dramatically. In the 1990s and early 2000s, it was a practice that seemed to languish. As is often the case when people adopt a new technology  back then, organizations were moving from structured design toward object-oriented design  they place all their focus on getting the essentials right and discard practices that don't seem to fit neatly into the new picture. And so they neglected unit testing.

But if we've learned anything over the past 10 years, it is that unit testing is an essential discipline. Tests help us better reason about our code, and they form a regression bedrock that makes refactoring and feature addition much easier. There is, however, a very subtle effect of unit testing that few people discuss. There seems to be an eerily consistent connection between testability at the unit level and good design. Almost uniformly, code that is hard to test has design problems. When you fix the design problems, it becomes easy to test.

Let's take a look at an example.

Figure 1: A typical class.

In Figure 1, we have a class that seems to have decent structure. There is one public method, evaluate(), which is the user's point of contact with the class. It delegates its work to a series of private methods. Overtly, there is nothing wrong with this  class RuleEvaluator does the job we've intended it to. Now, how should we write unit tests for this class? We should be able to instantiate it, call evaluate() with various arguments, and check the results. But suppose we wanted to test getNextToken()? The getNextToken method is private. Theoretically, we should be able write tests for evaluate that exercise getNextToken(), but sometimes it is difficult to engineer the inputs we'd want to test a deeply called method specifically. And, if we go down this route, the tests we write might be indirect and not very self-explanatory.

People often run into this problem and think that it is just a case of testing being difficult work. But let's look again.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!