2 ms·
> The trouble with TDD is that quite often we don't really know how our programs are going to work when we start writing them, and often make design choices ite
by eyelidlessness 4y ago
> The trouble with TDD is that quite often we don't really know how our programs are going to work when we start writing them, and often make design choices iteratively as we start to realize how our software should behave.
This is a trouble I often see expressed about static types. And it’s an intuition I shared before embracing both. Thing is, embracing both helped me overcome the trouble in most cases.
- If I have a type interface, there I have the shape of the definition up front. It’s already beginning to help verify the approach that’ll form within that shape.
- Each time I write a failing test, there I have begun to define the expected behavior. Combined with types, this also helps verify that the interface is appropriate, as the article discusses, though not in terms of types. My point is that it’s also verifying the initial definition.
Combined, types and tests are (at least a substantial part of) the definition. Writing them up front is an act of defining the software up front.
I’m not saying this works for everyone or for every use case. I find it works well for me in the majority of cases, and that the exception tends to be when integrating with systems I don’t fully understand and which subset of their APIs are appropriate for my solution. Even so writing tests (and even sometimes types for those systems, though this is mostly a thing in gradually typed languages) often helps lead me to that clarity. Again, it helps me define up front.
All of this, for what it’s worth, is why I also find the semantics of BDD helpful: they’re explicit about tests being a spec.