I appreciate TDD and think it indispensable but always write my tests ONLY after I write my source code then refactor accordingly. I can never bring myself to write the test first then the source to pass the test. So I always reverse the process. Is this a bad practice on my part? What are the disadvantages of doing it in reverse like me?
Is the design driven by the test considerations? If so, then testing drove the development. Which is what's supposed to happen.
Writing tests first absolutely assures that testing drove development. And it tends to limit refactoring.
If you want to write all the code first, then refactor, you're using testing to drive development (which is good). However, you're probable wasting time by writing all the code first only to refactor it all later (which isn't as good.) Using TDD will facilitate this; writing tests before code will also cut down on development time by saving some refactoring.
If you don't write your tests first then it's arguably not TDD. With TDD you normally write the test, watch it fail, then implement to make it pass.
The advantages over your workflow are:
- Your tests can fail! It's all too easy to create a test that simply cannot fail. And as Eric points out, if you don't write the test first, and watch it fail, how do you know the test is actually testing the functionality you just implemented?
- Your code is definately testable. Although I'm sure you follow testable techniques, test first development ensures that the code is definately testable as otherwise you wouldn't have written the code :-)
- Turns your solutions "upside-down". Debatable one this but TDD makes you think about "what you need" rather than "implementation details". By producing tests first you piece together your general architecture/class structure in your tests, then you get onto the implementation details.
You can mitigate the risks of all of those points, so it's down to you whether you want to keep going the way you are or switch to test first.
If you write the tests afterwards, do they really drive the development/design? I wouldn't think so.
To expand on Steven Robbins' answer: If your test does not fail before you make it pass, how do you know it is testing the right thing?
Thinking about your software design and coding accordingly followed closely by adding tests to make sure you didn't forget something is a good way to proceed in my book.
You think about your code from both a software design and from a testing standpoint. I tend to develop code and test in parrallel, never follow the 'write your test first' paradigm because it tends to result in code that fulfills your tests - not your design.
The risk in TDD is that de design phase is left out. If you build your tests trying to break your code in every way possible then fix the issues your test brings out you get stable code. I have had to refactor code that was written via TDD that was of prototype quality at best, it's not the method that delivers good code, it's the mental effort you put into it.