Although I understand its mantra, I was never able to “drive the design” using TDD. To highlight my issues, let me share a recent failed experiment.
I have been trying to create a command line tool to categorise my expenses and show a total by category. I’ve been using this exercise to practice TDD.
In my latest frustrated attempt, my first test was along the lines of “it can categorise a single transaction correctly”. The problem with this is that this is testing the “tip of the iceberg” that will be almost the whole, final app. I think I was attempting a more “top down” design strategy here.
Before that one, I tried the opposite: a more “bottom up” approach. I know I need to, at least, read a CSV, parse a CSV row into some data structure and then categorise it. So I TDDed my way through to complete these “sub problems”. However, when I was about to apply the categorisation rules I realised that the data structure I created didn’t help, was just bad and didn’t work at all :).
So, how do you do it when you have a “larger project” (here, “larger” means something that’s not your typical “2/3 points user story” at work)? I always end up feeling stuck whether I try bottom-up or top-down.
Sometimes that's building a full app and getting it to market. Sometimes that's isolating a bug in a legacy system to a unit test. Sometimes its the compiler failing to build your code. Sometimes it's a data science problem, and it means training a model in a notebook, to measure its accuracy.
Don't get hung up on using one particular feedback loop.
Getting stuck in the wrong feedback loop is a big anti pattern of software development. When it takes forever to submit a job to some system, then takes 20 minutes to give you a type error in a scripting language, that could be caught by a linter or type checker sooner. Those 20 minutes easily turn into 60 minutes of distraction. Imagine instead you could catch this in 5 seconds with a test / linter / whatever. Then you'd resolve the issue in minutes. OTOH spending hours decomposing simple code into unit tests can be a waste of time, when the most value is submitting that simple code to a batch processing system, to see if it produces output...