Interviewers often ask this question to SW engineers applying for a job.
Do you have experience with Test Driven Development?
I used to reply something like this:
Yes, I do. I think it's essential to write the tests before the code.
And even if my answer was shallow, the interviewers were pleased with it, and they would rarely go deeper with other questions on the topic.
My knowledge of Test Driven Development (TDD) was as shallow as my answer, and I was missing many essential details that make TDD effective.
Because of my lack of TDD experience, I used to take shortcuts and write tests after code, with all the drawbacks.
How TDD can help you to become a better developer
Some the advantages are:
- It makes explicit what you want to achieve.
- It keeps you focused.
- It Helps you to think about all the various scenarios.
After embracing TDD practices, I noticed a boost of confidence in my coding and my productivity.
The following is a typical mistake I made when I did not practice TDD.
When starting a new feature, I would jump on the keyboard writing the code to implement the solution in my mind.
I tried to see the feature coming alive as fast I could. And when I thought it was ready, I used to tell my teammates that the feature was complete, and it just needed to add a couple of tests.
That was rarely the case, and I often would overlook essential details, for instance:
- A scenario that I haven't initially thought of.
- Input that I did not consider.
- A state of the system that doesn't get along with specific input.
Sometimes a tiny overlooked case was hiding a mountain! Unplanned work that could take days to be completed.
What can you do in those situations where you've claimed the work is done, but it is NOT?
You put more effort and long hours to finish the job. So you get tired and take shortcuts.
Does it sound like a recipe for poor coding and bad code smells?
Yes, it is.
What was wrong with my approach?
It is very likely to get lost in the details of the implementation.
For example, let's say you want to develop a new feature. So you start to create a class with a specific responsibility, then add some collaborators to perform different duties, and then another one for that particular case, and so on until you'd get lost.
In other words, your brain could not keep up with all the implementation details. All those objects and methods used to solve the problem are just too cognitively demanding for the brain.
The TDD process helps describe the classes and methods and expand their functionalities step by step. It tames complexity progressively.
Tests are a form of documentation too, which clarifies the behaviour of your code - That is true even you write tests later.
It is easy to overlook scenarios and edge cases.
Because you need to keep in mind lots of details and focus on the happy path, you often don't consider specific scenarios.
Sometimes, I add comments and TODOs in the codebase, but still, without the TDD approach, it's not easy to keep track of all scenarios.
When you write a test before your code, you consider a particular scenario.
After you make it works, it is easy to create a new test and consider different inputs and expectations.
In other words, once you have your first test working, you can easily arrange and assert different scenarios of the behaviour under test.
A while ago, my TDD skills were weak. TDD is simple in principles but still requires quite a bit of practice and knowledge of the test doubles (Dummies, Stubs, Spies, Mocks and Fakes).
My thoughts about testing were similar to these:
Let's make it work now. I'll write tests later.
This feature will be simple, and I do not need any tests.
If I do not write tests, I can save time.
Those points are all misconceptions. First, even if you do not write tests from the start, you still need them. One day your code will need to change (new requirements, a refactor is needed, etc), and you'll want to be sure that it works as expected after the changes.
If you do not write tests - not even after your code - you will spend most of the time debugging and bug-fixing instead of adding new functionalities.
To wrap up
The test-first approach has enormous benefits. At first, it's not simple to fully embrace TDD, and it's easy to fall into the shortcuts of post-writing tests or even no-tests. However, if you practice TDD and stick with it, you'll enjoy the benefits.
Thanks for reading.
Updated on 09 Jan 2022