How to Get TDD Under Your Skin
It may be hard to force yourself doing proper TDD (test-driven development). Particularly, if you spend a lot of time developing in an environment hostile to it or other agile practices. It appears that most of the time the biggest obstacle is yourself.
It is good to keep reminding yourself what TDD is, because it is quite easy to keep forgetting the basic steps you should follow (not just try to):
- Before you write any code, you must write a failing test for it.
- You must write just the smallest amount of code to make that test pass (often using ugly tricks).
- You clean/refactor the code to remove duplicity and improve design without changing behavior or adding functionality (also applies to tests), keeping all tests passing.
There are many positive effects of using TDD in a right way. Among the most useful are meaningful unit tests covering almost all of the code and highly decoupled code. But you can find about this all around the web (e.g. TDD on wiki); I want to focus on different aspects here.
The first thing to clear up is the persisting confusion about all the contradictory facts you can find about TDD "controversy". Some critique is based on common fallacies as straw man fallacy, argument from ignorance, appeal to authority, appeal to majority, etc. Those are relatively easy to identify. However, there are substantiated claims that appear to demote the usefulness of TDD. In these cases careful analysis what the critique is about is required. And it seems that the most important thing about these claims is a context for which they are applied.
There are very interesting talks about related issues that are worth seeing like Rich Hickey's Hammock Driven Development, or Dan North's Patterns of Effective Delivery that may seem to be partially TDD-discouraging. The pattern here is usually that those are indisputable experts (they mastered the subject above the level of common competence).
You can get to this level of expertise by different paths, but some are very difficult. You can decide to not use TDD at any time, but there seems to be enough evidence now that deciding that before you actually master it and can see all the implications would be very irresponsible at the very least. This decision does not usually affect only your future you but also other people that may want or need to use or touch your code. People are very bad at predicting the future. Moreover, people are very good in underestimating their inability of predicting the future. That means that what you think now about the future is mostly irrelevant.
My Bag of Tricks
One small thing I found very helpful is to have something reminding you about your good intentions you started with. The famous green wrisband works for me and there is a chance it may work for you as well. The important rule is: Wear it as often as possible and never write code that does not respect the best practices you know with the band on. It should feel shameful to take it off. To get it is easy, to deserve it — not so much.
As with any art or craft the most important is practice. However, not all variants of practice are equal. The one that is confirmed by many studies (a very readable one) to be the most important is deliberate practice. One of the increasingly popular form of deliberate practice is code katas.
Code katas (named after katas in karate) is a complete solution to a relatively simple problem mastered to a certain degree of perfection. The main goal is to master some parts of the process so that it becomes automated by your subconsciousness and your brainpower is free to be used for creative parts of the process (similarly to how touch typing can be automated to let you think about what you want to write). The important aspect is that you learn how the process should ideally look like, preventing bad habits from creeping in. One additional positive side effect is that you also improve your skills in using your text editor or IDE.
For TDD the code katas let you almost automatize the cycle of test, code, refactor. Not having this cycle automated it is quite difficult to follow it unless you keep focused on it all the time.
When Not To Use TDD
Short answer: You just should. And even if it seems you cannot, you should try to find a way.
Longer answer: When you are sure you know what you are doing.
There are common cases where TDD does not make much sense. For instance a GUI that does not do more than setting/reading some properties and calling methods may not be even possible to design using TDD. There are pieces of code (proofs of concepts) that you are certain will be thrown away soon, however, make sure they are thrown away. I already mentioned the "ability" to predict the future and there is quite a lot of code in use around that was not meant to survive.
Remember: Lack of good unit tests leads to potential chaos, chaos leads to anger, anger leads to hate. The hate of your future you can be quite frustrating, although just for your future you. The hate from your future colleagues can be even dangerous (the company/manager does not always pass as the target to blame)!
What language do you mainly code in? Can you provide us your favourite tools that help dealing with all the TDD hurdles?
The most important aspect for me regarding the tools is not just my convenience, but convenience of others as well. When you make it easy for others working on your code to test, they will more likely keep using it. So usually I go with the most common ones for a particular environment. Sometimes I do not have a choice.
The other very important thing is reduce the friction as much as possible. Running tests using just a hotkey or a mouse click makes quite a difference.
There is also a video of a code kata I did for bowling game counting using TDD, Clojure, and Vim I will be writing about (if you cannot wait until then: http://www.youtube.com/watch?v=2Y_x-hh38ME ).