I don't think TDD has a problem of local maxima. The code you write might, as you have correctly noticed, but that's why refactoring (rewriting code without changing functionality) is in place. Basically, as your tests increase, you can rewrite significant portions of your object model if you need to while keeping the behavior unchanged thanks to the tests. Tests state *invariant truths* about your system which, therefore, need to be valid both in local and absolute maxima. If you are interested in problems related to TDD I can mention three different ones that I often think about: 1. The *completeness* problem: how many tests are necessary to completely describe a system? Is "coding by example cases" a complete way to describe a system? 2. The *hardening* problem: whatever tests interface to, needs to have an unchangeable interface. Tests represent *invariant truths*, remember. Unfortunately these truths are not known at all for most of the code we write, at best only for external facing objects. 3. The *test damage* problem: in order to make assertions testable, we might need to write suboptimal code (less performant, for example). How do we write tests so the code is as good as it can be? --- Edited to address a comment: here's an example of excaping a local maximum for a "double" function via refactoring **Test 1:** when input is 0, return zero **Implementation:** function double(x) { return 0; // simplest possible code that passes tests } **Refactoring:** not needed **Test 2:** when input is 1, return 2 **Implementation:** function double(x) { return x==0?0:2; // local maximum } **Refactoring:** not needed **Test 3:** when input is 2, return 4 **Implementation:** function double(x) { return x==0?0:x==2?4:2; // needs refactoring } **Refactoring:** function double(x) { return x*2; // new maximum }