Continuous Integration: A Summary

Continuous integration is another XP practice that benefits from the use of good software tools. In essence, continuous integration means building a complete copy of the system so far (and running its full test suite) several times per day. By doing this, you can be sure the system is ready to walk out the door (at least as ready as it could possibly be) at any moment. This process must be relatively automatic (a single command, perhaps on a timer, builds and tests the whole system), or no one would ever do it. There are several reasons for spending the set-up time and energy to achieve continuous integration: The customer and team can see progress on the system, integration bugs are reduced, and the tests are run frequently.

Visible Progress

Continuous integration includes something subtle that goes beyond its practical benefits. It affirms the unity of the team development effort. The built and tested system acts as a center of gravity toward which all development is pulled. As a developer, you know that as soon as you check code into the repository, it will be pulled into the main development stream. You’re less likely storm off in your own direction if you know that later that day your code will be playing with the entire system. Anyone can see the state of the working system at any time; and as more acceptance tests pass and new features show up in the built system, coders sense the progress towards the goal and gain confidence in its eventual attainment. (If the built system languishes and acceptance test scores don’t rise, this signals serious trouble that might have lain dormant far longer in an un-integrated system.)

Reduced Integration Pain

If class X doesn’t jibe with class Y, it makes sense to know about the problem as soon as possible. The longer the X and Y go before meeting, the fuzzier the authors’ memories will be on the subject when the time comes to discover the show-stopping X vs. Y bug. Continuous integration makes sure the incompatible dance partners meet within hours or minutes. Not only does it solve the immediate problem (the defect introduced by incompatible changes), but it forces the developers concerned to examine why the defect might have occurred in the first place: “Ah, I see, Sandra already refactored the CapriciousDictator class, so there’s no reason for me to have added the extraEnforcement method to OppressiveRegime.” A cleaner (and working!) system results.

Java Start Sidebar

The first big software project I worked on was a mess…but it had continuous integration. Why? The team, who were a bunch of inexperienced Java developers, couldn’t get a reliable build running on anyone’s machine. Too many dependencies and libraries had to be linked in for anyone to get them straightened out with the mounting pressure of an impossible deadline. Finally, we had someone cobble together a shell-based build script that compiled all the code that currently resided on the integration server. Because no one could compile individual files locally, in order to see something work, it had to be uploaded to the integration server.

With five or six developers working simultaneously, the script was run (and the Web server restarted) about once every five minutes. The developer hoping to integrate had to shout for permission before actually restarting the server: “Anybody mind a restart?!” The result was chaos—but if anyone’s changes clashed, we knew about it within seconds.

Java End Sidebar

Tests Run Frequently

Unit testing is an integral part of a continuously integrated system. The build is not complete until the unit tests have all passed at 100 percent and the functional and integration tests have run. The result is not only a system that runs but also one that is proven to run correctly. Tests lose value if they aren’t run frequently. If they are run as often as the build, and the build is frequent, they provide a constant update on how the system performs.

Continuous Integration and J2EE

Under the J2EE development model, apps undergo significant customization during assembly and deployment. Wrapping and packaging a full J2EE app requires in-depth knowledge of different archive formats (JARs, WARs, and EARs), deployment descriptors, and methods of deploying apps and components into existing containers. Given the complexity of a J2EE build, an automated build tool is required. Unlike many of the other practices of XP, achieving continuous integration is mainly a technical feat. Once an automated process is in place, using it should be easy (and beneficial) enough that developers barely have to breathe on it to keep the monster rolling. All a shop needs to begin continuous integration is a tool set to help automate and put together a repeatable build. This tutorial will cover Ant, the emerging standard for build automation in Java. Ant allows developers to write tests in an XML build script that calls on Java classes to do its work. The tool is cross-platform (a critical criteria for any Java-based tool) and easy to extend and modify. Ant performs all the basic tasks of a build tool: compilation, archive creation, classpath management, and so on. It also supports test and report automation as well as a variety of miscellaneous useful tasks, such as source control interaction, FTP, and property file editing. This arsenal of predefined build tasks allows developers to automate complicated build processes with ease. After some work with Ant, a Java app can be retrieved from source control, built, customized to its intended environment (production versus integration for instance), tested, and deployed to a remote server with a single command. Ant is still the industry-standard tool for continuous integration, but several other tools are now available which offer an alternative approach to continuous integration. First among these tools is Maven. Maven offers a well-defined project layout, built-in unit testing through Maven’s JUnit plug-in, built-in code visualization and reporting that includes a number of ready-to-run reports to help your team focus on the project, and integration with other agile technologies: Maven includes plug-ins for code coverage, CVS check-in, code formatting, code style violations, and bug tracking. Another interesting continuous integration tool is CruiseControl. Like Ant, CruiseControl was designed to be extended. All of the components it uses are built around a plug-in architecture (inspired by a similar mechanism in Ant), and writing your own plug-in to support your own environment is easy. CruiseControl supports a number of types of version control repositories are supported, including CVS (which is also covered in this tutorial). Although CruiseControl was built to use Ant build scripts, it also comes with support for Maven.

We also cover AntHill in this tutorial; it is available in both open source and commercial versions (we only discuss the open source version in this tutorial). AntHill offers a controlled build process, the ability to track and reproduce builds, the ability to signal a build status (through e-mail, CM labels, etc.), and a fully automated build process that can run tests and generate metrics.