Delivering software in a continuous delivery capacity is something that nearly every project strives for. Problem is, not many projects are able to achieve continuous delivery because they don’t have the confidence in their applications quality, their build pipelines, their branching strategy or worst case, all of them.
A good indicator as to whether you fall into one of the above is to ask yourself: `can I confidently release master branch right now`.
If your answer is no, then how do we start to break down and resolve these problems.
Building confidence in quality
A recent project I have been working on fell into a few of the above categories. Nearly all their testing was done on a deployment to a long living environment, after a merge commit to master. Along with a lot of duplicated work throughout their pipeline.
The test strategy shown above was for a simple front-end application that reads data from an external API.
To start, we identified areas of our application that we knew were unloved, or treacherous to develop. Once identified, we put in place appropriate test automation. When writing test automation it is so important that your tests are robust, fast and deterministic.
We pushed as much of our UI automation down into the application. Ideally you want your application adhering to the testing pyramid principles. Testing elements that have particular classes with tools such as selenium are both time costly and of no value. There are better, more appropriate tools to do this.
Once our test scaffolding was in place, we started to feel more comfortable refactoring problem areas and reducing complexity.
We isolated our application by stubbing out external services or dependencies where necessary – we didn’t want to be testing services outside our scope. Where possible, we recommend agreeing a contract with your external dependencies and using this to develop against.
We also recommend containerizing your app. Being able to deploy and run the same image of an application locally and on production is incredibly powerful. Long gone are the days of having long living application servers and the phrase of ‘well it works on my machine’.
Start failing fast
Once we had confidence that when our tests all passed then the application could be deployed, we then looked to address where our tests were running.
Having tests run after a merge commit to master is too late in the process. Leaving it this long introduces a risk that someone pushes the release to production button before tests have been run.
We need to run tests earlier in the process.
In the past, to solve this problem you may have adopted complicated branching strategies dev, test, master which on paper seem reasonable, but in practice introduce horrendously slow unnecessary feedback loops and messy merges between multiple branches.
We decided to harness the power of pull request environments instead, to allow our tests to run on short living infrastructure before we merge to Master. With DevOps paradigms such as immutable infrastructure, infrastructure as code and containerisation, deploying a new environment becomes trivial.
This becomes even more powerful if you deploy your pull request environments in the same way as your production site, since you effectively test the deployment itself.
Having pull request environments spun up also caters for any testing requirements, such as exploratory testing or demos, and massively speeds up developer feedback loops.
The end result is a much higher confidence in your applications quality in master branch, which to any project is invaluable.
This a two-part series, with the next article focusing on how we can start to deliver master branch to production. Watch this space.