16 Comments

Superb guide Daniel!

Expand full comment

Thanks my friend!

Expand full comment

The real benefit of TDD isn’t the tests but better design.

Writing tests first clarifies requirements, ensures modular code, prevents over-engineering, and builds confidence for refactoring.

The tests are just the safety net.

Simply put, Daniel.

Expand full comment

Could not agree more brother, TDD is testing, development and design tool!

Expand full comment

fantastic & concise guide, thanks - Daniel.

Expand full comment

Thank you too for the feedback, my friend!

Expand full comment

That's a solid roadmap for mastering TDD! 🔝

Expand full comment

Thank you Petar friend!

Expand full comment

Useful illustration regarding the TDD cycle! Yes, for learning TDD, it's best to practice on katas to learn concepts and get basic practice, and then we can try out the skills on Real Life Projects.

Expand full comment

Thank you Valentina! Katas are indeed the way, the good thing is that they are really short without much domain complexity, so we can focus on learning new skills.

Expand full comment

Exactly, the I find the complexity increases as follows:

1. Katas: lowest fidelity technical simulation, low domain complexity

2. Sandbox: high fidelity technical simulation, low-medium domain complexity

3. Read Life: the real thing, high domain complexity

That's why I'm focusing on writing TDD Sandbox guides within Optivem Journal, to help people learn TDD using a Sandbox Project https://journal.optivem.com/p/legacy-code-sandbox-project

Expand full comment

Nice!

Expand full comment

Very helpful thank you

Expand full comment

Nice post Daniel. I agree, TDD is an amazing productivity enhancer. I do favor BDD because it aligns more readily with delivered values but… same thing, mostly. 😁 Having been practicing TDD for upwards of 20 years now I can’t imagine how miserable my life would be without it!

I’m curious how much you encounter new practitioners running into a wall with TDD? I feel like it’s simple when done correctly… But it’s easy to overcomplicate. One of the biggest mistakes I see with new practitioners is trying to design all the tests upfront, and then facing a huge obstacle to getting anything running. Kent Beck started a conversation about it (summarized here: https://blog.bosslogic.com/p/everyone-does-tdd-wrong). I think the simple flowchart that emphasizes, “do one test at a time,” basically, is super critical.

If I could have my one wish granted, it would probably be that everyone follows TDD. Still very puzzled at how much resistance it gets in the day to day.

Expand full comment

Great guide - thanks Daniel!

Expand full comment

Great guide, thanks!

If I may offer a bit of feedback, a common pitfall I see otherwise great engineers fall into with TDD again and again is an unclear understanding of what a unit of code is. Could be valuable to call out what is a good level of abstraction to test at?

Testing every class / struct method by method and every function individually is usually not a good use of time and produces tests that are tightly coupled to the implementation and break often.

Sadly I don't have a small catch all definition of a unit... Like many things in our profession, it depends... I guess one could say the public interface is a good place to start for a unit of code. But this is still too granular in languages like Java, C# and much too coarse for languages like Go 🤔

I find myself gravitating towards points of combinatorial explosion as seams 🤔 Ex: In a simple strategy pattern, a strategy is often a unit, but testing all possible error and success scenarios through the dispatcher is pretty klunky. So I'd test each strategy, then test the dispatcher dispatches to the right strategy as a separate unit...

What do you think? Have you had to break up massive 500+ line unit tests in the past?

Expand full comment