PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 20 ■ CONTINUOUS INTEGRATION


gather up those throwaway scraps of code, written to put your component through its paces during
development, you’ve got yourself a test case. Stick them into a class and add them to your suite.
Oddly, it’s often the running of tests that people avoid. Over time, tests take longer to run.
Failures related to known issues creep in, making it hard to diagnose new problems. Also, you suspect
someone else committed code that broke the tests, and you don’t have time to hold up your own work
while you fix issues that are someone else’s fault. Better to run a couple of tests related to your work
than the whole suite.
Failing to run tests, and therefore to fix the problems they could reveal, makes issues harder and
harder to address. The biggest overhead in hunting for bugs is usually the diagnosis and not the cure.
Very often, a fix can be applied in a matter of minutes, set against perhaps hours searching for the reason
a test failed. If a test fails within minutes or hours of a commit, though, you’re more likely to know where
to look for the problem.
Software build suffers from a similar problem. If you don’t install your project often, you’re likely to
find that, while everything runs fine on your development box, an installed instance falls over with an
obscure error message. The longer you’ve gone between builds, the more obscure the reason for the
failure will likely be to you.
It’s often something simple: an undeclared dependency upon a library on your system, or some
class files you failed to check in. Easy to fix if you’re on hand. But what if a build failure occurs when
you’re out the office, though? Whichever unlucky team member gets the job of building and releasing
the project won’t know about your set up, and won’t have easy access to those missing files.
Integration issues are magnified by the number of people involved in a project. You may like and
respect all your team members, but we all know that they are much more likely than you are to leave
tests unrun. And then they commit a week’s work of development at 4 p.m. on Friday, just as you’re
about to declare the project good to go for a release.
Continuous Integration (CI) reduces some of these problems by automating the build and test
process.
CI is both a set of practices and tools. As a practice, it requires frequent commits of project code (at
least daily). With each commit, tests should be run and any packages should be built. You’ve already
seen some of the tools required for CI, in particular PHPUnit and PEAR. Individual tools aren’t enough,
though. A higher-level system is required to coordinate and automate the process.
Without the higher system, a CI server, it’s likely that the practice of CI will simply succumb to our
natural tendency to skip the chores. After all, we’d rather be coding.
Having a system like this in place has three clear benefits. Firstly, your project gets built, and tested
frequently. That’s the ultimate aim and good of CI. That it’s automated, though, adds two further
dimensions. The test and build happens in a different thread to that of development. It happens behind
the scenes, and doesn’t require that you stop work to run tests. Also, as with testing, CI encourages good
design. In order for it to be possible to automate installation in a remote location, you’re forced to
consider ease of installation from the start.
I don’t know how many times I’ve come across projects where the installation procedure was an
arcane secret known only to a few developers. “You mean you didn’t set up the URL rewriting?” asks one
old hand with barely concealed contempt. “Honestly, the rewrite rules are in the Wiki, you know. Just
paste them into the Apache config file.”
Developing with CI in mind means making systems easier to test and install. This might mean a
little more work upfront, but it makes our lives easier down the line. Much easier.
So, to start off, I’m going to lay down some of that expensive groundwork. In fact, you’ll find that in
most of the sections to come, you’ve encountered these preparatory steps already.


Preparing a Project for CI


First of all, of course, I need a project to integrate continuously. Now, I’m a lazy soul, so I’ll look for
some code that comes with tests already written. The obvious candidate is the project I created in

Free download pdf