HOT TIP: Ted Young’s "Make Your Code More Testable" class is coming up August 23rd. The class is excellent (and covers much of what I talk about below), Ted is a wonderful teacher – and I scored you a discount code. Go to MakeTestable.com and use code when you sign up to get $75 off!
Folks, I see a lot of ideas and opinions about TDD fly around, passed off as holy writ. By way of counter, I offer you Ten I-Statements About TDD.
By way of a reminder, there are lots more important things than geekery. If you enjoy what follows, please help folks keep working for change not just in the monitor, but outside it, too.
Black Lives Matter.
People get awful cranky. I’m people, too, and I get cranky. But I don’t think of it as one of my better aspects. Seems to me, we’d be better off taking a little more responsibility for ourselves as individuals. Here’s 10 I-statements about me and my TDD.
1) I practice TDD because it enables me to ship more value faster.
I do not practice it for reasons of morality, craftsmanship, patriotism, aesthetics, or intellectual purity.
It enables me to ship more value faster by providing me with greater confidence, consequence detection, rhythm, documentation, and collaboration, while requiring the same or less effort. It is more efficient for me.
2) I design all the time when I am TDD’ing, before, during, and after.
I rarely write tests I don’t have a pretty good idea how to pass.
Sometimes it’s the whiteboard, sometimes it’s a code sketch, sometimes it’s a meeting, sometimes it’s — my colleagues will attest to this — an entire novel in slack. Design design design, all the way through.
3) I push cod to head every time all the microtests are passing, except on those occasions when I’m so in the zone I’m going green-to-green in under a minute, usually near the end.
That means running the tests, usually all of the tests, every few minutes as I go. I have no ceremony for running the tests, just a hotkey. When they’re all green, I can and do push.
4) I alter my code fairly often for no other reason than to make it easier to TDD in and around.
Hard-to-write tests, or even tedious-to-write tests, are usually the Silicon Mother telling me my design needs work.
Most of the nightmarish tests I’ve had to write in my life were test-after tests, which is one of the reasons I regard TDD as so much more efficient. Designs that weren’t meant to be tested are often not very testable.
5) I avoid fakes — test-doubles, mocks, spys, auto-mocks, there are million words for a million flavors — in general, tho they’re occasionally unavoidable.
The techniques of hexagonal architecture have helped me with this a great deal.
In particular, I do not use mocking frameworks or library-specific testing supports, outside of temporary splints for legacy rescue. I find such things are meant to allow the kind of designs I do not value.
6) I do not write tests to prove that my whole application works, for me or for my customers, but to satisfy myself that all the parts I wrote that go into that applications do exactly what I wanted them to when I wrote them.
There are occasional exceptions, but the overwhelming majority of my tests are written against very small portions of my code, not the whole shebang. Combinatorics make large-scale tests very expensive and fragile, in my experience.
7) I also use my testkit to do a bunch of different things that aren’t properly "tests" at all, and I greatly value doing that.
Things I use the testkit for sometimes: to write probes for libraries I don’t understand; to formulate mad-sexy DSL to express something well; to see if my wild architectural idea will even compile; to demonstrate a coding concept for a junior. There are others, too.
8) I don’t like or value definition-wrangling, and I don’t care whether you call how I work TDD or not.
Probing the boundaries of ideas is great, axiomatizing natural language is boring, and often a form of browbeating.
That’s my prepared response to reply-guys. Since I’m an old guy with a rep, I get fewer than many of my talented and brilliant coleagues do, but I get enough to give fair warning. Don’t bother, with me.
9) I only have two "always/never" rules in my programming arsenal, including TDD.
Always suspect "always" and "never". Always put the cornbread on the bottom of the bowl and the bean soup on top.
It frustrates me greatly to see so many bright people come out with harsh declarations of what you must always or never do, generally in programming, and specifically in TDD. It’s judgement, folks, and it’s judgement all the way down. Build your judgement, then use it.
10) I have never seen even a single team in twenty years of coaching adopt effective TDD because they were made to.
I marvel at the number of organization who think this might even work a little bit.
Developers want less stress, tedium, and pressure, and to ship more value faster. They are perfectly willing to adopt TDD once they are given the experience and the mentoring they need to do it. In my experience, most harsh TDD critics never TDD’d, or TDD’d with lousy mentoring.
So there ya go. That’s 10 I-Statements about my TDD.
I hope you enjoyed them. If you’re not looking for a definition war, feel free to bring your questions, commentary, controversy, and QWAN.
Do you love the GeePaw Podcast?
If so, consider a monthly donation to help keep the content flowing. You can also subscribe for free to get weekly posts sent straight to your inbox. And to get more involved in the conversation, jump into the Camerata and start talking to other like-minded Change-Harvesters today.