CHAPTER 14 ■ GOOD (AND BAD) PRACTICE
you performed during development. You’ll have probably forgotten them all, anyhow, unless you kept
them in some way (perhaps commented out at the bottom of your class file as I sometimes do). Small
changes, though, have a way of causing large unintended consequences—consequences that might have
been caught had you thought to put a test harness in place.
A test harness is a set of automated tests that can be applied to your system as a whole or to its
individual classes. Well deployed, a test harness helps you to prevent bugs from occurring and from
recurring. A single change may cause a cascade of errors, and the test harness can help you to locate and
eliminate these. This means you can make changes with some confidence that you are not breaking
anything. It is quite satisfying to make an improvement to your system and then see a list of failed tests.
These are all errors that might have been propagated within your system but that now it will not suffer.
Continuous Integration
Have you ever made a schedule that made everything okay? You start with an assignment: code maybe,
or a school project. It’s big and scary, and failure lurks. But you get out a sheet of paper and you slice it
up into manageable tasks. You determine the books to read and the components to write. Maybe you
highlight the tasks in different colors. Individually, none of the tasks is actually that scary, it turns out.
And gradually, as you plan, you conquer the deadline. As long as you do a little bit every day, you’ll be
fine. You can relax.
Sometimes, though, that schedule takes on a talismanic power. You hold it up like a shield, to
protect yourself from doubt, and from the creeping fear that perhaps this time you’ll crash and burn.
And it’s only after several weeks that you realize the schedule is not magic on its own. You actually have
to do the work, too. By then, of course, lulled by the schedule’s reassuring power, you have let things
slide. There’s nothing for it but to make a new schedule. This time it will be less reassuring.
Test and build are like that, too. You have to run your tests. You have to build your projects, and
build them in fresh environments regularly, otherwise the magic won’t work.
And if writing tests is a pain, running them can be a chore. Especially as they gain in complexity
and failures interrupt your plans. Of course, if you were running them more often, you’d probably
have fewer failures, and those you did have would stand a good chance of relating to new code that’s
fresh in your mind.
It’s easy to get comfortable in a sandbox. After all, you’ve got all your toys there. Little scriptlets that
make your life easy, development tools, and useful libraries. The trouble is, your project may be getting
too comfortable in your sandbox, too. It may begin to rely on uncommitted code, or dependencies that
you have left out of your build files. That means it’s broken anywhere else but where you work.
The only answer is to build, build, and build again. And do it in a reasonably virgin environment
each time.
Of course, it’s all very well to advise this. It’s quite another matter to do it. Coders as a breed tend to
like to code. They want to keep the meetings and the housekeeping to a minimum. That’s where
Continuous Integration (CI) comes in. CI is both a practice and a set of tools to make the practice as easy
as it possibly can be. Ideally, builds and tests should be entirely automatic, or at least launchable from a
single command or click. Any problems will be tracked, and you will be notified before an issue becomes
too serious. I will talk more about CI in Chapter 20.
Summary
A developer’s aim is always to deliver a working system. Writing good code is an essential part of this
aim’s fulfillment, but it is not the whole story.
In this chapter, I introduced PEAR (which is also the subject of the next chapter). I discussed two
great aids to collaboration: documentation and version control. You saw that version control requires
automated build, and I introduced Phing, a PHP implementation of Ant, a Java build tool. I discussed
software testing, and introduced CI, a set of tools to automate build and testing.