I swear we tried. Really, really hard. Both at work and in our side projects, we embraced this whole “test driven development” thing in hopes of bathing in all its glory. But it really wasn’t until the last week or two that the process finally felt painless. Well, there was still a lot pain, but it was significantly less painful than before.
And I’ve been thinking a lot about why -- why is testing so damn hard when everyone swears by it? When not having specs elicits raised eyebrows and a judgmental smirk from even beginner coders? We don’t know how to use them, but we know we’re supposed to.
And I think one of the biggest reasons is simply the lack of domain knowledge on the app we’re building.
At a talk I gave, someone asked me if being artistic made being a developer any easier. And the truth is, it makes it so much more frustrating. My favorite part of drawing is shaping the picture in my mind. I may not know exactly what colors I’m going to use, or how much contrast there should be, but I know exactly how the drawing should feel, what tone it would have, and what tools I need to bring it to life. And that comes from knowing my domain.
As a new programmer building an app, especially if the app incorporates a new concept or problem or tool I haven’t encountered before, I can’t see the final picture of the app I’m building. I don’t have a clear sense for how the app should work, feel, react enough to write tests first -- because writing out the tests requires that knowledge.
When I talked this through with Scott, his response was matter-of-fact. “But you need to know that stuff to start coding anything anyway.”
But I think the key difference is that when I just start coding in a new domain, I’m also experimenting. I’m testing out different methods, seeing how they fit together, organizing the models in different ways until they make sense. And once I have a feel for my app, it becomes so much easier to write the specs. This is particularly true when my app includes external APIs, who’s functionality I don’t yet know.
And kinda by accident, that’s what we ended up doing.
We played with the Gibbon gem (which lets us use the Mailchimp API in our app) and built methods that confirmed our hypothesis on how we could use it. After building out the appropriate methods in our MailingList model, we had a very good feel for how it should work, what its limitations were, and what we wanted to do with it. Then, we commented everything out, and wrote the specs. We built the controllers and models based on the specs we wrote, using a BDD approach. And since we had a clear picture of how our app’s subscribe-to-mailing-list feature should work from the experimenting we had done beforehand, we were able to build our specs leveraging that context.
There was still a lot of learning around writing specs well enough that they confidently tested our app’s functionality, but with the domain we gained through experimenting, building the roadmap for our app was a lot less painful this time around.