Archive for May, 2008

Automated testing and bravery

Thursday, May 1st, 2008

Back in a previous part of my career I spent a lot of time engineering systems that did a very important but mostly dull thing for companies: processing their credit card transactions, enabling their revenue. If there’s one thing companies really care about it has to be getting paid.

We had heaps of code that made that work and we built out new features regularly.

I think we did a pretty good job and our transaction systems had really great uptime. Not only that but we delivered our software to requirements and on time.

Requirements, though, often took quite a long time to work their way through the product development pipeline to the point where we could get started on the engineering part of the process. Couple that lag with a QA department that was probably a little light on the ground and we had an interesting problem.

Engineers sitting about with a little too little to do and no way to roll changes out without the aegis of a full project to work under because there was too little QA to see our changes safely through into production. Push and pray was certainly out the question with something as mission critical as credit card processing. So what does that mean? It means that the cards were stacked against engineers using the downtime between projects to actively refactor or improve the codebase. That meant that we’d bite off little mouthfuls of improvement while doing project work but it mostly meant we learned to live with a cumbersome codebase. Frustrating.

Yesterday I spent a couple of hours adding some more automated testing to the small project I’m working on the moment: http://whenshouldwe.com. Even such a small application was already suffering a little bit of code rot from a few chops and changes in direction Rory and I had made while getting to grips with the nitty gritty of working with Rails’ RESTful architecture (a real conceptual shift from action based web-MVC). I wanted to cut out that rot and make a couple of other refactorings but I didn’t want to break anything and esp. with a dynamic language like Ruby there’s no way to tell what’s broken until you run the code.

By adding a few more functional tests and wrapping up the happy path in an integration test I was able to give myself a lot of confidence that any changes I made would not break what I had out on the site already. I was able to hack away dead, unused, code safe in the knowledge that while my test suite kept passing I probably hadn’t done anything wrong. With a really good test suite (see rcov) and a source code management system you can make improvements with abandon.

Tests like these would have been tremendously useful at my previous employer, sadly I wasn’t introduced to TDD and automated testing until a couple of years ago. The tests are a safety net, they remove the need for courage, bravery, caution, concern and just let you get on with writing and improving code quickly and confidently.