http://www.eternalis-software.com/images/tdd.jpg

TDD and Having Fun Coding

and how I finally managed to do both at once.

Travis Kaufman
wITh love
Published in
6 min readNov 18, 2013

--

At this summer’s GothamJS conference, two guys from Domo (Dave Gedes and Merrick Christensen) — during their talk — provided an excellent simile in regards to TDD, that went something like this:

Test-Driven Development is a lot like exercise: you don’t do it that often, but when you do it feels amazing!

This resonated particularly well with me, since I am somewhat of a TDD Fanatic (and I also love to work out), and I proceeded to use this analogy henceforth to preach the TDD gospel at every opportunity I could, vowing that every piece of code I ever make public will have tests associated with them.

Fast forward to a few nights ago. A coworker gives me a lovely idea for a git extension, and I decide that I’m going to go home and work on it that night as a fun thing to do. All day I’m partially distracted thinking about how much fun I’m going to have cooking up this seemingly simple git script when I get home. I race home at the strike of 6 O’clock, whip open my laptop, and start hacking some Ruby. But then I realize something…

Oh shit! I haven’t written any tests yet!

http://i0.kym-cdn.com/entries/icons/original/000/003/617/okayguy.jpg

And to my surprise, testing what I thought would be a very simple script proved to be quite non-trivial. Essentially, the script reverts a commit, pushes that reversion upstream, and then sends out an email to your team apologizing for the fact that you broke something.

Okay so…. where do I start with these tests? Should I test the email functionality first? How can I build out this functionality in a testable way? Maybe I should start with making sure it reverts commits? Start by mocking out the system command…but what will the system commands I’m using actually be? Do I even want to use system commands? How do I want to handle email authentication? How do I want to handle persisting that data? How am I going to test all these components which I‘m not even sure how will work yet? WHY DO I HAVE TO PUT THOUGHT INTO THE CODE I’M WRITING!!

http://i.imgur.com/xVyoSl.jpg

The (obvious) moral of the story was that I had clearly not put enough time or effort into fleshing out the inner workings of this module. But honestly, it was a fun project that I was just doing for kicks; why shouldn’t I just be allowed to let my imagination run free? Why should I have to be constrained by the limitations of specs and pre-meditated planning? I want to be able to just let my ideas fly from my mind into my text editor, leaving a trail of hacky code in my path, as if to pervert the ideologies I hold myself to when I write code during daylight hours.

The (obvious) answer is to that questions is multifold: 1) I would like people besides myself to actually use the script 2) I do not want to make maintaining this code moving forward a nightmare for me or anyone else, and 3) I do not want this code to poorly reflect on myself as an engineer. My code is my art; I take pride in my code as a jazz musician takes pride in a well-executed solo. As a dancer takes pride in a flawless performance. As a painter takes pride in the work before her canvas. I cannot be proud of any code I write, no matter how big or small, if I don’t feel that it’s done well. And in order to feel like it’s done well, it must be tested!

http://dalesheppard.com/blog/wp-content/uploads/2012/10/stalemate_2011-03-23-chronicle.jpg

Thus, I find myself at a mental stalemate. I want to be free to have fun and quickly hack my ideas into reality, but the OCD, TDD-preaching part of me will not allow this to happen.

But then I thought back to the exercise TDD simile I heard at GothamJS. One does not start immediately lifting weights before s/he even knows what her fitness goals are. And maybe an overarching fitness goal really isn’t that important to her yet. Maybe she just wants to test out the waters, or just feel refreshed or exhilarated from a good run. Everything doesn’t have to be so cut and dry, so this-then-that; maybe a smattering of activities and life events will help her figure out what she eventually wants to achieve, but she’s got to try it out to know for sure.

With this in mind, I simply began to write the script without any supporting tests. Eventually, I found myself doing the same thing over and over at the command line to test a specific piece of functionality. It was then I realized what I needed to write a test for, and thus I wrote one, and no longer had to break out pry every time I wanted to make sure I wasn’t breaking something. As I continued to write more of the module, I continued to catch myself hand-testing the code, in which case I stopped myself and just wrote a test. Before I knew it, all of the major functionality of the module was under test. Stalemate broken!

Somewhere in the depths of 4chan…

In being so adamant about TDD, I lost sight of the main reason I started this project: to have fun! It wasn’t worth me going home and banging my head against my desk for no reason at all, and unfortunately I let my professional practices bleed into my creative and artistic endeavors that I undertake outside the workplace, due to my job and my hobby being one in the same.

While I still stand by the notion that TDD makes your code better, self-documenting, well-structured, and not a nightmare to maintain, I have dropped the idea that — in personal, small projects — the tests have to be written before the code. Obviously, when you’re getting paid to write code, you take the time to sit down and intelligently architect the application you are developing. But sometimes you just want to be perverse and do the fun stuff first, eat desert before dinner, and if that’s not losing anyone any money than why the hell shouldn’t you be allowed to do so. Experiment and innovate first, but accept as an invariant the fact that you will do the diligence and write tests for the functionality of your code as you figure out what that functionality is. Now some TDD purists may say that this defeats the whole purpose of having the tests define the code (and not the other way around), but I challenge you to find any artist who hasn’t scribbled some shitty sketch on a notepad before taking to the canvas. Just because you don’t start out from nothing writing the tests doesn’t mean you still can’t drive development of the software forward with them. You just have to know when to draw the line between “it’s time to go back and do it right” and “I’m building on top of one huge hack.”

This philosophy allowed me to have fun while coding while also sating the TDD/OCD developer in me, hopefully it will do the same for you if you’re struggling with this problem!

--

--

Travis Kaufman
wITh love

Software engineer specializing in UI / UX development. Proud New Yorker, lifelong learner. ⚡️Gryffindor ⚡️