Adventures in unit testing the Basecamp API

I’m working on a little side project, that I might open source once the code is less rough, which involves using the [Basecamp API](http://developer.37signals.com/basecamp/).

My package uses the [Python wrapper for the API](http://pypi.python.org/pypi/BasecampWrapper/0.1) and then does some naming convention magic to divine the number of [Sprints and Backlogs][scrum] and generally gives some other useful reporting info.

There are no tests for the wrapper, and I couldn’t sleep at night, let alone [develop software](http://en.wikipedia.org/wiki/Test-driven_development), without tests.

I started off just using the API and living with the fact that my test suite made network calls to a dummy project I setup in [Basecamp](http://www.basecamphq.com/).

But this morning I worked up a clever (I hope) solution — I subclassed the Python wrapper object and hooked up some methods that allow my [TestCase](http://docs.python.org/library/unittest.html#id1) to record any network transactions and serialize them down to a fixture file.

When a test is run again the serialized data is used, the network is untouched, and I am a happy camper.

**Update:** The code for the [TestBasecamp object](http://gist.github.com/60556) has been posted to [Gist](http://gist.github.com/60556)

**Update again:** The entire Basecamp API project, dubbed [BasecampReporting](http://github.com/cmheisel/basecampreporting/) has been posted to [GitHub](http://github.com/cmheisel/basecampreporting/)

The advantages were that:

* I didn’t have to write a complete, or even a partial, implementation of the Basecamp API in Python to provide mock responses
* As I keep going if I need data that hasn’t been serialized yet my test suite will pull it from the dummy project only once and then subsequent tests can use it

It’s probably not the ideal solution, but so far it’s seemed to work for me.

[scrum]: http://en.wikipedia.org/wiki/Test-driven_development

This entry was posted in Programming, Python. Bookmark the permalink.