The past few weeks have been quite a lot of fun here in Boston. I gave a little talk on Git to some our training students, attended some fun Boston.rb events, hacked on some of Thoughtbot's open source projects, and tested a lot. Yeah, a lot. I think I've spent more time writing actual test code than real code in the past 2-3 weeks.
When testing first becomes a mode of development rather than a 'nice to have' or an afterthought, it's certainly jarring. So far it's been tough to learn and wrap my head around, but I believe in the long term the benefits are fantastic. I really do like the Red, Green, Refactor cycle, and being around some other awesome developers who are doing this daily helps immensely.
The process I've been going through in pair programming sessions and when I'm flying solo is usually this:
- Create a new feature branch in Git.
- Write out the Cucumber feature for whatever you're planning to do.
- From here, if you're not sure what to do, spike for a while and toss that away once you're done. (Time boxing is nice for this, but I think throwing the code away is more important.)
- If you find it necessary to write more than simple view or configuration code to make steps pass, drop down into functional/unit tests. Write a test, watch it fail.
- Make it green with the actual implementation, and only write enough code to make it pass.
- Back out to the acceptance test, if it still fails, back up to Step 3.
- Commit when you're in a good state, or at a decent break point.
- Try it out in the browser as a final test, then merge (or rebase and squash) your changes into the mainline.
- Make sure to at least run tests again before pushing your code up.
What's really awesome about this process is the amount of feedback that you get. From testing inputs/outputs of methods in models, giving good and bad data to individual controller actions, and out to integrating the entire stack with Cucumber steps, you get a great sense of how your code works and what it can withstand. Beware though, this feedback loop is addicting! I couldn't really imagine coding in a different way now that I've experienced this. I certainly wouldn't want to take a step backwards and not test anymore, but I am curious as for what's the next evolutionary step.
The biggest roadblock I've ran into so far is with mocking and stubbing. The technique as a whole is somewhat new to me, and although I see how much it helps especially with speed and isolation of tests in general, I do fear that I'm doing it wrong sometimes. Hopefully over the next few months I'll get some great experience with Mocha and maybe even RR.
If you've got a similar coding feedback cycle, or are trying to achieve one, let me know in the comments! I'd also be interested in hearing about other issues you've run into with TDD in general.