[LRUG] Dependency Injection and DHH

Tom Stuart tom at codon.com
Mon Apr 28 03:24:53 PDT 2014


On 28 Apr 2014, at 10:30, Gabe da Silveira <gabe at websaviour.com> wrote:
> I couldn't agree more that TDD/BDD do not lead to better designs—they lead to better tests, and good tests are just one metric of a good codebase.  Ruby, of course, requires good tests to have any reliability over time whatsoever, but we shouldn't forget that tests are still ancillary.  Being testable is only a small fraction of what makes a given architecture good.

This obscures an important point. DHH criticises “good tests” and “being testable” as meaningless goals; he characterises TDD practitioners as being fixated on testing qua testing, completely focused on testability and associated metrics (coverage, ratio, speed) in their own right, as if they blindly believe those things to have intrinsic value.

That’s inaccurate and unfair. Testability is useful precisely because it’s an effective, tangible proxy for other properties of software that are harder to anticipate or recognise: things like modularity, composability, reusability and so on.

Tests are useful on many levels, but at their most basic they provide a second client for your implementation, encouraging you to think harder about what each part of your software is doing and how it’s doing it. They give you an opportunity to step outside of your immediate goal and look at your software in a different way, from a different angle, with a different set of priorities. This gives you more visibility on the decisions you’re making, and that’s almost always worthwhile.

If it’s a nightmare to isolate a piece of your implementation in order to test it, what does that tell you? Directly: it’s not very “testable”. Indirectly: your design is perhaps a bit tangled up, and you probably could work harder to separate concerns and isolate dependencies and think carefully about how the pieces interact and what they individually mean, and it might be difficult to compose those pieces in different ways later. Would you have noticed those problems anyway? Probably, but going through the exercise of writing tests is one way of increasing the chances of noticing them sooner, while you still have a chance to do something about them before they become too baked-in.

So I disagree that “TDD/BDD do not lead to better designs” — in my experience they can, because they provide a simple, learnable, repeatable discipline that makes it more likely that you’ll notice design problems sooner. (There are other design benefits too, but I’m trying to focus on the least contentious one.)

Some programmers may be proficient enough at spotting these problems early that they don’t get any benefit from “testability”, and some may exert enough control over their software’s user-facing behaviour that they are able to dodge complexity at the requirements level, but for the rest of us it’s a useful litmus test for avoiding messy, knotted code. Being testable doesn’t make an architecture good, but good architectures tend to be easier to test.

I haven’t seen any sensible person say that TDD is a wholesale replacement for thinking about the design of your software, so it’s misleading to argue against that idea as if it’s representative. As you say: DHH’s goal isn’t nuanced discourse.

Cheers,
-Tom


More information about the Chat mailing list