Unlocking React Testing Library

What is the React Testing Library?

Quick Summary: This blog will highlight the React testing library, showcasing its importance in creating effective and reliable tests for React applications and helping you to ensure better software quality and user experience.

Introduction

React Testing Library builds on top of the DOM Testing Library. It is a small for React components. The RTL is an excellent tool for applications. With its utilities and methods, developers can write tests mimicking user interactions with React components.

These React testing libraries encourage a user-centric approach, focusing on the behavior and appearance of components from the end user’s perspective.

Collaborating with a trusted React js partner ensures reliable, efficient development and innovative solutions.

Here, we will cover the guide of react-testing-library and Jest, frameworks, exploring their core concepts, advantages, and how to test React JS Apps with React Library.

The closer your tests are to how your program is used, the more trust you’ll have in it.

Install

Creating React App projects provide support for the React Testing Library right out of the box.

If that isn’t the case, you can use npm to add it:

npm install --save-dev @testing-library/react

How does the react testing library work?

Instead of dealing with instances of rendered React components, your tests will deal with DOM elements.

The utilities provided by this package make it possible to query the DOM in the same way that a user would.

Finding form elements by their label text (like a user would), as well as links and buttons by their text (like a user would).

It also provides a recommended approach to discovering elements using a data-testid as an “escape hatch” for components with text content and labels that don’t make sense or aren’t practical.

An enzyme can be replaced by this library.

This library isn’t for you if you’re looking for:

  • A framework or test runner.
  • The library is specific to a testing framework (though it recommends Jest), but it works with any framework.

Methods for Finding Elements

Most of your React test cases should use methods for finding elements.

It provides you with several methods to find an element by specific attributes in addition to the getByText() method above:

  • getByText(): find the element by its textContent value
  • getByRole(): by its role attribute value
  • getByLabelText(): by its label attribute value
  • getByPlaceholderText(): by its placeholder attribute value
  • getByAltText(): by its alt attribute value
  • getByDisplayValue(): by its value attribute, usually for elements
  • getByTitle(): by its title attribute value

These methods are for getBy.

There are many other methods like findBy, queryBy, and getAllBy.

As we have these functions used in our for instance.

Example

Header.js

import React from 'react'
        import "./Header.css"
        
        export default function Header({
          title
         }) 
        {
          return (
            <>
                <h1 className="header" data-testid="header-1">{title}</h1>
            </>
          )
        }

Header.test.js

import { render, screen } from '@testing-library/react';
        import Header from "../Header";
        
        describe("Header", () => {
          it('should render same text passed into title prop', async () => {
            render(<Header title="My Header" />);
            const headingElement = screen.getByText(/my header/i);
            expect(headingElement).toBeInTheDocument();
          });
        })
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header"/>);
          const headingElement = screen.getByRole("heading");
          expect(headingElement).toBeInTheDocument(); 
        });
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header" />);
          const headingElement = screen.getByRole("heading", { name: "My Header" });
          expect(headingElement).toBeInTheDocument();
        });
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header" />);
          const headingElement = screen.getByTitle("Header");
          expect(headingElement).toBeInTheDocument();
        });
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header" />);
          const headingElement = screen.getByTestId("header-1");
          expect(headingElement).toBeInTheDocument();
        });
        
        //Find By
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header" />);
          const headingElement = await screen.findByText(/my header/i);
          expect(headingElement).toBeInTheDocument();
        });
        
        //QueryBy
        
        it('should render same text passed into title prop', async () => {
          render(<Header title="My Header" />);
          const headingElement = screen.queryByText(/dogs/i);
          expect(headingElement).not.toBeInTheDocument();
        });

Mocking function:

AddInput.js

import React, { useState } from 'react'
        import "./AddInput.css"
        import { v4 } from "uuid"
        
        function AddInput({ setTodos, todos}) {
        
        const [todo, setTodo] = useState("")
        
        const addTodo = () => {
          let updatedTodos = [
            ...todos,
            {
              id: v4(),
              task: todo,
              completed: false
            }
          ]
          setTodos(updatedTodos);
          setTodo("")
        }
        
        return (
          <div className="input-container">
            <input
              className="input"
              value={todo}
              onChange={(e) => setTodo(e.target.value)}
              placeholder="Add a new task here..."
            />
            <button
              className="add-btn"
              onClick={addTodo}
            >
              Add
             </button>
           </div>
          )
        }
        
        export default AddInput

AddInput.test.js

import { render, screen, fireEvent } from '@testing-library/react';
        import AddInput from "../AddInput";
        
        const mockedSetTodo=jest.fn();
        
        describe("AddInput", () => {
          it('should render input element', async () => {
            render(
              <AddInput
                todos={[]}
                setTodos={mockedSetTodo}
              />
            );
            const inputElement = screen.getByPlaceholderText(/Add a new task here.../i);
            expect(inputElement).toBeInTheDocument();
          });
        
        it('should be able to type into input', async () => {
          render(
            <AddInput
              todos={[]}
              setTodos={mockedSetTodo}
            />
          );
          const inputElement = screen.getByPlaceholderText(/Add a new task here.../i);
          fireEvent.change(inputElement, { target: { value: "Go Grocery Shopping" } });
          expect(inputElement.value).toBe("Go Grocery Shopping");
          });
        
        })

Conclusion

The React test framework empowers developers to write robust and user-centric tests for React applications. Its simplicity, focus on accessibility, and integration with best practices make it a valuable testing library tool for ensuring high-quality software development.

FAQ

The best react testing framework choice depends on your project’s requirements. Popular react test tools include Jest with React Testing Library, Enzyme, and Cypress for different types of testing (unit, integration, end-to-end).

React-native-testing-library and Jest serve different purposes in React testing. Testing library/React native is a testing utility for interacting with React components, while Jest is a testing framework that manages test suites, assertions, and mocks. RTL can be used alongside Jest for component testing.

A lightweight testing solution for React components is the React Testing Library. As a result, it enables better testing practices on top of react-dom and react-dom/test-utils.

With the Testing Library library family, you can perform testing without worrying about implementation details. It primarily allows users to find nodes by querying, similar to how they would do it manually. Using the testing library, you can be confident in your user interface code as a result of your tests.

React Testing Library is not a unit testing framework; it’s a utility for testing React components. It integrates with testing frameworks like Jest for comprehensive unit testing.