This week, I tried a master mind coding exercise, two different ways.
Mastermind was a code breaking game from my childhood; each incorrect guess returns a hint, describing how close your guess was to the goal.
At the Boston Software Crafters meetup, our breakout room first attacked the problem of identifying all 5000+ codes (ten letters, but no repeats). Once we got that sorted, we then started working on implementing the filters we would need to eliminate candidates. And progress, though steady from that point, was slow - we had to think a lot about what the next guess might be.
Working the problem on my own the next day, I made two changes to my approach - I deliberately introduced an (untested) adapter between the game client and my more easily tested design, and then with that more easily tested design I started working with unreachable candidate lists.
By unreachable, what I mean is that there is no sequence of guesses that would eliminate all of the other possibilities and leave just the two samples that I had selected.
Although the samples were not reachable, they were easy to reason about. I could concentrate my attention on how the new logic should interact with these two data points, ignoring all of the other considerations as "out of scope".
In the end, my test suite included five assertions, never more than two lines of code per assertion. And yet, when I hooked it up to the "real" data, the system worked, right out of the gate.
@ScottWlaschin argues that it can be useful to choose designs that make illegal states unrepresentable; I don't disagree - but I think that some care is required in choosing an appropriate definition of "illegal". Some of the states that you won't encounter in a healthy system are still useful when trying to explore the properties of that system.