Introducing Continuous Integration as a Way to Improve Software Quality and Reduce Risk
- A Day in the Life of CI
- What Is the Value of CI?
- What Prevents Teams from Using CI?
- How Do I Get to "Continuous" Integration?
- When and How Should a Project Implement CI?
- The Evolution of Integration
- How Does CI Complement Other Development Practices?
- How Long Does CI Take to Set Up?
- CI and You
- Commit Code Frequently
- Don't Commit Broken Code
- Fix Broken Builds Immediately
- Write Automated Developer Tests
- All Tests and Inspections Must Pass
- Run Private Builds
- Avoid Getting Broken Code
- Assumption is the mother of all screw-ups.
- —Wethern's Law of Suspended Judgment
Early in my career, I learned that developing good software comes down to consistently carrying out fundamental practices regardless of the particular technology. In my experience, one of the most significant problems in software development is assuming. If you assume a method will be passed the right parameter value, the method will fail. Assume that developers are following coding and design standards and the software will be difficult to maintain. Assume configuration files haven't changed, and you'll spend precious development hours needlessly hunting down problems that don't exist. When we make assumptions in software development, we waste time and increase risks.
We may think that the latest, greatest technology will be the "silver bullet" to solve all of our problems, but it will not. At one company, one of my initial responsibilities was to incorporate good software development practices into the company—by example. Over time, we were able to implement many widely accepted practices for developing good software into the projects. Having worked on many different projects that used different methodologies, I have found that, in general, iterative projects—using the Rational Unified Process (RUP) and eXtreme Programming (XP), in my case—work best, because risks are mitigated all along the way. Developing software requires planning for change, continuously observing the results, and incrementally course-correcting based on the results. This is how CI operates. CI is the embodiment of tactics that gives us, as software developers, the ability to make changes in our code, knowing that if we break software, we'll receive immediate feedback. This immediate feedback gives us time to course-correct and adjust to change more rapidly.
CI is about the fundamentals. It may not be the most glamorous activity in software development, but integrating software is vitally important in today's complex projects. Seldom do the users of the software say to me, "Wow, I really like the way you integrated the software in the last release." And since that doesn't happen, it may seem like it isn't worthwhile to make these efforts behind the scenes. However, anyone who has developed software using a practice such as CI is empowered by a consistent and repeatable build process kicked off when a change occurs to the version control repository.
Spending some time on the nonglamorous fundamental activities in software development means there is more time to spend on the challenging, thought-provoking activities that make our jobs interesting and fun. If we don't focus on the fundamentals, such as defining the development environment and building the software, we'll be forced to perform low-level tasks later, usually at the most inconvenient times (immediately before software goes to production, for example). This is when mistakes happen as well. The discipline involved in keeping the build "in the green" frees you from worrying about whether everything is still working. It's like exercising—yes, it takes self-discipline; yes, it can be painful work—but it keeps you in shape to play in the big game, when it counts.
This chapter attempts to answer the questions that you may have when making the decision to implement the practices of CI on a project. It provides an overview of the advantages and disadvantages of CI, and covers how CI complements other software development practices. CI is not a practice that can be handed off to a project's "build master" and forgotten about. It affects every person on the software development team, so we discuss CI in terms of what all team members must practice to implement it.
What's a day of work like using CI? Let's examine Tim's experiences.
A Day in the Life of CI
As Tim opens the door to his company's suite, he views the wide-screen monitor displaying real-time information for his project. The monitor shows him that the last integration build ran successfully a few minutes ago on the CI server. It shows a list of the latest quality metrics, including coding/design standard adherence, code duplication, and so on. Tim is one of 15 developers on a Java project creating management software for an online brewery. See Figure 2-1 for a visualization of some of the activities in Tim's day.
Figure 2-1 A day in the life
Starting his day, Tim refactors a subsystem that was reported to have too much duplicate code based on the latest reports from the CI server. Prior to committing his changes to Subversion, he runs a private build, which compiles and runs the unit tests against the newest source code. After running this build on his machine, he commits his changes to Subversion. All the while, the CruiseControl CI server is polling the Subversion repository. A few minutes later, the CI server discovers the changes that Tim committed and runs an integration build. This integration build runs automated inspection tools to verify that all code adheres to the coding standard. Tim receives an e-mail about a coding standard violation, quickly makes the changes, and checks the source code back into Subversion. The CI server runs another build and it is successful. By reviewing the Web reports generated by the CI server, Tim finds that his recent code refactoring successfully reduced the amount of duplicate code in his subsystem.
Later in the day, another developer on the project, Lisa, runs into Tim's office.
- Lisa: I think the changes you made earlier today broke the last build!
- Tim: Hmm but, I ran the tests.
- Lisa: Oh, I didn't have time to write tests.
- Tim: Are you following the code coverage metric we have established for the project?
Because of this discussion, they decided to fail the integration build if their code coverage was below 85%. Furthermore, Lisa wrote a test for the defect and fixed the problem she discovered because of her conversation with Tim. The integration build continued to stay "in the green."