Test-Driven Development (TDD) is not for Frontend developers
That's wrong, let me tell you how I do it.
Where to learn TDD?
Follow
if you want to learn everything about TDD.Introduction
I started out as a Frontend developer. When I learned how to write tests, I dug into TDD.
Looking into it, I didn’t think it was for Frontend developers. It felt complicated.
Back then, I had the wrong understanding of TDD.
TDD Recap
TDD is a development methodology that’s a complete package.
It consists of three steps in its cycle:
Writing a failing test.
Write production code.
Refactor.
It’s important to mention TDD is deeper than this.
One of the important things that many learn wrong is TDD is about taking small steps.
The struggles
Small steps
The first problem I had with TDD: I was taking too big steps.
I would try writing the entire test before diving into the production code. This is wrong. You take small steps when doing TDD.
You might go through the TDD cycle 10 times before finishing your task.
What will the UI look like?
The second struggle I had was not knowing what the UI would look like.
This problem is solved by taking smaller steps.
As you can see, they go hand in hand.
How I do TDD today
E2E with Cypress
I love E2E tests with Cypress. I use it in combination with Testing Library to write tests that focus on accessibility and the user’s perspective.
Sometimes, I don’t feel like starting out with a test because there is no UI in place.
I hit a block. There is no UI in place and I’m not entirely sure of the type of elements I will query with Cypress.
I go about this in two ways.
TDD from beginning
Doing TDD from the beginning.
Here I assume you have the UI designs. You should know what elements will be added to the page. If you don’t, it’s usually a lack of accessibility knowledge.
When I do TDD from the beginning, I start off by asserting the UI elements with their values that exist on the page.
The nice part here is when you get to the functionality part, you already know how to query all DOM elements in the Cypress tests.
Don’t feel bad about partial tests. It’s not expected that your tests will be completed from the beginning. You’re doing TDD. TDD is about taking small steps.
Even when writing your tests, don’t assert all UI elements at the same time.
Assert the UI elements that are reasonable to implement in one go. For example, start with the title and subtitle before asserting the form.
Now, it’s time for the second step of the cycle: write the production code.
Lastly, the third step of TDD: Refactoring!
TDD from functionality
I don’t have a strict approach. I either do TDD from the beginning or from functionality when writing E2E tests.
Many times I already know how the UI will be. It’s because of the existing code in the codebase and we’re not implementing anything new.
If I’m more productive coding up the UI needed before starting with functionality, I will do so.
When I get to the functionality part, I start with TDD.
When I say TDD, here is what I think:
Make a little progress on the test till it fails.
Implement the production code to make the test pass.
Refactor the code.
You don’t want to write a big piece of your test and then dive into the production code.
A rule of thumb is to not spend too long swimming in the production code. That’s what TDD prevents.
Unit with Vitest
This is standard TDD.
If I want to assert the output of a function, I write the test and then dive into implementing the function.
From my experience, TDD when writing functions and smaller pieces of code is straightforward.
Integration with Vitest (APIs)
At work, we build APIs. We use Express, TypeScript, Firebase and other technologies.
We write integration tests for these APIs. We can run them against the Firebase emulator. A simulated environment. We can make requests and the Firebase database will be populated.
Here I like to write the code for each case.
For example, if we expect an endpoint to return certain data when successful (200x responses), I will write the test for that case before diving into the production code.
We have strong consistency and great developer experience in our codebase responsible for the APIs. This works well and I don’t feel the need to take granular compared to when I’m writing the E2E Tests.
The dangers of dogmatism
The problem I had as a Junior was the dogmatic mindset.
I felt I had to go all in or not in whatever I did.
Bend TDD to work in your situation. It’s rare TDD won’t work for you.
Most of the Frontend developers that I know struggle with TDD:
Not taking small steps.
Lack of testing knowledge.
Lack of accessibility knowledge.
Test implementation details.
Conclusion
TDD is for all developers.
Don’t shy away from it.
If you notice gaps in your knowledge that stop you from doing TDD, fill those gaps!
Follow
if you want to learn everything about TDD.
Great article sharing how to do TDD right. Thanks, Tiger!
Awesome article Tiger, and thanks for the shoutout, appreciate it!