One of the most common mistakes of newcomers into TDD is that they often mistake the “Fail first” requirement with “Fail by testing something illogical”. For example, given a method requirement with this spec:
Int Sum(int a, int b) : returns the sum of the two numbers
They would write a failing test like this
Public void Sum_AddsOneAndTwo()
int result = Sum(1,2);
Assert.AreEqual(4, result, “bad sum”);
While this might feel like a good way to make a failing test, it totally misses the idea of why we actually want to write a failing test. A failing test proves that there is something wrong with the production code. That is, the test should pass as is when the production code is fully done. As things stand with the test above – it is not logical and will fail even if the production code is complete. Making it pass requires changing the test itself – instead of making us change or add something to the production code. In short – this test does not reflect the end-reality like we would like it to be when the production code is complete, thus is not a good test.
On a more philosophical note
A good test in TDD will make us change the reality of the code to make it work, instead of reflecting the reality right now or reflecting a wrong reality (where 1+1 returns 0 just to fail the test).
We want the tests to reflect the reality like it should have been/we want it to be if the current requirement would have worked, then we make reality adjust to our needs.