Creating high-quality software products requires a considerable time investment. It’s therefore unsurprising that software engineering teams want to make their development workflows more time-efficient.
Continuous integration is a principle that has grown from that desire. The main principle of continuous integration is to commit changes to the code more frequently. The code is then tested by an automated tool and, if it passes, is committed to the master branch of the project.
In traditional integration, developers may commit their changes to the codebase once per week. In continuous integration, commits are made once or maybe even several times per day.
Without any further information, you might jump to the conclusion that this would actually be an inefficient time practice. To demonstrate that line of thought, let’s use grocery shopping as an analogy.
Grocery shopping against software development
How many people do you know that go to the supermarket to get what they need before every single meal? Even if you live above a grocery store, walking down to the shop every single time you’re hungry is not going to be time-efficient. You might think that making a commit every time you make a small change to the code would also be inefficient.
What most people do is reduce the number of trips they need to take to the supermarket. They spend one day per week buying everything they need for the week ahead. This is a traditional weekly shop. It seems analogous to traditional integration. This analogy fails on a few levels, however.
The first significant difference between grocery shopping and software development is bugs. You rarely need to test your weekly shop for errors. Occasionally you might buy the wrong thing. Sometimes there might be an error on the receipt. Or a literal bug in your lettuce. You probably won’t even notice. You might notice that you bought the wrong thing when loading your groceries into the fridge. Even on the seldom occasion that happens, you’ll probably just live with the mistake and eat it anyway.
The second significant difference is that you generally shop individually, not as a team. Sometimes you might take the kids along, and they overload the cart with sweets, but other than that, it’s not really a team endeavor. Software projects have numerous developers contributing to the source code. As such, the source code is continually evolving. If grocery shopping were like software development, it would be like ten team members going out to buy the ingredients to buy a cake. When the team members buy ingredients, the recipe for the cake updates. Suddenly the eggs and butter that you bought no longer work with the cake because the recipe has been updated to make it a vegan cake.
Time inefficiency of fixing errors
The big problem with traditional integration is the time it takes to fix errors when a week’s worth of work from several developers is combined at once. With such a long period of development time, this creates a large risk of merge conflicts. Resolving these conflicts isn’t easy: which developer should change their code?
Through the implementation of continuous integration methodologies, we can mitigate this problem. More frequent commits mean there will be less significant changes to the source code between commits. When errors are identified, there is less code to work through to find the problem. The code is automatically sent back to the developer that submitted it.
To use another cliched analogy: finding errors is like finding a needle in a haystack. With continuous integration, you have divided your haystacks into much smaller piles. You can easily identify which pile the needle is in, particularly if you tested your code as soon as you committed it.
Time inefficiency of testing
While continuous integration may reduce the time spent to find errors, there is still an additional time overhead on testing. If you are manually testing for errors for every commit, every day of the week, that’s obviously going to take a lot longer than it would to test just once a week. The time saved finding and fixing errors is unlikely to cancel out all that extra testing.
For this reason, automated testing is critical to continuous integration. Having a human perform testing on every single commit will simply take too long for continuous integration to be truly viable. Fortunately, large parts of software development testing can be automated.
Continuous integration tools are essential to make the development philosophy work. These tools work by running automated tests on all code committed by a developer. If the code fails the test, it is immediately sent back to the developer for correction.
Automated testing can’t ensure absolutely everything works. There will still need to be some level of human testing, particularly on the visual level. However, in many aspects, computers are far better at testing than humans are. The quality of the testing will depend on the quality of the tests you run. If the tests are thorough, you can have confidence in your newly committed code. You won’t have to do manual human quality assurance on every single commit.
With a rigorous automated testing procedure, continuous integration helps cut time spent on bug fixing. Your team will have more time to spend building features.