As new product releases and development expand at an ever-quickening rate, there are more and more questions which DevOps teams need to address. How do you ensure that your quality assurance (QA) is adjusted properly? And can your testing program really keep up with continuous integration and/or agile development?
For most organizations—and old approaches to QA—the answer to the latter question is likely to be no. This doesn’t mean that exploratory testing is dead, and nor does it mean the only way forward is to automate via machine learning. But it does mean you need to blend and optimize in order to grow your business—and testing—appropriately.
By blending, optimizing, and growing your testing powers, your QA should be able to meet the needs of your business. It should, over time, evolve into a distinct business unit which advises your company on how to grow and dominate individual markets. Ultimately, you need to deliver mobile and web apps that can lift your company to new heights.
In recent years, continuous integration (CI) has become a mainstream technique, widely adopted as part of the software development process. CI servers like Jenkins are trusted by developers around the world, while there are also various CI tools for open-source systems like Google’s Kubernetes, allowing developers to automate delivery pipelines.
We’ll go into more detail further down, but continuous integration—in tandem with continuous delivery and continuous deployment—is speeding up release rates, enabling smaller (and less disruptive) code changes, improving test reliability, and generally saving developers time, money and effort. Most importantly, this is ensuring that users are getting more reliable apps, and much quicker.
We’ll start by defining CI and underlining its importance, and then we’ll list its key benefits before looking at some best practices to help you get the most out of continuous integration.
What is continuous integration?
Continuous integration—or CI—encompasses a set of principles and coding practices that enable software development teams to make minor adjustments to code more regularly and reliably. It is designed to enhance workflow and smooth the development process as well as bringing about culture changes so that development teams are better equipped.
As well as being a set of practices, CI is also a philosophy intended to facilitate greater consistency in the integration process. It allows DevOps teams to make code changes more frequently, encouraging closer collaboration and boosting app quality. It is designed to ensure consistent, automated methods of building, packaging, and testing.
With continuous integration, teams have the ability to continuously deliver integrated code—whether new features or bug resolution—so that ‘green builds’ are ready to release. Making use of CI is quite simple: Teams can implement their chosen version control system (e.g. Git, SVN, or Bitbucket), write tests for critical components, and then use a continuous integration and delivery service to run tests on each committal to the repository.
The importance of continuous integration
In the absence of CI, engineering teams can become cut off from the rest of the organization, with communication in particular being hindered. This can add substantial bureaucratic costs, while slowing down code releases and leading to increased failure rates. In turn, this makes it harder for engineering teams to provide delivery-time estimates for requests as integrating new changes is more difficult.
Continuous integration is also important as it can enable better transparency. It isn’t just developers who benefit from this, but the whole business. In this way, continuous integration helps to facilitate more effective planning, and it also ensures that teams are better equipped to turn those plans into reality.
Using continuous integration
CI is usually used in tandem with agile software development. A product roadmap composed of a list of tasks is drawn up, with these tasks then allocated to members of the engineering team. The software engineers can then work on these tasks independently and in parallel with one another. As individual tasks are completed, software developers can add them to the CI system so that they can be integrated into the wider software development project.
When using CI, follow this step-by-step process:
- Write tests for the most critical aspects of the code base.
- Run those tests automatically on every push to the code repository.
- Ensure every team member integrates their code changes every day.
- Resolve any breaks and errors swiftly.
- Write tests for each new story that’s implemented.
Continuous integration, continuous delivery & continuous deployment
It’s important to clarify the differences between continuous integration, continuous delivery, and continuous deployment. While they are interrelated, they serve different functions—in effect, they’re three different aspects of an automated software release pipeline, guiding the project from the initial idea to completion and delivery.
The first step along this pipeline is the CI process—the integration phase—where numerous developers work to merge their code changes with the project’s main code repository. The continuous delivery stage is next, where automated building tools are used to assemble an artifact which can then be rolled out to end users. By this stage, it should be ready for delivery at any time.
Finally, there’s continuous deployment, where the software is automatically launched and distributed to end users. By this point, the artifact will have passed the integration and delivery stages, and so can be rolled out to users. This is done automatically, via tools and scripts that transfer the software to an app store or other mechanism, like public servers.
To roll your software product out smoothly and quickly, then, it helps to automate your whole workflow rather than just having automated testing on its own. Robust continuous deployment also makes the onboarding process easier as there’s a fully automated process in place, allowing you to integrate new team members with minimal hassle.
Benefits of continuous integration
Now that we’ve clarified the differences between continuous integration, continuous delivery, and continuous deployment, we need to look at some of the key benefits of introducing CI tools to the build process. CI can have transformative impacts on development practices, smoothing the release process and allowing for a more productive production environment—so let’s look at how that happens.
1. There are smaller batches of code changes
One key advantage of continuous integration, delivery, and deployment (CI/CD) is that it allows developers to integrate smaller pieces of new code. As a result, these code changes are simpler and more straightforward than integrating larger pieces of source code, leading to fewer problems further down the line. With continuous testing, these smaller batches of code can be tested once they’re added to the code repository, so any problems are uncovered sooner.
2. It’s easier to isolate faults
CI tools should also allow for more efficient isolation of any faults—fault isolations should be easier to highlight and then to implement. This way, there should be fewer bugs appearing in the software, reducing the risk of sudden breakdowns and other technical problems as issues are discovered and addressed before they can damage the system as a whole.
3. The production and release cycle will move faster
As failures are easier to detect with CI/CD, this should help to speed up your production and release cycle, while ensuring that applications meet a consistently high standard. Smooth CI/CD pipelines ensure that codes are continually merged and deployed, so that they’re always in a release-ready state. Your test-driven development process should always take account of how end users will be using your applications, and reflect that closely.
4. The software is easier to maintain
With an automated build process, you should find that it’s easier to maintain your software and resolve any small defects. Solving non-critical issues quicker comes with numerous advantages. In particular, it frees your developers and testers alike up to focus on more serious issues, making sure that these are addressed sooner. The ultimate beneficiaries are your end users as they’ll benefit from enhanced functionality.
5. Your customers will be happier
Indeed, satisfied customers are the aim of the game. First impressions count for a lot: If a user is confronted with a poorly-designed user interface, there’s a good chance they’ll look for alternatives instead. Your CI/CD process should also allow you to tweak future versions of the app, including adding new features, based on how your customers actually use it. Customer feedback is important—you must pay attention to it and take it seriously.
Essential practices in continuous integration
Important as it is to understand why continuous integration can work for your DevOps team, it’s also essential to familiarize yourself with the relevant best practices—from integration tests, test suites, and key metrics through to dependencies and tutorials. Here, we’ll take a closer look at some of them, taking our cue from software developer Martin Fowler’s principles of continuous integration:
1. Keep a single source repository
A single shared repository can make a huge difference. Software development is unavoidably complex, involving a code base consisting of many different files and with multiple individual developers working on any given project. Everyone should know where to find the files they need, and this is why there should be a single repository. There should be no ambiguity or uncertainty about where particular files are stored.
2. Deploy automation
Automated tests and build environments are invaluable. These days, automated build environments are a regular fixture of development: Java has Ant and Unix has Make, while GitHub and Docker Hub can also be used to set up automated builds. It can be a very complicated process (including loading schemas into databases, moving files, compilation, and so on), turning sources into a running system, which is why you should automate it.
3. Enable software self-testing
With automated testing, highlighting and resolving bugs in the software is rendered much more efficient. Just because a program is up and running, of course, doesn’t necessarily mean that it functions as it should. Including automated tests in the build process can help to ensure that any bugs are caught quicker. However, self-testing code requires a series of automated unit tests that can analyze a large part of the code and be self-checking.
4. Fix errors immediately
If you have a broken build, you shouldn’t hang around before fixing it. If the mainline build fails, it should be fixed without delay. Mainline breaks aren’t necessarily a disaster, but if they’re happening continually, it suggests your team needs to be more careful before committing code. What matters, though, is that errors are fixed quickly. One method of doing this is regression to the most recent known good build; you can then progress from there.
5. Ensure your team can see and acquire all necessary resources
Communication is central to continuous integration, so everyone working on a particular project needs to have visibility of its current state and any changes that might have been made to it. Communicating the status of the mainline (or master branch) build is particularly important. When members of the team have a clear overview of how work is progressing, and which changes have been made, this can eliminate avoidable errors and confusion.
There’s no simple, one-size-fits-all solution to introducing continuous integration—making CI work for you will obviously depend on the particular structure of your setup as well as the make-up of your team, so you’ll need to be flexible and pragmatic about it. And if you’re just starting out, and adopting continuous integration for the first time, it may be worth getting some pointers from teams that have used it before.
Nevertheless, the suggestions and observations we’ve made should provide some useful insights to help you along the way.