Listen to this post
Defects can either be prevented or detected.
Let’s say you write a method in C# that takes, as its parameter, one of the nine players on a baseball team.
If you decide to make that parameter an integer (1 is the pitcher, 2 is the catcher, and so forth), then the code will still compile if a number greater than 9, or less than 1, is passed into the method. You will have to take some action in the code if that happens: correct the data, throw an exception, something along those lines. This code would be written to “detect” the defect, and would be driven from a failing test in TDD.
On the other hand, we would not have to allow for the possibility that someone will pass a non-integer, like 1.5, into the method, because the compiler will not allow this. Anything the compiler, linker, IDE, etc. will not allow is considered a “prevented” defect.
In TDD, we do not write tests for prevented defects. But any defect that cannot be prevented must have a test or the test suite is incomplete. Ideally this would never happen, since all code is written to satisfy a test that is written first, but mistakes will happen.
Therefore, any defect that makes it into production is not considered a defect at all in TDD. It is a missing test. Figuring out the test you missed is job one.