UPDATE: This post has been restructured and made into a video, you can view it here.
Here are five underplayed premises of TDD.
Why "underplayed"? Well, they’re there. Hardcore TDD’ers model them all the time. But it feels like they just don’t get the camera time. I want TDD coaches and teachers to step back from "what’s an assert" and rigid rule systems, and highlight these premises in their own work.
The money premise: we are in this for the money. That’s a funny way to say it, on purpose, but here’s what I mean.
I use TDD for one reason and one reason only: to move features faster. More faster features is my job. TDD does that. In particular, here are some substitute reasons to do TDD that aren’t nearly as spot-on. I don’t TDD for art. I don’t TDD for intellectual purity. I don’t TDD for morality or good citizenship, or even quality.
When I write tests, I do it because writing tests lets me make more features faster. That’s the only reason. When I don’t write them, it’s cause writing them — for some case — does not make more features faster.
The judgment premise: there’s no computable algorithm for rolling code well. Geeks doing TDD use individual human judgment, all the time. We use our judgment to decide when to write a test, or not. When to write a faster one, or not. How to ‘joint’ a problem testably, and so onflowcharts of TDD are training wheels at best. They leave out parts of what I do because they must — I’m a TDD’er, not a TDD algorithm. We are permanently, absolutely, irremediably, — and happily — dependent on your individual human judgment as a TDD’er.
The chain premise: the best way to test a chain is to test it link by link. This premise underlies our huge preference for testing very tiny subsystems of our larger app. If a function involves a chain of objects, A -> B -> C -> D, and we satisfy ourselves, Aworks if B works. B works if C works, and so on, we have come very close to satisfying ourselves that ABCD works.
I can hear the yabbits blowing in the warm spring breeze. Please read carefully: very close. Why is very close so good? Because single-link tests are orders of magnitude easier to read, scan, write, and run than larger-scale. And remember: I’m in this for the money. Those cycles I don’t spend reading et al large-scale tests are cycles I use to move more features.
The chain premise is about a preference, not a rule. I often test subsystems, or even through subsystems, but the chain premise pushes me towards the smallest and lightest subsystems that will prove the point.
The correlation premise: the internal quality of my code correlates directly with the productivity of my work. We could say a lot about external quality (EQ) vs internal, (IQ), but i’ll shorthand it here. EQ is things detectable by an end user. IQ is things detectable only by a programmer with the source.
The correlation premise is hard for some folks cuz they confuse those, EQ and IQ. Here’s the thing, you can trade EQ for more features faster. You can. If my customer doesn’t care if it’s slow, I’ll finish faster. If she doesn’t care that it’s ugly, I’ll finish faster, doesn’t care that the program’s rules don’t map perfectly onto the domain’s, same.
Consider the polynomial of my daily productivity. Two big terms are 1) my skill, and 2) the domain’s complexity. If I hold my skill and domain complexity, what’s the next biggest term, the one that dominates my production function? It’s the quality of the material I start with. This is the correlation premise doing its work.
Finally, the driving premise. Tests and testability are first-class participants in design. When we sketch designs, we consider many 1st-class factors. The two non-TDDer’s and noobs focus on: ‘will it work’ and ‘will it be fast’. But the driving premise says the third first-class question is ‘will it test’.
Tests & testability considerations shape our code. The biggest block I’ve seen in young’uns getting to TDD is their unwillingness to change designs to make them readily testable. The driving premise says we have to. There’s a tangent I’ll offer, maybe later today, on soft-TDD vs hard-TDD, but either way, we have to.
So those five premises underlay almost every move a TDD’er makes. And this is all pretty flavor-agnostic. It cuts across schools pretty well.
We’re in this for the money. We rely on human judgment. We tests chains link by link. We keep IQ high. We shape design w/testability.
My coaching and teaching friends, if you’re out there doing your thing today, please talk to folks about the premises you’re using. We absolutely have to get past this thing of creating faux-systems of rules, and in to transferring the heart of TDD.