…besides the fact that they both give me headaches?
Clay Shirky may have succeeded in drawing a very bright line between the people who Get It and the people who don’t in the post-Internet media age. (Hint: Most television producers are on one side of the line; most four-year-olds are on the other.) This was the most fascinating goddamn thing I’ve read in 2008, and I am set on buying his new book.
This gets a little into the psychology of programming, at least as it applies to me.
Here’s why I’m a fan of Test Driven Development: When I’m adding a new feature – especially a new decision branch – and I’m not doing TDD, I will often only test the “happy path”. That is to say, I check what happens with the expected/normal inputs, and rationalize to myself that the change is small, and the likely error conditions are already handled. (Yes, I know. But if you’re reading this, chances are that you do it too.)
In contrast, when I’m doing TDD, I tend to triangulate compulsively, check boundary conditions, and generally dream up piles of test cases that would never come up if I were doing code-then-test rather than test-then-code. I suspect it has to do with the fact that writing an automated test at the beginning is far cheaper than spending my time clicking through every possible bad input in my UI, to say nothing of manually mocking up all the possible defects in a GET or POST request. I even find it kind of fun to spend a few minutes thinking up new edge cases for my code to handle gracefully.
And when I’m done, that code never gets deployed in a broken state again – at least for the paths I’ve tested.
As an example, consider putting your site through an invitation-only beta period. Perhaps you’re using something like Restful Authentication or some other prepackaged user signup & login code, and you have to add on the invitation validation process as a bag on the side. (In fact, you want to implement invitations as a separate model and code path so that you can easily cut it out later when the site opens to the public.) So you throw some extra code into the signup process to check a submitted invitation code, boot the user out if the code is invalid or used, and mark it as used if the signup is successful.
What if the signup is not successful, because the user put in a mismatched password and password confirmation? Does the invitation code get marked as used anyway, thus booting the user out and confusing him when he submits the form a second time with corrected input? That’s the kind of path that I often wouldn’t (and I’ll admit here: didn’t) think to test manually if I’m just coding away, but would take me 30 seconds to code a test case for when I’m working test-driven.
And that’s why I’m going to try to stay more disciplined about test-driving my development.
I had recommended Sitealizer (a Rails plugin) to a friend for monitoring stats on his website. Normally, I consider Sitealizer to be a pretty slick package – it has everything a smaller site needs (uniques, referrers, search terms, breakout by browser, etc.) and not a lot of cruft.
The downside: It appears that under certain conditions – like if you’ve used the standard deprec deploy (at least using the instructions at Slicehost), where Mongrel serves the app and Apache talks to the outside world – Sitealizer records all incoming IP addresses as 127.0.0.1. Not good.
And when the choice comes down to debugging the interaction of someone else’s code with arcane configuration issues or just going with Google Analytics? Sorry, Sitealizer..
So, it’s happened again – as with any of my interests, this blog has been through a fallow period and is back again, different, changed according to my interests and inclinations as they exist today.
If you’ve been a reader of this blog in the past, expect less personal material. If you’re here for the first time, expect lots of rumination about the craft of software development, nuts-and-bolts material on Ruby on Rails and Java, thoughts on personal productivity, links that amuse/interest me, and the rare rant.