I’ve been working on my tutorial session for WindyCityRails (tickets still available…). The session is about how to test when you are working in a legacy app that doesn’t have tests.
Naturally, that requires some legacy code for the attendees to work with during the tutorial. My own worst Rails messes are either back in the 1.2.x time frame or I don’t have access to them any more. I don’t have the right to distribute legacy code that I have inherited, and most of those people wouldn’t want me calling their code a junkpile in public.
So I’ve been writing a faux-legacy application, or at least enough of one to make the needed points in the tutorial. The idea stumped me for a bit because the app needs to be both complex enough to plausibly show the issues in legacy testing and simple enough so that setup and changes can actually happen in a short workshop.
Eventually, I hit on the following guidelines for writing deliberately bad code:
- Aggressive corner cutting on features that aren’t essential to the presentation.
- Don’t look anything up and don’t use gems or plugins, not least of which to prevent setup issues.
- Make no effort to put things in the “right” place.
- Work quickly, without design and never go back to clean up a mess.
- Randomly, do something a little bit less elegantly than normal. Oh, and some metaprogrammy Ruby things were off limits, assuming I was writing as somebody who didn’t know Ruby that well.
And I think I got some nicely tangled code rather quickly.
At this point I think I’m supposed to say one of two things:
- Boy I sure was able to write that code fast without the pesky rules! I guess that TDD stuff isn’t that great after all.
- Boy, I sure wrote nasty code without those pesky rules! I guess that TDD stuff really is great after all.
I think I believe the second point more than the first. It’s hard to look at this code and not see some major pain coming in the future. That said, you have to acknowledge the emotional power of seeming to write fast code.
Because I did go pretty fast here, and I got a satisfying amount of app built in a relatively short number of hours with a very continuous novelty burst in my head from seeing new things in a browser.
The temptation to say, “I was deliberately writing ugly code. If I just stopped doing that, then boy, I could go really fast and not use TDD, I can control bugs without TDD.” And the thing is, that’ll be true for a while. Maybe a long time, if you’re pretty good and working by yourself.
This is related to the very seductive idea that your project doesn’t need to use Agile methods because you can control your changes up front. In both cases, you go quickly mostly by ignoring the inevitability of anything changing in the future (who cares how tangled the code is if nobody ever has to modify it…)
In the end, though, change is coming. So the trick to working in a legacy environment is taking code that was never written to allow change and making it more amenable to change.