A Beginner’s Guide to Test-Driven Development (TDD) in React

Savan Chhayani
TechVerito
Published in
5 min readSep 4, 2024

Test-driven development (TDD) has become an essential approach in modern software engineering. It not only helps developers write cleaner code but also ensures that the application is well-tested from the start. In this guide, we’ll explore how to apply TDD in a React project using Jest and React Testing Library. By the end, you’ll see the benefits of adopting TDD in your development process.

What is Test-Driven Development (TDD)?

Test-Driven Development (TDD) is a software development methodology where tests are written before the actual code. The development cycle follows three phases: Red, Green, and Refactor.

  1. Red Phase: Write a test that defines a desired functionality or behaviour. Since the functionality hasn’t been implemented yet, the test will fail.
  2. Green Phase: Write just enough code to make the test pass.
  3. Refactor Phase: Clean up the code while ensuring all tests still pass.
        +----------------------+
| Write a failing test | (Red)
+----------------------+
|
v
+---------------------------+
| Write the minimum code | (Green)
| to pass the test |
+---------------------------+
|
v
+----------------------+
| Refactor the code | (Blue/Yellow)
+----------------------+
|
v
+----------------------+
| Start next test | (Loop back to Red)
+----------------------+

Why TDD Matters in Software Development

TDD provides several benefits:

  • Improved Code Quality: TDD enforces writing clean, modular, and bug-resistant code.
  • Fewer Bugs in Production: By writing tests upfront, you catch errors early in the development process.
  • Better Documentation: Tests can serve as documentation, showing how components should behave.
  • Ease of Refactoring: You can confidently refactor your code because you have tests in place to ensure that nothing breaks.

Setting Up the React TDD Environment

Installing Necessary Dependencies

Before we dive in, let’s set up our project with the necessary tools:

Project Setup Instructions

Ensure that your project is set up with Jest as the test runner (which is pre-configured in the Create React App). It also includes the React Testing Library, which focuses on testing the component’s behaviour from a user’s perspective.

Defining the Example UI Component

Introducing the UI Component: A Simple Counter

For this guide, we’ll build a simple counter application. The component will have buttons to increment and decrement the counter value.

User Requirements for the Component

  1. The counter should start at 0.
  2. The “Increment” button should increase the counter by 1.
  3. The “Decrement” button should decrease the counter by 1.
  4. The counter should never go below 0.

Writing the First Test (Red Phase)

Understanding the Red-Green-Refactor Cycle

In TDD, we begin by writing a test that fails. This drives the development by setting clear goals for the code we need to implement.

Writing a Test for the Initial State

Let’s write a test to ensure the counter starts at 0:

Counter.test.js

Here, we import render and screen from React Testing Library, render the Counter component, and check if the counter starts at 0.

If you run the test then you will see the following output:

npm run test

Implementing the UI Component (Green Phase)

Coding to Pass the Test

Now, let’s write the minimum code necessary to pass the test:

Counter.js

This simple component initializes the counter with a state of 0. When we run the test, it should pass.

Running the Test and Confirming it Passes

You can run the test using the following command:

npm run test

If everything is set up correctly, the test should pass, turning the phase from “Red” to “Green”.

Refactoring the Code

Reviewing the Code for Clarity and Maintainability: Since the code is simple, no major refactoring is needed at this step. However, ensure that the code is clean and adheres to best practices.

Writing Additional Tests

Adding Test Cases for Increment and Decrement Functionality

Next, let’s add tests for the increment and decrement functionality:

Counter.test.js

Testing for Edge Cases

To prevent the counter from going below 0, you can modify the decrement test and ensure it stops at 0:

Counter.test.js

Implementing Additional Features (Green Phase)

Updating the Counter Component to Handle Increment/Decrement Actions
Modify the Counter component to handle increment and decrement:

Counter.js

This ensures the counter can increment and won’t decrement below 0.

Notice that our decrement test is now failing because we’ve updated the counter logic to prevent the value from dropping below 0. Let’s update the test accordingly to reflect this change.

Ensuring All Tests Pass After Implementation

Run the tests again to confirm everything works correctly.

Conclusion

Test-driven development is a valuable technique for writing reliable, maintainable code. In this tutorial, we demonstrated TDD principles in React by building a simple counter-component. By focusing on writing tests first, you’ll find that your code quality improves, and refactoring becomes less risky. Start practising TDD in your projects and experience the benefits firsthand.

Happy coding ⌨️

--

--

Savan Chhayani
TechVerito

Senior Consultant At Techverito React | JavaScript | TypeScript | Kotlin | Spring Boot | Docker