Page 172 -
P. 172
can do their jobs. Implementing automated unit tests can ensure that those units work,
letting the QA team concentrate on more complex behavior. By helping the programmers
understand the line between unit testing and functional testing, and take on the responsi-
bility for unit testing, the project manager can help reduce the tension on the project.
Unit Testing Saves Programming Time and Effort
Some project managers find that programmers are resistant to unit tests. Sometimes the
programmers resent the assumption that their code isn’t perfect, even when there is a his-
tory of defects that had to be fixed on previous projects. Other times, they assume that the
QA team’s job is simply to find the programmers’ bugs. But mostly, they don’t like spend-
ing time writing and running unit tests that won’t be delivered in the build. It feels like a
waste of time, without adding much value. But in fact, the opposite is true. Most program-
mers who adopt unit tests find that it actually reduces the total time it takes to build soft-
ware. It may take time to write the tests up front, but it costs more time to go back later
and fix all of the bugs that the unit tests would have caught.
One way that unit tests help the programmers deliver better code is by improving the
object interfaces or function definitions that the programmers use. Many experienced pro-
grammers will recognize the feeling of regret that comes when they start using an object
that they built to encapsulate some functionality, only to realize later that they should
have designed the interface differently. Sometimes there is functionality that the object
needs to provide that the programmer didn’t think of; at other times, it may be that the
methods are awkward to work with, and could have been laid out better. But the code for
the object is already built, and it’s too late to fix it. She will just have to work around the
awkwardness, even though building the object right from the beginning would have saved
her some time and effort. Or she may be frustrated enough to go back and rebuild the
object entirely, which costs even more time. This is a common trap that plagues object-ori-
ented design—there’s no way to know how easy it is to use an object until code is built
that uses it, but there’s no way to build that code until the object is done.
In practice, test-driven development is an effective way to avoid that trap. The program-
mer can build a series of simple unit tests before the object is built. If the object is needed,
she can build a mock object to simulate it. By the time she is ready to define the interface,
she has worked out many of the details and has discovered and avoided the potential
problems with the interface before the object is built.
Programmers also find that effort is unnecessarily wasted in situations when one person
has to use an object that was designed by someone else. Often a programmer finds that the
object’s interface is not clear. There could be ambiguous function names or variables, or it
could be unclear how to use objects that are returned by certain functions.
This is another case when unit tests can be very useful. When a programmer consults doc-
umentation for an object or an API manual, the first thing she usually looks for is an
example of the functionality that she is trying to implement. The unit tests serve the same
purpose. When an object comes bundled with a series of unit tests, the programmer can
consult them to see how the object was intended to be used. Not only do they provide her
164 CHAPTER SEVEN