I think you get to the nub of it here. TDD lets you develop a spec that is consistent with requirements (the subset so far implemented) and the code at all times.
This is another TDD-related argument that I just don’t understand.
A specification might say that the function add returns the sum of its arguments.
A unit test might verify that add(1,1) = 2.
One of these describes the general case. One of them describes a single specific case. Unless your problem space is small enough to enumerate every possible set of inputs and the expected result for each of them, no amount of unit tests can replace a full specification of the required behaviour. Unfortunately, not many real world problems are that convenient.
This is another TDD-related argument that I just don’t understand.
A specification might say that the function add returns the sum of its arguments.
A unit test might verify that add(1,1) = 2.
One of these describes the general case. One of them describes a single specific case. Unless your problem space is small enough to enumerate every possible set of inputs and the expected result for each of them, no amount of unit tests can replace a full specification of the required behaviour. Unfortunately, not many real world problems are that convenient.