As I’ve learned more and more about testing I’ve learned that there’s way more to testing than just automated tests. There are other practices which, when combined with writing automated tests, serve to make the development process smoother and improve the quality of the product the development team is working on.
One such practice is continuous integration. Perhaps the easiest way for me to explain what continuous integration (CI) is is to describe its opposite.
The opposite of continuous integration
In 2008 I worked at a higher-education software startup in Austin, Texas. As I recall it, our developers tended to work in feature branches that would live for up to a few weeks. About once a month or so we would hold something called a “merge party”. I found the name funny because parties are supposed to be fun but merge parties were a fucking nightmare.
Here’s what would happen at a merge party. The development team (about 10 people) would get in a conference room. Someone would pull up some code on a screen. We’d attempt a merge and get a merge conflict. Anyone whose code was involved in the merge conflict would squint at the screen and try to judge if the “left” code or “right” code was the right version. We’d repeat that process about 95 times until everyone wanted to kill themselves. You might wonder: How did we know, at the end of the merge party, whether our decisions were correct and the code still worked? Good question. There was no way to know. We just had to hope to hell we were right.
Later, in 2013, I worked at a healthcare startup. We used CircleCI there (a great tool BTW) and so our development manager believed that this automatically meant we were practicing CI. We weren’t, though. Once I was forced to code on a feature branch for about three months. I don’t recall the exact process of merging that branch back in but I certainly remember that dealing with merge conflicts at that job was part of our regular workflow.
So if I’m working on a team where we have long-living feature branches (that is, several days or more), then that’s not continuous integration, because the integrations happen infrequently. In continuous integration the integration happens continuously.
What continuous integration actually is
Continuous integration is when developers stitch their work together as frequently as possible.
The benefit of CI is that it reduces the pain of the integration process. There’s a saying: “When something hurts, do it more often.” The more frequently a team integrates their work, the less stuff there is to integrate. Merge conflicts will be less frequent and less severe, and when they happen, the code will be fresh in the developers’ minds and so the merge conflict resolution work will be fairly trivial. But in my experience, when a team practices CI, merge conflicts just don’t happen that much.
What continuous integration has to do with testing
A CI server like CircleCI or Jenkins tends to be associated with running tests. The idea here is that you always want to be sure that the test suite is passing on master, so you check the test suite after every single merge.
I want to be clear though that CI could certainly be practiced without having automated tests and that I think it would still be a really good idea. Merging infrequently without tests would still be more painful and risky than merging frequently. But given the choice, I’d of course prefer to be able to verify that my post-integration master branch is in a working state by running a test suite than by having to run manual tests.
You could say that your test suite is your mechanism for ensuring with a reasonable confidence that each integration was successful.
The difference between continuous integration, continuous deployment and continuous delivery
Continuous integration and continuous deployment are often mentioned together. Continuous integration means always keeping a small difference between the master branch and any feature branch. Continuous deployment means always keeping a small difference between what’s in the production environment and what’s in the development environment.
CI and CD are beneficial for basically the same reasons. Small changes are less risky and less of a headache than big changes.
What’s the difference between continuous deployment and continuous delivery? Think about the difference between a Rails application and an iOS application. We can deploy a Rails application however frequently we want. There’s nothing stopping us from deploying, say, 50 times a day. But an iOS app has the whole review process and stuff. You can’t just deploy it willy-nilly. But that doesn’t mean you can’t always have a complete and working build sitting on the master branch of your iOS project. That’s continuous delivery – always having something ready to go. If you’re practicing continuous deployment, you’re practicing continuous delivery. But you can practice continuous delivery without necessarily practicing continuous deployment.