How TDD Affects My Designs - The Code Whisperer

I find that practicing TDD leads me to write code that has (some of) the (widely advertised as) desirable characteristics of functional programming, even in languages where mutation of state is the normal thing. For example, going through complicated setting–up exercises to get an object into the right state to exhibit the behaviour I want to test for is a pain, so I tend to pass in state explicitly. And if I see that several methods take the same bundle of state I'll create a value object to hold them, and then I might end up giving that value object some behaviour thus discovering a useful new abstraction.

Asserting on the state of an object is more work than asserting on the return value of a method, so I tend to write more functions and fewer commands.

Code that talk to the outside world is harder to test than code that doesn't so I tend to both minimize it and move it all together around the outside of my code with a largely pure engine in the middle, as per “hexagonal architecture”

I find that practicing TDD makes it more natural to write good code because good code is easier to (write) test(s for). What I think is missing from a lot of discussions of whether or not TDD produces good design is an assessment of whether or not the programmer doing TDD knows what their “good” options are. If they don't, it might not help very much.