More tests, less comments
I tried to practice Test Driven Development (TDD) where possible during the past couple of months. One interesting thing I noticed is that the more tests I write, the less comments I put into my code. I think it’s because TDD forces me to think about the functionality I’d like to have in my system before implementing it. Without TDD, when I for instance have to implement a new method, I usually write the method’s comment first. While writing I think about the task of the method, it’s outcome, constraints and all these things. I may decide to split the method into two or not to implement it at all because it’s nonsense. All this happens before I write a single line of code (I don’t really consider comments as code). Hence the main purpose of comments is forcing me to think about the behavior of a code fragment before implementing it. As a side effect, the comments may help others who have to use or to modify the code. TDD does exactly the same thing. Before I implement a new method I first write a test. While writing the test I think about the method’s behavior much in the same way I did when writing comments. The test also helps others to understand what’s going on. Even better, it provides a sort of “executable documentation”. If someone changes the code, she or he can run the test to ensure that everything still behaves as expected (documented). Now, adding a comment to the code is like restating the test in another language. Thus it would be a violation to the DRY principle so I usually don’t add comments for things I have a test for.
Beside this, it’s more difficult to keep comments and code synchronized than tests and code. A test fails if you change the behavior of the tested code fragment. This forces you to either adjust the code or the test. But for comments, you have to check them manually and it’s too easy to let them slip. At the end, we have code with wrong comments which is quite worse, even more worse than having code without comments.
Interestingly, the testing aspect is “just” a side effect of the TDD approach (much in the same way as “documentation” is a side effect of writing comments). The main reason for writing a test is, as stated before, to justify the expected behavior of the code to be written. The term Test Driven Development is therefore a bit misleading. It’s more about behavior than testing. Therefore, the term Behavior Driven Development/Design fits better. Have a look at this blog entry from Elizabeth Keogh for an idea of what “test” stands for in TDD. There are many other interesting reads in this blog about TDD/BDD.