Development Driven Development

Some time ago I waxed ecstatic over JUnit automated unit tests here, and I think the software community has gotten even more wild-eyed over automated tests in the meantime, with the latest buzz about Behavior Driven Development. For my part, lately I’ve begun to question all this conventional wisdom. I’ve begun to believe that the fact that programmers love testing so much for the same reason Twitter is so popular: writing short little works is more fun than reading something long and difficult.

You see, MY test case is elegant and concise, whereas YOUR legacy code is convoluted and difficult.

Don’t get me wrong. My legacy code is convoluted and difficult, too, but it’s a lot more convoluted and difficult for you than it is for me, because I wrote it, and I have a better than even chance of knowing where the tasty bits are and what I was thinking. Your code is sometimes worse than mine, and sometimes better, but either way I don’t know it as well as my code until I start grepping and reading and stepping through it in the debugger. After a while doing that, I become more proficient in your code, but it’s still YOUR code.

During the day I make my living reading and fixing YOUR code. Well not yours exactly, but Other People’s Code. The particular compilation of Other People’s Code that pays my bills lately has been evolving since the 1980s, with very little in the way of automated testing. Yet my employers are selling the product and making enough revenue to hire me and a bunch of other guys to work on it. To be sure, it may be nearing the end of its life cycle, in which case I may need to find OTHER Other People’s code to go work on, but I guarantee you that in the meantime my wife doesn’t mind when she cooks dinner.

When I first got to this job I lamented the fact that there were no native automated unit tests. I wrote a few, but not nearly as many as I’d like, nor nearly as many as we need. QA has also been recently trying to add a lot more automation, though they’re written in the tool we’re developing — not the language I’m working in. More and more I just try to bite the bullet and debug and fix the problems that get logged by ad hoc testing against Other People’s Code, and I try not to let my overwhelming agile genius keep me from having a good time.

As a younger programmer than I am now, at my first true development job, my agile genius was at the height of his awesome career. As I was explaining some ingenious and difficult idea to my manager, he detected my agile genius at work. He rewarded my heroic efforts with the following response, which I offer up to you now as a Development Driven Development manifesto:

He said, “Just write the damned code.”

Just Write The Damned Code

I don’t think many developers are going to go for this as a way of doing business, because just writing the damned code is not really theoretical, and we developers love our theories. This sounds too much like chaos, and too many of us have suffered from chaos as a model of software development.

And do I really mean we should give up all testing, finish our edits and just do an svn commit without further ado? No, of course I mean that we should test our code, step through it in the debugger, examine it, review it, think about it, clean it up and the like. In fact, I submit that the compelling love of automated testing is precisely a reflection of the fact that while I’m an accomplished professional with a serious work ethic who always debugs and tests his code before checking it in, Other People as we all know are the dreaded perpetrators of Other People’s Code.

The sleight of hand here of course is that Other People are also the dreaded perpetrators of Other People’s Automated Tests. In my non-day job, rather than getting paid to work on a codebase that has no unit tests, I’m not paid (yet) to work on a project written in Ruby, where automated testing is “baked-right-in”. Of course, the tests that script/generate will spit out as a by-product of its work all pass, but more importantly, one of the Ruby third party gems I use heavily has sucked up more of its fair share of my time because its tests fail whenever I start running a new version of Ruby or make another change.

Am I just being ornery and jealous of my time that I don’t want to spend the happy part of my coding weekend updating tests that say that a user should end up on page X when they’re finished with some task, after I just explicitly made the change so they’d end up on a page Y? Really, we need tests to tell us what page people are going to now? Did we think they’d suddenly start hopping over to pets.com? And do I care that the string format of a DateTime object changed and now your tests are failing not because the dates are wrong but because of that incidental?

Test Driven Development works like this:

1) Write test case, color should be red.
2) Watch test case fail, color is not red.
3) Write code to make red.
4) Test case passes.

Development Driven Development works like this:

1) Write code to make red.
2) Verify red.

Yes, I’ve had cases where automated tests have alerted me to real bugs, so I don’t want to damn them out of hand. But I think a lot of the religious fervor surrounding unit testing boils down to something like this: “I don’t want to step through your code, and I haven’t yet created anything valuable enough that some other poor sap has to step through mine and I can get paid for it while being cursed as a fool.”

So I’m changing my goal, from writing unit tests for Other People’s Code to just debugging that code as best I can while writing my own code.

I’d rather be a hammer than a nail. As the great software engineer, Louis XIV, said, “Other People, C’est Moi!”

John Lockwood is a software developer who apparently doesn't work hard enough at the job he gets paid to work hard at, he has to also hang around here and write these tutorials. And by the way, THANK YOU to all those who've forked the tutorials on Github. Pull requests written around new articles would be kinda cool! (hint hint).

