Lecture 17: Case Study: JUnit
The JUnit testing framework which you’ve been using to test your own code in 6.170 is
worth studying in its own right. It was developed by Kent Beck and Erich Gamma.
Beck is an exponent of patterns and Extreme Programming (XP); Gamma is one of the
authors of the celebrated design patterns book. JUnit is open source, so you can study
the source code yourself. There’s also a nice explanatory article in the JUnit distribu-
tion, entitled ‘A Cook’s Tour’, which explains the design of JUnit in terms of design pat-
terns, and from which much of the material in this lecture is drawn.
JUnit has been a great success. Martin Fowler, an insightful and pragmatic proponent
of patterns and XP (and also author of a wonderful book on object models called
Analysis Patterns
), says about JUnit:
Never in the field of software development was so much owed by so many to so few
lines of code.
JUnit’s ease of use is no doubt in large part responsible for its popularity. You might
think that. since it doesn’t do very much – it just runs a bunch of tests and reports their
results – JUnit should be very simple. In fact, the code is rather complicated. The main
reason for this is that it has been designed as a framework, to be extended in many
unanticipated ways, and so it’s full of rather complex patterns and indirections
designed to allow an implementer to override some parts of the framework while pre-
serving other parts.
Another complicating influence is a desire to make tests easy to write. There’s a clever
hack involving reflection that turns methods of a class into individual instances of the
type
Test
. Here’s another example of a hack that seems unconscionable at first. The
abstract class
TestCase
inherits from the class
Assert
, which contains a bunch of static
assertion methods, simply to allow a call to the static
assert
method to be written as
just
assert (…)
, rather than
Assert.assert (…)
. In no sense is
TestCase
a subtype of
Assert
,
of course, so this really makes no sense. But it does allow code within
TestCase
to be
written more succinctly. And since all the test cases the user writes are methods of the
TestCase
class, this is actually pretty significant.
The use of patterns is skillful and well motivated. The key patterns we’ll look at are:
Template Method
, the key pattern of framework programming;
Command
,
Composite
,
and
Observer
. All these patterns are explained at length in Gamma et al, and, with the
105

exception of
Command
, have been covered already in this course.
My personal opinion is that JUnit, the jewel in the crown of XP, itself belies the funda-
mental message of the movement – that code alone is enough. It’s a perfect example of
a program that is almost incomprehensible without some abstract, global representa-
tions of the design explaining how the parts fit together. It doesn’t help that the code is
pretty lean on comments – and where are there comments they tend to dwell on which
Swiss mountain the developer was sitting on when the code was written. Perhaps high
