
in the underlying logic affecting our presentation layer tests. (They are hard
enough to automate well as it is!)
Another consideration is to design the presentation layer so that its logic can
be tested independently of the presentation framework. Humble Dialog (see
Humble Object on page 695) is the key design-for-testability pattern to apply
here. In effect, we are defi ning sublayers within the presentation layer; the layer
containing the Humble Dialogs is the “presentation graphic layer” and the layer
we have made testable is the “presentation behavior layer.” This separation of
layers allows us to verify that buttons are activated, menu items are grayed out,
and so on, without instantiating any of the real graphical objects.
Variation: Service Layer Test
The Service Layer is where most of our unit tests and component tests are
traditionally concentrated. Testing the business logic using customer tests is
a bit more challenging because testing the Service Layer via the presentation
layer often involves Indirect Testing and Sensitive Equality (see Fragile Test on
page 239), either of which can lead to Fragile Tests and High Test Maintenance
Cost (page 265). Testing the Service Layer directly helps avoid these problems.
To avoid Slow Tests (page 253), we usually replace the persistence layer with
a Fake Database (see Fake Object on page 551) and then run the tests. In fact,
most of the impetus behind a layered architecture is to isolate this code from the
other, harder-to-test layers. Alistair Cockburn puts an interesting spin on this
idea in his description of a Hexagonal Architecture at http://alistair.cockburn.us
[WWW].
The Service Layer may come in handy for other uses. It can be used to run the
application in “headless” mode (without a presentation layer attached), such as
when using macros to automate frequently done tasks in Microsoft Excel.
Variation: Persistence Layer Test
The persistence layer also needs to be tested. Round-trip tests will often suffi ce
if the application is the only one that uses the data store. But these tests won’t
catch one kind of programming error: when we accidentally put information
into the wrong columns. As long as the data type of the interchanged columns is
compatible and we make the same error when reading the data, our round-trip
tests will pass! This kind of bug won’t affect the operation of our application but
it might make support more diffi cult and it will cause problems in interactions
with other applications.
When other applications also use the data store, it is highly advisable to imple-
ment at least a few layer-crossing tests that verify information is put into the
Layer Test
Layer Test
339