25 June 2012

Test-Driven Development as a Design and Learning Technique - Introduction


The company for whom I'm now working is a Ruby on Rails shop, and prior to starting with them I hadn't done much more than Hello World in Ruby and its equivalent in Rails.  So, once I started I decided to use TDD as an approach and tool for learning the Ruby language and Rails framework, as well as a driver for everything I needed from an environmental perspective.  I wouldn't add or start anything new until I had a concrete need in the form of a failing test!

One of the first things I did with the company was to run a TDD demonstration session using the Prime Factors kata, which required me to learn a little Ruby and test-unit, and I used a combination of text editor and the command line on my Mac.  I had already done that particular kata loads of times in Java with JUnit, so it was quite straightforward to implement using Ruby.  Did I write the best Ruby code for the exercise?  Perhaps not, but I'm sure over time I'll improve.

So, I was past Hello World, but now needed more.

My next step was to do something 'real'.  I use public transit to get to work, since it's actually quicker, cheaper and less stressful than driving to the location in which I work.  The local transit authority recently opened up a REST API for obtaining live information about bus trips for specific routes and stops, and it sounded like something interesting to play with that had some concrete value, so I dug in.

I had a vision of an application that could take a geographic location, find the nearest bus stops within a given range, and give me a list of bus arrivals at those stops.  Ultimately, the system would be driven from Android and iOS apps using the Location Services on the device to provide the current location of the user.  I also envisioned having the user be able to select favourite bus routes and stops in order to filter the list to show only the buses that were of interest to the user.  I'm sure someone else has already done something similar, but I wasn't trying to build a system for commercial purposes.  The idea here is to learn while creating something with a real world application!

Here's a high-level view of the system:

This system appealed to me because it was going to slice through many areas that were new for me.  I had to learn the Ruby language sufficiently to retrieve, process and push data to a client of some sort.  I also have done nothing beyond Hello World in Android, and nothing at all in iOS.  This system provided many dark corners in which I could shine a light, and get my hands dirty again in code!

Again, though, the whole philosophy I will follow is to take a TDD approach - nothing new added from a code, library, environment or tool perspective until required by a failing test!

Stay tuned for more about my first steps into this adventure!

4 June 2012

Stoop and Scoop

We have a dog... a big dog.  Hannah is a very active Golden Retriever who is programmed to be one of two states - on a walk or wanting to be on a walk.  She accepts swimming as an acceptable substitute for walking, but that's another story.  So, each and every day in practically any weather we take her out for her exercise.

Being a dog, Hannah isn't particularly fussy about where she, um, takes a bio-break.  Now, we could simply look the other way and pretend that we didn't see what just occurred but, again, she's a big dog.  Since we follow a couple of well-worn routes around our neighbourhood and in the park behind, the accumulation of doggy doo would be quite significant very quickly.  Add to that all the other dogs, large and small, in our area and you would have piles upon piles of... I think you get the picture.

So, being the good citizens that we are we stoop and scoop, cleaning up the mess right there on the spot.  We diligently take it back home in a plastic bag and toss it in the garbage.  Most of our neighbours do the same, and the area is the better for it.  There have even been times when we've cleaned up the mess from other dogs whose owner were not quite so diligent, all for the greater good of our neighbourhood.

Imagine for a moment that the code in which you work is your neighbourhood.  When you are adding new code or making changes, do you want to be stepping in all the crap that other dog... er, code owners have left?  Do you think they want to step in the crap you 'neglected' to see because you looked the other way when your dog decided to stop?

Of course not.

When you're writing code, do the equivalent of stoop and scoop.  Ask yourself if the code you're writing, be it production code or tests, is adding crap to the neighbourhood.  If it is, clean it up!  I'm OK with the idea of getting the code to work and then refactoring to improve the design, but I can say from experience as both a programmer and dog owner that the smaller the pile of crap you have to clean up, the easier it is on the senses.

For the 'how' part of cleaning up the code, Joshua Kerievsky's Refactoring to Patterns is an excellent place to start.  His company, Industrial Logic, also published a cheat sheet for Code Smells to Refactorings that is a very helpful starting point for identifying what's smelly about the code and patterns for how to remove the smell.  These are small, stoop and scoop steps that will help you to prevent the construction of a large pile of crap that does nothing but smell!

So remember, other people have to live in the same neighbourhood as you.  Be a good neighbour - stoop and scoop your code!

(Please note - any "this is a crappy blog post" comments will be summarily marked as spam! :)