DevOps is rooted in applying Agile principles to operations. It caught on like wildfire because developers were hitting a wall with respect to how early and how often they could deliver value. The wall was based partly in operations and partly in other areas of business.
The practice of automating operations is the love child of this mash-up between development and operations. Operations folks are writing automation scripts, and developers are writing operations code. It all works together to create a continuous flow of new features (read: added value) for consumers.
But if you aren’t doing unit testing, you are sure to hit another wall. Luckily, getting started with unit testing is actually quite easy. Yet there are many development shops that aren’t unit testing. A significant number of those are picking up some DevOps practices and using DevOps tools. But without unit testing, they’ll only ever achieve a modicum of the true spirit of DevOps. They’ll quickly hit a wall in terms of how short their delivery cycle can get. This limit has something like a sublinear curve. The limiting factor is the budget for headcount in the manual testing department.
This isn’t a bad thing, per se, since they are getting some benefit from the advances in tooling. But by not embracing the full culture of DevOps and adopting unit testing, these shops are missing out on some substantial benefits. See, DevOps is about more than just automation, tools, or practices IT performs in a bubble. To me, DevOps is a natural state of being. It’s a bit of a no-brainer. It also adds some much-needed accountability.
We’ll get into more of the strategic advantages of DevOps in another post. For now, I want to get back to focusing on how unit testing fits in with DevOps.
Unit Testing in the Value Stream
The DevOps process goes like this:
Plan > Create > Verify > Package > Release > Configure > Monitor > Repeat
Unit testing falls mainly into the create stage (plus some gray area with respect to verify).
During the create stage, developers make changes. While making these changes, they create unit tests. If they’re practicing TDD (test-driven development), they’ll write the unit tests before the code. Writing the tests first ensures two things:
- There are clear acceptance criteria for the change taking place.
- The code being written has a well-defined interface.
The former impacts the business as a whole and leads to overall improvement of quality and delivery. The latter improves the code by making it easier to understand, thereby improving quality. Both are important for practicing DevOps, since improving quality is one of its main goals.
Unit Testing in the Delivery Pipeline
You can’t think about DevOps without conjuring visions of continuous deployment. Continuous deployment isn’t just about automating deployment; it’s about automating testing, too. Unit testing often finds its place just after the build stage of the delivery pipeline.
Developers commit their code and push it to a code repository. This triggers a build. Once the build is complete, unit tests run on the compiled code to ensure the new code hasn’t broken the old code. If the unit tests don’t pass, the pipeline halts and the code isn’t deployed. It isn’t verified in later stages of the pipeline, either. You can try continuous deployment without unit tests, but the outlook won’t be so good.
You Don’t Want CI Without Unit Tests
Let’s take moment to think about what a CI environment would be like without unit tests.
Essentially, we would be operating under the assumption that each change we made didn’t break anything. Having made that assumption, we’d automatically push the build to the first environment. We might do some testing there…or not. If not, the build would make it all the way to QA before really being tested. This is the verify stage of the DevOps cycle I mentioned earlier.
During this stage, QA might run some automated tests. Or…they might not. They might find a bug. Or…they might not. The real trouble would arise if they didn’t find a looming bug just waiting to make its first appearance in production. That bug could cause some real problems for your customers.
Let’s be slightly optimistic and say QA did find the bug—sparing your customers the trouble. If the bug had been caught even earlier in the process, then it would’ve incurred a lower cost. It could’ve had been caught in the build process before it got deployed to the CI environment. In that case, it would’ve only cost you developer time. Now it’s going to cost (at the least) QA time, manager time, and developer time. It would have cost a lot less if all developers had run a comprehensive suite of unit tests after each change—or, at a minimum, before each push to the code repository. This would have kept things flowing smoothly with less need to loop back for bug fixes.
Unit testing winds up saving everyone more time in a continuous integration environment. Then, there’s the added benefit of built-in regression testing.
Curious how this continues? Stay tuned for the second part of our series.
Read the 2nd part here.