According to this answer to this question, a good reason for always starting with a failing test ("Red") is to make sure that the test is working and that the code that will be written is what makes the test passes. (my paraphrase)
Since it appears to me that the ability to write a test before any code has been written is a kind of mental acumen that not everyone can do (I can't), would it be sufficient if I write the code first, then write the test, then revert my code change to see that the test will fail without the code change?
Suppose that could be automated by some kind of IDE integration - would that be an alternate form of TDD?
In development environments in which TDD is enforced by the IDE/Framework, does strict mechanical rule enforcement limits developer's options for optimizations?
An example in which this might be useful:
Suppose the module and its unit tests have already been completed and are both working correctly. Now, I want to introduce a refactoring which would improve the performance by an unknown amount by reducing the number of internal function calls, without any fundamental change in the external behavior of the module.
Because I don't know how much benefits I would get from that refactoring, I can't write a test for that. But without a failing test, I'm not allowed to modify the code. This seems a chicken-and-egg problem.
If I am allowed to write a dummy test which simply captures the number of internal function calls in the old/new code, and then modify the code (in the name of "refactoring"), now I can update my test (if the refactoring is successful in reducing the number of internal calls) to assert that the number of internal calls should be reduced.
(Afterthought)
Although, this type of performance tests has a lesser importance than requirement unit tests:
- I would like to keep the benefit of the more efficient code if there is no change in functional requirement, and I do not want others to "refactor away" this benefit based on the assumption that no functional requirement would be broken.
- However, if there is a change in functional requirement, and if it's not possible to meet the current performance level, then the functional requirement should be met first. After that, a new performance target would be set from experimentation.
(Disclaimer: I have never done strict-TDD (and am skeptical of it), although I have been doing test-soon-after-coding for several months.)
More afterthoughts
- The code change in this question appear to be "post-TDD development", since it occurs well after all functional requirements had been met and all tests were in place. Therefore, as long as all of the original TDD unit tests continue to pass, this type of code change is considered "tuning".