Testing React apps with Jest and React testing library(RTL)

MVS KIRAN
5 min readFeb 16, 2023
Photo by Lautaro Andreani on Unsplash

Testing is critical for software engineering. It creates robust and high-quality software, enhances confidence in the codebase, and makes applications less prone to errors when introducing improvements and new features. In the end, It enhances product quality while lowering expenses and shortening development times.

Teams with complex codebases make testing a core practice in their everyday routines, and no feature is released before automated tests are in place and no PR will be approved without the proper test coverage. I was one of the victims. Some Developers even write test cases before writing the actual code, this process is called Test-driven development (TDD). It is also called red-green testing as all tests go from a red failed state to a green passed state.

Types of Tests:

Units Test: Basically a Unit Test is a method of testing small samples of code within an application. This can include functions that run code blocks or APIs that return data. The goal is to find out if the code is working properly and if it is catching any errors when they occur.

Integration Test: Integration Tests are pretty much just multiple Unit Tests grouped together.

End-to-End test(E2E): As its name denotes, End-End Tests are a way to test an application's frontend workflow. It is a method to test the whole application so that you know it’s going to behave the way you expect it to.
Common tools: Cypress, selenium, etc.

There are few libraries out there to test a react application. In this article, we’ll test React applications with Jest and React Testing Library, a popular combination of a JavaScript testing framework and a React utility for testing components.

Jest Vs React Testing library:

Jest is a test runner that finds tests, runs the tests, and determines whether the tests passed or failed. Additionally, Jest offers functions for test suites, test cases, and assertions.
React Testing Library provides virtual DOMs for testing React components.

sample test file app.test.js

Here, the test method which runs a test case is provided by Jest. For rendering and accessing the virtual DOM, we import and use both render and screen from React Testing Library.

Anatomy of test: test(name,fn,timeout)

The first argument is the test name used to identify the test.

The second argument is a function that contains expectations to test.

The third argument is timeout which is an optional argument. The default timeout is 5 seconds.

If you set up your React app from scratch, then you must install and set up Jest and React Testing Library yourself.
Follow this link to setup install the required libraries for testing https://youtu.be/9kPiq8-i-0M

Assertions and RTL queries :

Assertions: when writing tests, we often need to check whether a value meets a certain condition, Assertions decide if your test fails or passes.

Ex: From the above the snapshot,

expect(linkElement).toBeInDocument();

Using expect method we’re making an assertion to check whether the link element is present in the dom with toBeInDocument() as a matcher function. There are several assertions and jest matcher functions available,

Matcher functions: toBeInDocument(), toBeEqual(), not.toBeEqual() … etc
Follow this link https://github.com/testing-library/jest-dom

RTL queries: React testing library provides some of the query methods to access and find the elements on the page.

For Single elements on the page, we have

1. getByRole

2. getByLabelText

3. getByPlaceholderText

4.getByAltText

5. getByText

6.getByTitle

7. getByDisplayValue

8. getByTestId (for Custom elements )

To find the multiple elements on the page, we have

getAllByRole, getAllByValue … etc

Let's see some of the basic examples to testing react components:

Let's write the test cases with jest and RTL for the above component.

Let’s follow a pattern [ ARRANGE → ASSERT → ACT ]
Arrange:
Set up the conditions for your test. This might involve creating objects, setting up variables, or anything else that’s required for your test.

Act: This is where you actually execute the code that you are testing.

Assert: Verify that the code you’re testing behaves as expected. This might involve checking the value of a variable, or verifying that a certain method was called.

As you can observe above the component contains Display text that displays’s current amount value and is followed by an Input field, checkbox, and a submit and Inc Rupee button.

First, we will import render, and screen from react testing library (Pls Ignore other imports..)

The render method takes component to be tested as arguments and it provides the virtual dom to test the elements.

In order the access the elements on virtual dom, we will Screen the method with React testing queries [ Line no 14]. For the sake of example, I have used different styles to query elements on the page, one with a custom test match function and another with a passing second parameter (Refer to official docs for more info) style to query the unique element by providing the second parameter. I have come across this awesome chrome extension called Testing Playground where hovering over the elements on the page gives the respective query. (I have attached the link on the ref links section at the bottom)

Here we are asserting [Line no 31 to 37] that on the initial render, the page should render with the display and login status of the user followed by display value as ‘0' and the Input text field value should be empty, the checkbox should be unselected, the Input button should be disabled.

Now, We will test a scenario [ test while clicking on the Inc rupee button the display value should inc by 1 ]. Here, to stimulate the clicks, react testing library provides FireEvent and it also provides user-event by default. Currently, We will user-event library to test the interactions on the page.

First, We will initialize the user with the user.setup();
We will grab the button with RTL query and by using user.click() here will have used await and async because state update is in async fashion.

And last, with jest assertions using expect method we will assert with a matcher function toHaveTextContent(‘1’).

Conclusion: These are the basic test for demonstration purposes and there are some other methods to test like async func testing, snapshot testing, and testing mock data using MSW. I will try to cover these additional topics on another blog soon. Moreover, What to test is important while writing the test cases, I will cover that as well in an upcoming blog.

Useful Ref links:
Testing playground chrome extension, (life saver) https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano?hl=en

--

--