Thoughts on Test Driven Development


Recently I've been to a workshop about Test Driven Development, held by Jason Gorman. I don't consider myself as an expert in TDD, but the concept has started becoming more familiar to me thanks to other developers I met during my career. This workshop definitely cleared my mind about some matters (matters that go beyond red-green-refactor cycle), which I'd like to share with you.

  • Tests should ALWAYS be valid: you're not allowed to change a passing test you already written while developing a feature. If you have to do this, it means that you didn't understand properly what your class should do at the beginning. Of course, it is appropriate to change tests when the requirements change, but that's another story.
  • Never refactor while a test is still failing: you haven't implemented your logic yet, and refactoring (still a great practice!) should be done only when you have passing tests as safety net (and yes, that also means IDE refactoring).
  • While writing a test, assert first: while writing a test, the first thing that should be written is the assert. This way, your test goal will be clear, and only needed given/when clauses will be written.
  • If you know your tests need collaborators, you can declare them: if you already discovered from earlier tests, or from requirements, that the class you're testing need to interact with some collaborators, you're allowed to define them (and define their behaviour while writing a specific test).
  • You don't need Big Up-Front Design, you just need enough: nobody said that design is a bad practice, although some agile practitioners may have said or believed that (including myself in the past). You should only design what's necessary (this article tells a story I pretty liked), and using a method such as Class Responsibility Collaboration cards you can identify the classes and interactions needed in your software. You can then use these classes and interactions to start writing tests.

Lastly (and most importantly), as all practices mastering test driven development takes time - a common myth is that by starting TDD all benefits brought by it will immediately be visible. While it will become natural for you to code in this way, test driven develpoment has got some kind of steep learning curve. At the beginning everything will seem more complex, and probably you will take more time to write your code than it would have taken without using this approach. However, your software will be simpler, more maintainable and more orthogonal. Plus, as your software will always be correct per requirements (but not bug free), the developers and the business will have more confidence on working/releasing without spending weeks on acceptance tests, significantly speeding up the delivery process.