Monday, March 2, 2009

A story about 'getting it done'

I had a great time pairing for a day with Uncle Bob, getting a treeview integrated in FitNesse for navigating the pages. We were using the YUI Treeview widget, and ran into an interesting situation. I've related it to a couple people now, and the story always takes the same turn towards 'pragmatism', so I thought I would write it here.

Uncle Bob and I spent a bit of time spiking out the treeview integration, trying to understand what divs were required, how the dynamic loading worked, etc. Once we had a feel for it, we looked at each knowingly: we are at the point where we need to start having tests for this.

Neither Uncle Bob nor I had much experience unit testing javascript, much less test-driving it. I've done a lot of javascript in the past, but I've never taken the time to learn any of the testing frameworks (yes, horrible, gaping deficiency in my skillset, which I am working on improving through practice). Add to that the fact that I'm more familiar with Prototype than JQuery, and the situation gets even more complicated. As is the case, my first inclination is to go find a testing framework. I did a quick google search, saw QUnit was the jquery framework and decided to take a look at it. We set a timebox for investigation (I think it was 15 minutes) and started reading about it. Hmmm.... It seemed complicated enough that it was going to take us more than 15 minutes to get it set up for the first time and start using it. We got to the end of the spike with not much better of an understanding. Since I was only there for a day, we didn't want to spend it just trying to get a testing framework set up. We just wanted to get it done with a minimal of fuss.

This is the point in the story when everyone's ears perk up, since I'm always ranting about what you do when you have to 'get it done.' After all, this is the defining moment for your skills. What you do at this moment is fall back on your techniques. This is when I see a lot of people start throwing around 'pragmatism' to make excuses for themselves. For me, this is the moment when you look at the situation and figure out how to stick to your principles with what you have.

So, instead of just throwing our hands up and hacking away, we took a second to think about what we really needed. For our simple situation, all we really needed was assertEquals(). So, I wrote the following javascript function:

After all, the very basics of testing is checking that two things are the same. Now, there comes a time when you might need a slightly more robust situation (checking floats, for example), but we didn't have this requirement. This took me less than a minute to write. Then I wrote the supporting html:

So, as we wrote new tests, we added them to the list. We weren't able to run them all in a suite, instead having to refresh the page each time and click the next one. But, since what we were doing was fairly simple (we only ended up with 6 or 7 tests), this wasn't a huge problem.

The half hour that we spent investigating QUnit and then writing this small utility saved us much more time than that over the course of the day, as we were experimenting with features later on. And, yes, we even wrote tests for the AJAX calls (stubbing out the jquery ajax request).

Moral of the story? For me, this was a great example of what happens when you spend a little bit of time to dig into what your fundamental problem is and work towards that. Rather than make excuses for our deficiencies (lack of experience with a js testing framework), we figured out the simplest thing that we needed and ran with that. For us, the simplest thing was not just hacking away in an environment we weren't familiar with (jquery ajax stuff, yui treeview). In the end, we got the treeview integrated and working, exactly what our goal for the day was.

Figuring out the simplest thing that you need isn't a skill that comes for free, though; it takes practice.