Dominique Stender Good software is only the beginning

20Nov/090

HOWTO: Continuous Integration for PHP, pt. 1

bubblesAfter my initial post which gave only a rough outline on how to install all the various components for a continuous integration environment for PHP I had to struggle quite a bit to get everything to work. There doesn't seem to be a tutorial or howto online that goes to the level of depth required. Hence I decided to make my own.

This will be a series of several posts where I will try to cover all basic aspects of continuous integration for PHP:

An informational article about what continuous integration is all about.

After that I'll give you a step-by-step guide on how to set up a continuous integration environment using a virtual environment.

I will provide you with an example build script for automated local tests in the third article.

The fourth article will put all things together and establish continuous integration.

This article will cover the first topic "What is continuous integration all about?".

Continuous integration is an important aspect in agile development methodologies and test driven development.

The whole idea behind continuous integration is to have a process running in the background that integrates and tests the various pieces of source code that you generated continuously and automatically. In a nutshell, that's it.

Why would we want to automate our testing? Well I believe that is obvious:

  1. Testing is hard.
  2. Testing is boring.
  3. Testing is time consuming.

All three aspects - and there might be more - make it impractical to achieve complete test coverage manually even in a medium sized project. It becomes much more feasible to invest the effort of setting up an automated test environment and writing the tests once which from then on will run day after day after day.

Which components are required for continuous integration with PHP?

There are a few alternatives to what I'm going to discuss here (I give some of them in parenthesis) but roughly you'll want:

  • Unittest scripts that will cover your regression tests. PHPUnit is the tool of choice here (SimpleTest also does a good job)
  • A build tool such as phing. It will automate the building of your test environment.
  • For the continuity aspect a cronjob is enough. (CruiseControl & phpUnderControl are much more sophisticated. Check them out if a cronjob is not cutting it for you)
  • You will need some sort of revision control. My tool of choice is Subversion. (CVS, and many others are available)
  • I strongly recommend using your own integration environment over testing on your development machine. VMWare is a great free virtualizer.

Is there more that we can do with continuous integration?

Hell yes! Here are a few examples:

  • Frontend testing (yes, automated) with Selenium IDE and Selenium Remote Control. Note that you will also need some sort of graphical environment for that. Xvfb is usually good enough.
  • You could generate your API doc for PHP with phpDocumentor.
  • You certainly can generate an API doc for JavaScript as well.
  • You could perform unittests for JavaScript or your jQuery plugins.
  • and last not least why don't you push everything on a staging system for your client to see when everything goes well?

Now that we have that covered...

How does an environment with continuous integration look like?
How do we have to work in order to get the most out of it?

As usual, there are many ways to do this. My personal approach consists of two, better three environments:

First, the development machine(s). That is where we develop our code.
Second, the integration machine, where the continuous integration is happening.
Third, optionally a system for staging. This gives you constant feedback from the client.

Overall the workflow looks like this:

My continuous integration environment

My continuous integration environment

The 'devel' environment is local on the developers' machine. A virtual machine as I pointed out earlier but that is not relevant at this moment. If there is more than one developer, each will have his own 'devel' environment. The development (1) is done locally. All developers commit to and update  from a central Subversion repository (2).

The 'int' (integration) environment usually sits on a different piece of hardware. I prefer the 'int' and the 'stage' system to be on two different virtual hosts on one machine. However your setup might be, on the 'int' environment a cronjob is running continuously and pulls the latest revision of the product out of Subversion (3). If a new revision is found, the integration (4) starts, running all tests, generating all reports, writing API docs and so on.

If an error occurs during the integration test, a mail is being sent to all developers. I've heard of teams who change the color of an ambient orb to red in this case, or switch on a lava lamp. Do as you please. A mail is a good start, however. The team can then utilize all reports on 'int' (available thru the apache virtual host) to inspect the problem and fix it.

Because the integration is continuous, the feedback about a failing test is fast.

Not much code has to be revised in order to find and fix the bug.

Only when the integration runs without errors, the step (5) starts: Deploying that revision to the 'stage' environment where the client can test it. If you think that might probably not be a good idea in your case / with your client, you might be right. Releasing every other week, at the end of a sprint works just as well. This last step (5) is optional.

That concludes the first part in my series on setting up continuous integration for PHP. Continue with the second part: A installation howto.

Bookmark and Share

Related Posts:

Comments (0) Trackbacks (2)

Leave a comment