Posted in Miscellaneous
6 comments on “Development Driven Development
  1. I think we disagree about the purpose and the benefits of unit tests. My code (even if you threw out all the tests afterwards) is much cleaner when I write the tests first. The tests specify how I’m going to call into my code and what I expect back. This causes me to think about making the code it is calling readable and accessible. This is the design aspect of test first. You are essentially writing client code for your production code.

    This, then brings us to unit tests as documentation. How do I use your code and what does it do? Read the corresponding tests and you see how to call into the code and what you expect in return. If the test is failing then hopefully you are directed where to look in your code. As you unravel the failing tests you will write more tests that point to where the problem really is.

    This brings us to the protection part of unit tests. Unit tests help you when your head is down and you are thinking about one particular aspect of the code and you don’t notice that you’ve broken something else. The failing unit tests alert you to changes you’ve made that impact others.

    So can you write a single bit of code faster without unit tests? Perhaps. But as you see in your day job, code must be maintained and you are incurring greater costs in the maintenance phase by thinking you are saving little bits of time when writing it.

  2. Well, thanks for the comment. As you pointed out in your email my comments weren’t working, but because I like you so much I fixed them. No extra charge.

    I didn’t write a unit test for the fix either, by the way.

    Well, first of all, this is a friendly discussion I’m sure because I’m the first guy in more than twenty years of coding and probably well over 100 programmers to add ANY automated unit test in C / C++ to this C / C++ code base.

    Still, let me rebut a few points in light of what the industry has now learned about Development Driven Development from my brilliant essay.

    Regarding the design aspect of unit tests, your code may always be much cleaner if you write the tests first, because you’re a competent guy, but I always design my code before I start whether I write tests or not, because I use Development Driven Development. (Which by the way really is a magic bullet — made from recycled candy canes). I’m going to be calling this code and stepping through it in the debugger, so I don’t want it to suck.

    As for the documentation aspect of unit tests, the development driven development approach to that is “Just write the damned function (or class) header”. You understand what my code is supposed to do and how to use it because unlike the XP community, whose agile genius is supposed to shine through the sheer glory of their tests, I document my code.

    Last week I spent a day on code delivered by a team I used to work for, who are steeped in an XP-like approach. They balk at documentation and communication, so when they wanted to reverse the return values used to describe LONG VARCHAR and LONG VARBINARY, they may have tested it, but they didn’t tell us about it. Woops. It turns out testing and communication are different, and both important. Who knew?

    Finally, on to the protection aspect. Yes, you’re right, so if in the twenty years and 100 programmers besides me there were scads of unit tests covering every last DLL and COM server and class and #IFDEF’ed, cut-and-paste, legacy bat-turd, then I could keep my head down and work on one aspect of the code and the tests would help me. But surely your point is not that before I fix a bug I have to put in 100 man-years catching up on unit tests.

    Finally as to the fact that I’m incurring greater costs in the maintenance phase, that’s almost correct. Actually I’m reaping the benefit (in the form of salary) from the fact that my employer is incurring greater costs in the maintenance phase. But here’s the thing: because somewhere along the line Other People bit a bullet and wrote the damned code, there is a product to sell, and a company to sell it, and people are employed.

    To me, the choice is not between this software theory or that, but between having to work on someone else’s code and getting to work on mine. The highest goal of software is to allow you to dump the bosses off your back. As long as I’m not creating genuine marketable value in the world, then bosses and Other People’s Code are my natural rebuke.

  3. Daniel says:

    Debugger? That is definitely not how I want to spend my days.

    As for testing other people’s code … I mean this in a Michael Feathers testing legacy code sort of approach.

    XP is not anti documentation or communication. It is anti-stupid documentation. So a comment before this method

    (int) deposit( int x) {
    balance += x;
    return balance;
    }
    that says “The deposit method takes a single dollar amount as a float and adds it to your balance and returns your new balance” is stupid. The code tells me that. So XP doesn’t say in isolation don’t comment – it considers comments to be a code smell. If your code needs comments then maybe you aren’t writing small clear method/functions that do single testable tasks.

    Sure, other people doing it this way has worked well for you but it’s not good for the industry.

  4. Daniel says:

    It’s funny how my last comment made exactly the right point by accident. I looked back at my code and said uggh — we don’t pass money as floats. I changed my code and now the code and the comment are out of sync.

    Love serendipidity,

    D

  5. Now now, let’s not bait the Morlocks. Kent Beck and his band of serious men notwithstanding, there are thousands of professional developers who spend a lot of time in the debugger, to excellent effect both in learning their way through other people’s code and perfecting their own prior to inflicting it on other people.

    As for well documented code being a smell, well, by its own admission XP is opinionated. Every software team I’ve ever been on took documentation as a virtue, however, because every developer who’s been at his craft for awhile has run into cases where code should have been better documented than it was.

    If your code and your comments are out of sync, then according to the tenets of Development Driven Development, you should go fix them. Don’t jive me with your pair programming debris. Do your work.

  6. PMI ACP says:

    Is anyone on here going to take the PMI ACP Agile Exam?

1 Pings/Trackbacks for "Development Driven Development"
  1. [...] and connection strings for development and production and testing along the way using NUnit tests (Yes, Dan, NUnit Tests).  Once those were in place I began testing out the Plain Old CLR Objects and a [...]

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>