- Change the code as usual
2. Write a test that only passes after the change
3. Revert to before 1
4. Type the test again (copy/paste is cheating & invalidates the warranty of the exercise)
5. Make it compile by changing the code
6. See it fail
7. Change the code to make it pass — Kent Beck (@KentBeck) July 30, 2021
I literally did this for one afternoon (back in 1999, I think) and began to feel the difference almost immediately. I also happened to like that feeling, even though there were moments where it felt strange: think, think, think, give up, write the production code, I see…, write the test, run it, see it pass, Hmm…, undo all of it, count to 10 (no, really!), now write the test…. I practised this for a few weeks (my manager seemed not to notice any drop in my productivity!) and the block that Kent describes in his tweet was mostly gone. This helped me build the habit of writing the test first.
The first change I noticed was in step 4: when I wrote the test, I sometimes noticed that I could write a simpler, smaller, more-direct, or clearer (somehow) test. This was the first “Aha!” for me.
The first big change I noticed was a change in how I thought about code. I thought more directly about inputs and desired outputs, rather than data structures and algorithms. I always managed to find suitable data structures and algorithms, anyway. I still do, even when I build them up impossibly incrementally.
As I became more comfortable thinking about code in terms of inputs and desired outputs, I stopped seeing only classes and started seeing interfaces. Previously, I hadn’t understood the value of interfaces at all, let alone how to use them effectively.
Within a few months, I began deeply to understand what I didn’t like about programming: being forced to know all these details about that thing over there when I merely wanted to use it. Gradually, I saw this weakness in my own designs as well as in others’ designs.
You can do it.