Understanding Testing Library Jest DOM

Jest DOM is an extension of Jest testing framework. Learn to run Jest tests using custom matchers, & test React App using Jest with React testing library

Get Started free
Understanding Testing Library Jest DOM
Home Guide Understanding Testing Library Jest DOM

Understanding Testing Library Jest DOM

In your journey of testing web applications created using Javascript, you might decide to invest in testing frameworks, such as Jest, Cypress, etc. If you decide to go ahead with Jest as your testing framework, you can leverage the Jest DOM extension library to test the Document Object Model (DOM) in JavaScript applications, particularly web applications.

What is Jest DOM extension library

Jest DOM is an extension designed for the Jest testing framework. It enables Jest with specialized matchers for efficient testing and interaction with the Document Object Model (DOM) in JavaScript applications.

Jest DOM is an extension library for Jest that provides custom matchers to simplify testing DOM elements. It enhances Jest’s built-in assertions by offering more intuitive and readable queries, like toBeInTheDocument(), toHaveTextContent(), and toHaveClass(), making it easier to test web components and their behavior in a browser environment.

Features of Jest DOM

Some of the features of Jest DOM are:

  • Custom matchers: Jest DOM provides a range of custom matchers for enhanced assertions on the DOM elements, attributes, and content.
  • Simulate events: With Jest DOM you can simulate user interactions and events such as keyboard events, etc in your tests.
  • Testing async: For asynchronous operations, such as where you are waiting for elements to appear, etc, you can use the Jest DOM utilities.

Use Jest DOM matchers

With the @testing-library/jest-dom library, you can extend Jest with the set of custom matchers it provides. These matchers help write easy to read and maintain tests.

Let’s understand how to use custom matchers in your tests. We will use the .toExist() matcher to verify if the Login button exists on https://the-internet.herokuapp.com/login site.

Prerequisites of using Testing Library Jest DOM

Before you can start writing tests, you must set up your environment.

1. Setup directory and install Jest

  • In VScode, create a directory, named Jest.
  • Click Terminal > New Terminal.
  • Run the following command to initialize a node project.
npm init
Copied
  • Run the following command to install Jest.
npm install --save-dev jest
Copied

2. Install Puppeteer

We will be using Puppeteer to write our tests and Jest to run our tests. In the terminal, run the following command to install Puppeteer in our directory.

npm install puppeteer
Copied

3. Install the Jest DOM package

We will be using the custom matchers that the Jest DOM package extends to assert the existence of the Login button. In the terminal, run the following command to install the Jest DOM package.

npm install --save-dev @testing-library/jest-dom
Copied

Create and run the test using Jest DOM

Here are the steps to create and run test using Jest DOM

Step 1. In VScode, open the Jest directory.

Step 2. Create a custommatcher.test.js file in the directory.

Step 3. Add the following code to the file:

const puppeteer = require('puppeteer');


describe('Login Page Test', () => {

 let browser;

 let page;


 beforeAll(async () => {

   browser = await puppeteer.launch();

   page = await browser.newPage();

 });


 it('should visit the login page and verify the login button', async () => {

   await page.goto('https://the-internet.herokuapp.com/login');


   // Custom matcher to check if an element exists

   expect.extend({

     toExist: (received) => {

       const pass = received !== null;

       if (pass) {

         return {

           message: () => `Expected element not to exist, but it does.`,

           pass: true,

         };

       } else {

         return {

           message: () => `Expected element to exist, but it does not.`,

           pass: false,

         };

       }

     },

   });


   // Use Puppeteer to select the login button

   const loginButton = await page.$('#login > button');


   // Verify if the login button exists using the custom matcher

   expect(loginButton).toExist();


   // Take a screenshot for reference (optional)

   await page.screenshot({ path: 'login-page.png' });

 }, 10000); // Set a timeout of 10 seconds (adjust as needed)


 afterAll(async () => {

   await browser.close();

 });

});
Copied

Step 4. In your terminal, run the following command:

npm run test
Copied

The login-page.png file shows the login page with the Login button existing. In the code, the expect(loginButton).toExist() statement uses the matcher to check the assertion for the Login button to exist.

How To Test a React App with Jest and React Testing Library

The Jest with React testing library is often used for testing React apps because of the functions it provides to do user-centric testing. The tests are also readable and easy to maintain.

You can often use React Testing Library and Jest DOM together in your testing workflow, as they serve different but complementary purposes. React Testing Library helps you with user-focused integration testing, while Jest DOM provides useful matchers for DOM element assertions within those tests.

