Stop writing imaginary code.
Hello. My name is Keith, and I have an addiction to moleskines.
I can’t help myself. Every time I walk by a display of them, I have to force myself to walk away before I start thinking of all those wonderfully blank pages just waiting for someone to fill them up with imaginings, designs, pseudocode, ideas for pseudocode, thoughts on designs… My writing hand trembles just thinking about it. It doesn’t matter that I’ve already got several mostly-empty notebooks lying around waiting for some love. I’ve got no shortage of imaginary code floating around in my head, each project deserving of its own pristine field.
For much of my career, I followed what is probably going to be a familiar pattern for many developers. I’d start by thinking of the problem, then imagining the code I’d need to write to get to the solution. Then I’d start taking notes on the code that lived in my head, delving deeper into each mini-problem along the way.
Before long what started out as a relatively simple problem to solve had become a road littered with titanic obstructions, making the mental cost of even starting on the problem paralyzing. It was only when I brushed away everything I’d so carefully planned out and stopped worrying about the details that I was able to begin new projects.
How BDD changed all that.
By thinking in terms of the feature—how it should work, and what the workflow needs to look like—I’m able to take a step back and keep the big picture in mind (while still satisfying my desire to plan and write lots of notes in fancy moleskine notebooks!) But further than that, the step-by-step work of actually writing the code for a feature has become vastly simplified most of the time.
By writing the feature scenarios first, the tests will actually tell me what code to write next. ‘When I follow “New Something”’ becomes an error pointing to a missing path helper – oh yeah, I forgot to add that resource to my routes! ‘Then I should see “XXX”’ fails – oh right, we actually need to output information for the user to see it… When I stall out after an explosion of coding, wondering where to go next, my test is there, directing my efforts towards what actually needs to be done.
Tests tell the story.
There’s another important aspect of this style of development—making sure your functionality is fully documented in your tests. By doing the bare minimum and letting your tests tell you through failures what code needs to be written, you’re ensuring that when that code quits working because of that really awesome refactoring you just dreamed up, you’ll know about it in short order.
Its not a panacea, of course. If a broken test could tell you every single line of code that ever needed to be written we’d probably all be out of jobs. But by breaking away from the details before they matter and keeping imaginary code in my imagination, I’ve finally got a process that keeps me out of most of my ruts.