This week saw my first major TDD project. It started off without a hitch. A slow grind for sure, but my mocking was superb (at least for a beginner). That is, until I finished testing my first class. I had tested everything but, being heads down in testing, I ended up in an architectural mess. Sure, my code was tested and worked, but it had no use case. What made things worse was that any more classes would require a circuitous route of dependencies that would never resolve.
So I was left with a question of what to do when "Red Green Refactor" wasn't enough.
Basic Red Green Refactor
In a traditional TDD cycle the idea is to write a test, watch it fail, write minimal code to make it pass, then repeat as you find edgecases. Through the process you also refactor, using the written tests to make sure you don't break your working code.
Here be Dragons
The problem with TDD is that it is heavily tied to Domain Driven Design. While it is over complicated in most places, DDD simply says that your software architecture mimics a physical process or object. In client work or at a large firm, the domain is likely layed out or somewhat understood. Unfortunately this was not the case with the project at hand. In juggling the ideas of grabbing and relating data from Twitter's 1.1 API (which brought much stress), Google's Geocode API, filesystem caching to reduce rate limiting, database storage, and more made me lost in the enchanted forest of TDD. I knew that something should have smelled by the time I had about 5 dependencies, two of which had to be renamed due to naming conflicts (Database Location vs Geocode Location).
I was proud of the code and the little green line, but one full day was lost and all I had to show was useless code and a green line with a few dots...
Explore the Wilderness
Like many developers before me, I strove for architectural purity but came out with something that looked like a monster from Star Trek The Original Series.
The problem was that I had not sent a red-shirt out in front of the full crew (I had to stick with the Star Trek theme, and couldn't think of a fairytale equivalent). What I mean is that sometimes to better understand your domain, you have to write really bad untested (and often untestable) code. The more structure you can give to this code, the better, but in reality, it is a shim. It is just a bit of a way to cut the fog of your domain down to manageable chunks.
Sometimes, this red-shirt may last to actual deployment, other times it may not make it through a full day before dying off and giving way to a test driven replacement. In my case, I have structured this prototype out in a way that I can fork the code, write my tests based on API names and the research I have found by throwing code into the wild.
I call this approach "Red-Shirt, Red, Green, Refactor" because you add the fast iterative prototype process before test driving in order to better learn your domain. Now, go and kill yourself a Gorn with just some rocks and a piece of bamboo.