Test driven development requires you to have a spec upfront.
When you already have a testable spec, test driven development seems to be a net positive. It can be a good way to explore the spec before building the implementation. At the same time, you shouldn't force yourself to write all of the tests up front; additional tests will typically occur to you as you build the implementation.
If you don't have external factors forcing a spec, I feel that test driven development is a net negative. Forcing a spec up front often requires making decisions before you fully understand the problem. Once you have tests, you have invested in the decisions and are less likely to reconsider them when encountering things that should have influenced the design. On a related note, most interfaces, particularly internal interfaces, should be influenced by the implementation to keep the implementation simple. Building a simple yet comprehensive solution typically requires a full understanding of the problem.
The point is to never test how it's working. Instead declare what it should be doing. If you can't declare ahead of time what it should be doing (maybe this is what you mean "how it is going to work") then you can't build it, can you?
Either you’re making a point that’s technically correct but missing the point, or you’re misinformed about how TDD works. TDD is an iterative process that generates tests and code at the same time, in very small (1-5 lines of code) bite-sized pieces. Although it could be argued that tests are specs, they don’t happen up front.
When you already have a testable spec, test driven development seems to be a net positive. It can be a good way to explore the spec before building the implementation. At the same time, you shouldn't force yourself to write all of the tests up front; additional tests will typically occur to you as you build the implementation.
If you don't have external factors forcing a spec, I feel that test driven development is a net negative. Forcing a spec up front often requires making decisions before you fully understand the problem. Once you have tests, you have invested in the decisions and are less likely to reconsider them when encountering things that should have influenced the design. On a related note, most interfaces, particularly internal interfaces, should be influenced by the implementation to keep the implementation simple. Building a simple yet comprehensive solution typically requires a full understanding of the problem.