As an industry, our broad goals are to produce the highest quality software possible in the shortest amount of time. For the past two decades, most organizations have used a five-stage software development lifecycle (SDLC) to give teams a way to ensure high quality and detect as many issues as possible before production.
On the other hand, most people see those goals as being in conflict with each other. If you want to create extremely reliable, high quality software, it is going to be relatively slow; if you want to prioritize speed, you will inevitably have more change failures and resulting outages.
The way we’ve managed these competing pressures over the past two decades has been with a development lifecycle that went from development to testing to integration to staging to production. Between the development phase and the “real-world use” phase, there are three environments dedicated to catching issues that would cause the software to work differently in production.
Two Critical Phases: Development and Production
The truth is the most important phases in the lifecycle are development and production. Development is where the application comes to life; production is where it actually lives. The software development lifecycle needs to focus on those two stages, the beginning and the end, and help applications move as quickly and efficiently as possible from one to the other. A five-stage software development lifecycle over-emphasizes the testing, integration and staging portions of an application’s life. Just as importantly, compared to more modern, cloud native approaches, this type of lifecycle is slower and more error-prone — exactly what we want to avoid.
Rethinking the Phases
Ideally, we’d be able to get all software completely production-ready before leaving the local developer’s machine. In reality, it makes sense to have an intermediate step between development and production to make sure the application has a chance to be evaluated by someone other than the original developer before going into production. But there’s no reason this step should require three separate environments — one intermediate environment should be enough. I think a good name for this environment is “production-like,” making the software development lifecycle development —> production-like —> production.
The key to making this work, however, is to ensure that developers are as empowered as possible to test their applications — and that the developer environment and the intermediate environment are both as similar to production environments as possible. The goal is to make sure developers are able to test for as many sources of problems as possible so that the production-like stage is devoted to handling tests that can’t practically be done by developers, such as involving production data, ensuring configurations are correct and testing load.
Improving Developer Confidence With Change Validation
No one wants someone else to find the fault in their code, but at the same time, developers aren’t crazy about running tests, whether that means writing tests or doing manual tests. But developers shouldn’t have to ship their code off to a testing environment to discover if it works or not and worry about the embarrassment of having a colleague find an error.
Robust change validation does just that — it allows developers to spot potential errors before the application or update leaves the local environment. Validating changes involves not only testing that the code is good, but also that it works as expected with all dependencies. When a change isn’t validated, the developer knows immediately and can fix the problem and try again immediately. And when a change is validated, the developer can push the code into the production-like environment with confidence, knowing that it’s been tested against upstream and downstream dependencies and won’t cause anything to break unexpectedly.
The idea is that as much hardening as possible happens in the development environment so that developers can ship with maximum confidence. As the code moves from development to production-like, it goes through a change validation tool that can ensure it works with all dependencies before it goes into the next stage.
What Happens in the Production-Like Environment?
Once we’re in the production-like stage, that’s the time to make sure all environmental factors and configurations have been verified and everything integrates appropriately with dependencies.
In an ideal world, the service should be treated as a first-class citizen in the production-like environment. This isn’t how most continuous integration works currently. By the production-like phase, the focus needs to be on how requests are moving between services and how interactions are managed, not just whether or not the code is solid.
Reducing the distance between development and production is a way to simultaneously improve development velocity and reduce change failure rates. Moving to a three-stage software development lifecycle does just that. It also has the added benefit of giving developers more control over the testing and hardening of their services, giving them more confidence to ship.
Feature image via Pixabay.