This piece of writing started as repost comment on LinkedIn responding to a question from J. B. Rainsberger about how people with an ADHD diagnosis experienced TDD. It's a good question, but it's the kind of topic I "own" enough that I don't want to leave my thoughts on it locked away on a platform like LinkedIn, so now they're here too!

This is an interesting one for me; I have both an ADHD diagnosis and I do feel that I use certain programming practices to compensate for it. Something that interests me enough that I'm talking on the subject at Lambda Days 2024, in fact.

Any practice that starts with building a feed back loop is going to be helpful from the ADHD point of view; for example, I have a strong preference for strongly typed languages because the compiler will remind me to finish bits I've forgotten about or catch the typos of concentration lapses in the wild.

That said, I'm personally not a huge fan of TDD as I've normally met it in the wild (I can see the one true Scotsman replies from here, and some of you are probably even right). And the reason for that dislike is also ADHD related but has nothing to do with the initial writing of the code - but with refactoring.

In the vast majority of cases I've seen, TDD has led to code bases with many, many, tests that are tightly coupled to the current implementation of a piece of code because what's actually happened is that each test has been written to confirm the next piece of the implementation is doing what is expected, not to test the overall inputs/outputs of the "block". Mocks that check they are called in a certain order or with certain inputs. Carefully crafted fake dependencies which return the data needed in the correct order and type to satisfy the internal of the function being tested. (Is this what TDD is meant to be? No, not at all - I'm aware)

This makes refactoring deeply painful with a pain that hits hard at the heart of ADHD - you're faced with the choice of updating all these painful, pointless, implementation internal specific mocks on the one hand or having the argument about why your refactoring PR "reduces test coverage" on the other. If you're particularly unlucky there aren't any tests covering the actual behaviour of the original code at all, and now you're left wondering:

"But is my refactor really a refactor at all?"

(It would be remiss of me not to note that teaching developers how to test behaviour and not implementations is actually a service I offer, partly because I don't want to live with the consequences of them not knowing! See my short term consulting page.)