I discovered today that I’m not the same programmer I used to be.
Most of my time at work recently has been devoted to either team building or organizational change. Half of my team is away at training this week, however, and the rest are at our Wisconsin location working on uncovering what we need to do to get the next critical bit of functionality working. That means that I’ve needed to step in and pick up some of the programming slack. I’ve noticed that my approach to programming has been subtly and profoundly changed by my exposure to Agile/XP technical practices.
The task I’ve been working on is writing test code to support our porting work. We’ve got an OS abstraction library that most of our code is written to. In theory, all we need to do is port that library and most our code will work on a new operating system. Of course, we don’t have any tests for this library. So as we’re porting over each module, we’re writing tests so that we can make sure that it operates the same on both OSs.
One thing that’s obvious is how James Shore’s Let’s Play TDD screencasts have influenced my approach to writing unit tests. I’m not TDDing1 this code; I’m writing characterization tests to establish the current behavior. Still, it’s useful to pretend as though I’m implementing the code as I write the tests. I start by writing the simplest test I can, to verify the tiniest part of the functionality. I want as little time as possible between test runs, and developing the tests incrementally keeps me focused. I also write failing tests — by inserting test values that I know are wrong — to make sure that the tests are doing what I expect before I fix them and make them pass. And perhaps most importantly, I’m giving my test methods highly descriptive names that tell me what behavior they’re verifying. While testing an atomic increment function today, I noticed that it had a return value that I’d largely been ignoring. I had to look at the documentation to see what it returned. As a result Unit_Atomics::test_IncrementAddsOne() became Unit_Atomics::test_IncrementAddsOneAndReturnsOldValue(). Six months ago you wouldn’t have been able to read the header file for my tests and tell what the object I’m testing does.
There’s other stuff too, like my growing impatience with how long our build cycle is, and the slow realization that almost none of the things we call unit tests really are.2 But this is something where it’s not just my awareness that has changed, but my behavior as well. I’m excited to see what’s next.
1 That is, I’m not using Test-Driven Development.
2 Michael Feathers has one of the best descriptions I’ve seen.