To understand how to use the React testing library to test your React app, let’s consider this scenario. We will be creating a simple React app that includes a Login button. We will create a test that checks whether the button exists using the .toBeInTheDocument() function.

Create a React App

Step 1 In VScode, create a directory, named custom-matchers.

Step 2 Click Terminal > New Terminal.

Step 3 Create a React project and create a new React app:

npx create-react-app my-react-app
Copied

Step 4 Change the directory to my-react-app:

cd my-react-app
Copied

Step 5 Create a helloworld.js file and add the following code that creates the sample app:

// src/HelloWorld.js

import React from 'react';

function HelloWorld() {

 // Function to handle the login button click

 const handleLogin = () => {

   alert('Login button clicked!');

   // You can add your login logic here

 };


 return (

   <div>

     <h1>Hello, World!</h1>

     <p>This is a simple React app.</p>

     <button onClick={handleLogin}>Login</button>

   </div>

 );

}

export default HelloWorld;
Copied

Step 6 Add the following code in the App.js file that adds the helloworld.js file as a dependency:


import HelloWorld from './helloworld';
….
Copied

Create the test using Jest

Step 1 In VSCode, from the navigation menu, expand the custom-matchers directory.

Step 2 Create the App.test.js file and add the following code. The App.test.js file tests whether the Login button exists using the .toBeInTheDocument() function:

import React from 'react';

import { render, screen } from '@testing-library/react';

import HelloWorld from './helloworld';


test('it renders a login button', async () => {

 render(<HelloWorld />);


 // Use React Testing Library's queryByText to find the login button

 const loginButton = screen.queryByText('Login');


 // Assert that the login button exists

 expect(loginButton).toBeInTheDocument();

 // const x= await page.screenshot({ path: 'login.png' });

});
Copied

Note: Jest and React testing library is installed as part of the command.

npx create-react-app
Copied

Run your test

Step 1 In VScode, click Terminal > New Terminal.

Step 2 Run the following command to run the test.

npm test
Copied

The following screenshot shows that the test passed and so did the assertions.

Test React App using Jest DOM and React Testing Library

Advantages and Limitations of using Jest DOM

Advantages of Jest DOM

Let us understand some of the advantages that Jest DOM provides:

  • DOM testing: DOM interactions are made easier with the custom matchers and utilities that Jest DOM provides.
  • Easy to read assertions: As Jest DOM custom matchers are easy to read and maintain, they are preferred when writing tests that involve DOM interactions.
  • Async testing: With asynchronous scenarios such as waiting for a DOM element, etc, Jest utilities are very useful.

Limitations of Jest DOM

Though Jest DOM has plenty of advantages, when making a decision, do consider the following disadvantages:

  • Needs Jest: If your tests are already written in some other testing framework, Jest DOM adoption might prove difficult.
  • Requires initial learning: If your developers are new to using testing libraries, adapting existing systems to use Jest DOM might slow down adoption.
  • Overuse: Because of the ease that the library provides, you might overuse the matchers leading to very tightly-coupled tests.

Best Practices for using Jest DOM

Here are some best practices for using Jest DOM:

  1. Use Semantic Queries: Prefer queries like getByRole, getByLabelText, or getByText over getByTestId to ensure tests are more maintainable and accessible.
  2. Write Readable Tests: Focus on clarity by keeping assertions simple and descriptive, ensuring tests are easy to understand.
  3. Use beforeEach and afterEach: Set up and clean up your test environment to prevent tests from interfering with each other.
  4. Mock External APIs: Use Jest’s mock functions to simulate API calls, ensuring that tests focus on the component rather than external dependencies.
  5. Test Accessibility: Always test for accessibility by checking if components are properly interactive and accessible for screen readers and keyboards.
  6. Avoid Over-Mocking: Mock only what’s necessary to prevent overly complex and brittle tests.
  7. Use screen for Queries: screen makes querying elements more flexible and accessible within the test suit

Conclusion

In this article, we learned how to use the Jest DOM library and the custom matchers that it provides. We also learnt how to use them with the React App and leverage the UI testing ease it offers. Though Jest is robust and offers ease of creating tests, it does limit the range of browsers and devices that you can test in real-time situations.

For stable testing, you must simulate real world devices and for that using a real device cloud, such as BrowserStack, is a great option. Access to multiple devices helps you predict and handle issues before your product reaches production.

Tags
Automation Testing Website Testing