Every software engineer has heard about Test Driven Development as described by Kent Beck, in which proper development is defined as always writing all your tests first and then writing a small chunk of code at a time to make one test pass after another. If you work in this world, don’t forget to feed your pet unicorn.
This pure version of TDD that people aspire to simply does not work in real life. So, that means we should not even bother, right? Wrong! I know you are coding applications that far exceed the complexity of Hello World. I know writing test-first with mock objects can be hard. I know those who do not code will never understand that proper unit tests actually require you to write more lines of code than that which actually goes to production. There are many reasons to say “TDD cannot be done” and just move on to implementing the feature you are tasked with. After you are done, if there is time, maybe you’ll write a handful of unit tests just to say you did it. The tests you write may help give you acceptable code coverage but little more. However there is one major reason to strive for TDD: you are care about writing quality code.
Take the short quiz below to see if you should be doing TDD:
- Do you like being assigned defects for code you have written?
- Can you leap over tall buildings in a single bound while using your phone to SSH into a production server to fix that performance problem that has been eluding the rest of your team for months?
- Are you a thrill seeker? Do you want to play russian roulette whenever you refactor your code? Maybe it will work maybe it won’t.
- Is every line of code you write a masterpiece?
- Do you commute into work riding a unicorn who walks on a rainbow bridge?
- Is there no chance your application/service will ever change or add functionality?
- Is the browser you are viewing this post on running on an operating system you wrote before you got your first zit?
- Do you not care at all about the code you write just as long as you get a paycheck?
- Do you have a crush on a member of your quality assurance team and are you looking for any excuse to speak to them?
- Are you unconcerned with writing quality code and doing a job well?
If you answered yes to two or more of these questions then there is no need to bother with TDD.
So, what is the answer if the pure textbook version of TDD is the stuff of legends? Instead, be true to the spirit of test driven development, implement a version that works for the feature you are developing, in the code base you are working with, and within the time allotted for development. Are you following a pure agile software development lifecycle? Of course you are not. You are using a version of agile that fits your team’s needs. It can be the same thing with TDD.
Forget Test Driven Development and start thinking Test Inspired Development. The first step in TDD is the most important: think about your tests first before writing any code. While writing all your tests first can take a lot of time, it does not take a huge time investment to write out all the use cases that your code should handle. Think about those edge cases. Think about the happy paths. Think about how your code should fail gracefully or blow up in the face of whoever is trying to abuse it. Think about how your design matches up with the requirements given to you. Writing all the use cases your code should handled and their expected results will get you thinking about the big picture and help you write robust, quality code.
Test Inspired Development does not have to end with writing out the uses cases for your code. If I am going to go through the exercise of writing out test cases, then I am going to write it out in the unit test class in which I will eventually implement the methods. Stub out your test cases and in the comments write out the scenario you are going to test and your expectations. This will ensure the effort you took to think of the uses cases for your code is not lost. When you start feeling more adventurous, actually code the assert statements in test cases that you have stubbed out. From here you are a stone’s throw away from coding your test cases prior to implementing the application code. Your test cases will basically write themselves and won’t require a major time investment after you are done writing the production code.