How to use the react testing library debug method?

Use the debug method in React Testing Library to troubleshoot your components. Test on Real devices with BrowserStack.

Get Started free
How to use the react testing library debug method
Home Guide How to use the react testing library debug method?

How to use the react testing library debug method?

When writing tests with React Testing Library, it’s essential to understand the rendered output of the components. The debug() method is an efficient feature that helps to inspect the current DOM tree in your test environment.

Overview

What is React Testing Library?
React Testing Library is a lightweight tool for testing React components based on user interactions. It focuses on behavior rather than implementation, making tests more reliable and easier to maintain.

Core Methods in React Testing Library:

  • render(): Renders a component to the virtual DOM for testing and returns utility functions.
  • screen: Provides access to query methods without needing to destructure from render().
  • container: Gives direct access to the DOM for edge cases where standard queries aren’t enough.

Best Practices for React Testing Library Debugging:

  • Use screen.debug() to inspect the virtual DOM and spot missing elements.
  • Verify accessibility attributes like roles and labels for better queries.
  • Clean up debug logs after resolving issues to keep tests tidy.
  • Base tests on user-visible DOM, not component internals.

Read this guide to understand the React Testing Library through the debugging process, examples, and best practices to follow.

What is React Testing Library?

React Testing Library is a lightweight testing library built to test React components from the user’s perspective.

Instead of focusing on the internal implementation or component structure, the React Testing Library helps analyze how users interact with your application, such as clicking buttons, entering text, and reading visible content.

This helps create more robust and maintainable tests less prone to breakage from UI refactors or internal changes.

Core Methods in React Testing Library

Here are the core methods that need to be followed for writing effective and user-focused component tests:

1. render()

The render() method is used to render a React component into a virtual DOM for testing. It returns a set of functions that help you create queries and interact with the rendered output.

Syntax:

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

render(<MyComponent />);

Example:

const { getByText } = render(<Greeting name="Ayush" />);

expect(getByText('Hello, Ayush')).toBeInTheDocument();

2. screen()

The screen object is a globally accessible feature that provides access to all query functions. It eliminates the need to destructure queries from the render result and promotes more consistent test patterns.

Syntax:

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

render(<MyComponent />);

expect(screen.getByText('Welcome')).toBeInTheDocument();

3. container()

This is useful for inspecting the full DOM tree or using DOM APIs directly, though it’s recommended only when queries like getByRole or getByText aren’t sufficient.

Syntax:

const { container } = render(<MyComponent />);

expect(container.firstChild).toHaveClass('my-component');

How to add React Testing Library to React apps

Here are the steps to be followed for adding React Testing Library to React apps:

Step 1: Install Required Packages

To begin, install React Testing Library along with its dependencies:

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

For the Yarn users:

yarn add --dev @testing-library/react @testing-library/jest-dom

Step 2: Set Up Jest DOM in Your Test Environment

  1. If using Create React App, open src/setupTests.js (this file is auto-detected).
  2. Add the following line:
import '@testing-library/jest-dom';

Step 3: Create Your First Test File

Create a test file in a separate _tests_ folder.

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

import App from './App';



test('renders welcome message', () => {

  render(<App />);

  expect(screen.getByText(/welcome to react/i)).toBeInTheDocument();

});

Step 4: Run Your Tests

Use the built-in test command to run your test suite:

npm test

or

yarn test

Step 5: Add Testing Scripts to package.json (Optional)

For easier test execution, define a custom script:

"scripts": {

  "test": "react-scripts test",

  "test:watch": "react-scripts test --watchAll",

  "test:coverage": "react-scripts test --coverage"

}

How to use React Testing Library

Follow these steps to use React Testing Library to test a simple React component:

Step 1: A component called Greeting.js is created that displays a message based on user input.

import React, { useState } from 'react';



function Greeting() {

  const [name, setName] = useState('');

  return (

<div>

   <h1>Hello {name ? name : 'Guest'}</h1>

   <input

     type="text"

     placeholder="Enter your name"

     onChange={(e) => setName(e.target.value)}

   />

</div>

  );

}

export default Greeting;

Step 2: Write a Test Using React Testing Library

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

import Greeting from './Greeting';



test('renders default greeting and updates when user types', () => {

  render(<Greeting />);



  expect(screen.getByText(/Hello Guest/i)).toBeInTheDocument();



  fireEvent.change(screen.getByPlaceholderText(/enter your name/i), {

target: { value: 'Ayush' },

  });



  expect(screen.getByText(/Hello Ayush/i)).toBeInTheDocument();

});

Step 3: In the terminal, run:

npm test

What is React Testing Library Debug Method?

Think of the react testing library debug function in React Testing Library like a magnifying glass. When you’re testing your React component and you want to see exactly what’s being created or what it looks like, you use this react testing library debugging magnifying glass.

For instance, say you have a component that you’re testing:

const { debug } = render(<MyComponent />);

Here, render(<MyComponent />) is like drawing or creating your component on a piece of paper. Now, you want to see this drawing, right? That’s when you use your debug magnifying glass:

debug();

When you do this, it’s like the magnifying glass is showing you exactly what your drawing (or component) looks like in the terminal where you’re running your tests.

And the cool thing? You can use debug to look at specific parts of your drawing too. For instance, if you have a bit of text like ‘Hello’ in your component and you just want to look at that, you can do:

Here, getByText(‘Hello’) finds the ‘Hello’ text in your component (like pointing to it on your drawing), and then debug(helloText) lets you use the magnifying glass to look specifically at this ‘Hello’ text part of your component.

So, debug is a handy tool to visualize what’s going on when you’re testing your components. It’s like a helper showing you your test ‘drawings’.

const { getByText, debug } = render(<MyComponent />);
const helloText = getByText('Hello');
debug(helloText);

How to debug in react testing library using screen.debug() method?

screen.debug() prints the current state of the rendered DOM, which helps to visually inspect what your component is rendering and why a query might be failing.

1. Automatic Logging

This method logs the current DOM tree to the console. This can be inserted anywhere in the test code to visualize the component’s rendered HTML.

Syntax:

screen.debug();

Example:

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

import Greeting from './Greeting';



test('debug example', () => {

  render(<Greeting />);

  screen.debug();

});

Output:

<body>

  <div>

<h1>Hello Guest</h1>

<input placeholder="Enter your name" type="text" />

  </div>

</body>

2. Understanding screen.debug() Syntax

React Testing Library’s screen object provides the debug() method and comes with a few helpful parameters:

  • element: A specific DOM element or subtree to print.
  • maxLength: Limit the output length for readability.

3. Example Using screen.debug()

Check out this practical example using screen.debug() to identify an issue in the test:

Component:

function Greeting() {

  return (

<div>

   <h1>Hello Guest</h1>

   <button hidden>Hidden Button</button>

</div>

  );

}

Test Case:

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

import Greeting from './Greeting';



test('debugging a hidden element', () => {

  render(<Greeting />);
 

  const button = screen.queryByRole('button');
 

  screen.debug();



  expect(button).not.toBeVisible(); // This will fail unless you use queryByRole correctly

});

Output:

<body>

  <div>

<h1>Hello Guest</h1>

<button hidden="">Hidden Button</button>

  </div>

</body>

How to test a method in React Testing Library

Suppose you have a component called Counter that displays a count and has a method called incrementCount to increase the count when a button is clicked. Here’s how you can test it using React Testing Library:

Counter Component (Counter.js)

import React, { useState } from 'react';

function Counter() {
const [count, setCount] = useState(0);

const incrementCount = () => {
setCount(count + 1);
};

return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
}

export default Counter;

Counter Test (Counter.test.js)

import { render, fireEvent } from '@testing-library/react';
import Counter from './Counter';

test('counter increments the count', () => {
const { getByText } = render(<Counter />);

const button = getByText('Increment');
fireEvent.click(button);

const countElement = getByText('Count: 1');
expect(countElement).toBeInTheDocument();
});

In this test, you’re rendering the Counter component and finding the “Increment” button using getByText. Then, you simulate a user clicking the button using fireEvent.click. Finally, you find the element that displays the updated count and assert that it’s displaying the expected count.

By testing the component behavior through user interactions, you indirectly test the incrementCount method. You’re verifying that when the button is clicked, the count updates as expected. This approach focuses on testing the component from the user’s perspective rather than directly testing the method implementation.

This way, your tests are more robust and flexible, allowing you to make changes to the implementation details of the component without breaking the tests.

With BrowserStack, you can easily test your React apps across multiple browsers, devices, and operating systems, ensuring seamless compatibility and optimal user experience. One of the key products offered by BrowserStack App Live. It allows you to test your React mobile applications in real-time on real devices, ensuring accurate rendering and functionality across various screen sizes and platforms. You can access App Live.

Try BrowserStack App Live

Waiting for Appearance and Disappearance

To wait for element appearance or disappearance in React Testing Library, you can utilize various mechanisms provided by the library. These mechanisms allow you to wait for specific elements to appear or disappear before performing assertions in your tests. Here are a few approaches you can use:

1. findBy: Use findBy queries to wait for an element to appear. It returns a promise that resolves when the element is found or rejects if not found within the specified timeout.

const element = await screen.findByText('Hello');

2. waitFor: Utilize waitFor to wait until a condition is met. It repeatedly checks the condition until it resolves or reaches the specified timeout.

await waitFor(() => {
const element = screen.queryByText('Hello');
expect(element).toBeNull();
});

3. queryBy: Use queryBy queries to check for the absence of an element. It returns null if the element is not found, allowing conditional assertions based on its presence or absence.

const element = screen.queryByText('Hello');
expect(element).toBeNull();

These methods help you wait for element appearance or disappearance in React Testing Library tests, ensuring reliable and accurate testing of your components.

Testing for Appearance and Disappearance

Consider a scenario where you have a component called Notification that displays a notification message. Initially, the notification is not visible, but it appears when a button is clicked. After a few seconds, it automatically disappears.

import React, { useState, useEffect } from 'react';

function Notification() {
const [isVisible, setIsVisible] = useState(false);

useEffect(() => {
let timeout;

if (isVisible) {
timeout = setTimeout(() => {
setIsVisible(false);
}, 3000);
}

return () => {
clearTimeout(timeout);
};
}, [isVisible]);

return (
<div>
<button onClick={() => setIsVisible(true)}>Show Notification</button>
{isVisible && <p>Notification message</p>}
</div>
);
}

export default Notification;

Notification Test (Notification.test.js)

import { render, screen, fireEvent, waitForElementToBeRemoved } from '@testing-library/react';
import Notification from './Notification';

test('notification appears and disappears', async () => {
render(<Notification />);

const button = screen.getByText('Show Notification');
fireEvent.click(button);

const notification = screen.getByText('Notification message');
expect(notification).toBeInTheDocument();

await waitForElementToBeRemoved(() => screen.getByText('Notification message'));

expect(notification).not.toBeInTheDocument();
});

In this example, we’re testing the appearance and disappearance of the notification. First, we render the Notification component and click the ‘Show Notification‘ button. We then assert that the notification message appears in the DOM. We use waitForElementToBeRemoved to wait for the notification message to disappear from the DOM, and then we assert that it is no longer in the document.

By using these techniques, you can effectively test the appearance and disappearance of elements in your React components, providing confidence in the behavior and functionality of your application.

Pro-Tip: BrowserStack also provides parallel testing capabilities, allowing you to run multiple tests concurrently, significantly reducing your testing time. This helps you achieve faster time to market for your React applications. Learn more about parallel testing.

How to Debug specific component elements

You can debug specific component elements using React Testing Library as seen in the code below:

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

test('debug specific component elements', () => {
render(<YourComponent />);

const specificElement = screen.getByText('Specific Element');

screen.debug(specificElement);
});
  • In this example, when you run this test, you will render the YourComponent that you want to test.
  • Next, you will use getByText to select the specific element you want to debug based on its text content.
  • Finally, by using debug, you will print the debug information of the specific element. The debug output will provide you with valuable insights into the state and properties of that element.
  • By running this test, you will see the debug output in the testing console, which helps you understand and debug the selected component element during testing.

Using logRoles() for Debugging

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

test('create test logs using logRoles', () => {
render(<YourComponent />);

logRoles(screen.getByRole);
});
  • In this example, you import the necessary functions from React Testing Library. Then, you render the YourComponent that you want to test.
  • After rendering the component, you use the logRoles function, passing screen.getByRole as a parameter. This function generates test logs for the roles present in the component.
  • When you run this test, the logRoles function will generate test logs in the testing console, providing you with information about the roles and their accessibility within the component.
  • These logs can be useful for understanding the roles used in your component, ensuring proper accessibility, and assisting in documenting and validating the accessibility features of your application.

Debugging with logTestingPlaygroundURL() Method

logTestingPlaygroundURL() is a utility function from React Testing Library that logs a unique link to Testing Playground.

When the link is opened in a browser, it loads the current rendered DOM and highlights the best way to query your elements using getByRole, getByLabelText, etc.

Example:

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

import Greeting from './Greeting';



test('debug with testing playground', () => {

  render(<Greeting />);

  logTestingPlaygroundURL();

});

Output:

Open this URL in your browser:

https://testing-playground.com/#markup=...

Best Practices for React Library Debugging

Here are some of the best practices to be followed for React Library Debugging:

  • Use screen.debug() to Inspect the DOM: This method allows you to view the current virtual DOM output at any point in your test. It helps identify missing elements that may cause assertion failures.
  • Check for Accessibility Attributes: Use debugging to verify that elements have appropriate roles, labels, and accessible names for effective queries.
  • Keep Debug Output Temporary: Remove or comment out screen.debug() and other debug helpers once tests pass to keep test output clean and focused.
  • Update Tests Based on DOM, Not Implementation: Use debug tools for queries that reflect user behavior, not internal structure.

BrowserStack Live Banner

Testing on Real Device Cloud with BrowserStack

Instead of managing an in-house device lab, teams can instantly test their apps on real devices hosted in the cloud to ensure accuracy and speed.

BrowserStack Live helps in cross-browser testing by giving instant access to real mobile and desktop devices. It can also run manual tests or integrate with automation tools like Selenium, Cypress, or Playwright, helping in bug-free, responsive, and user-ready application testing.

Key Features of BrowserStack Live:

  • Real Device Testing: Instantly test on 3,500+ real devices and browsers, including the latest iPhones, Androids, Windows, and macOS machines.
  • Live Interactive Testing: Perform manual, live, and interactive testing sessions in real time to analyze real user experiences on various devices and browsers.
  • No Setup or Maintenance Required: Test directly on real devices in the cloud without the hassle of setting up or maintaining your device lab.
  • Secure and Private: BrowserStack Live offers strong security to protect your test data with encrypted connections and private session options.

Talk to an Expert

Conclusion

In conclusion, the React Testing Library (RTL) is a powerful tool for testing React applications. By focusing on user-centric testing and encouraging tests that resemble real user interactions, RTL helps ensure that your application functions as intended from the user’s perspective. Companies like Facebook and Airbnb have leveraged RTL to enhance the reliability and user experience of their projects.

By leveraging BrowserStack’s robust platform, React Developers can gain confidence in the quality and performance of their applications, leading to enhanced user satisfaction and increased productivity. Experience the benefits of BrowserStack’s comprehensive testing platform for React applications.

Try BrowserStack Now

Useful Resources for React

Tags
Cypress Website Testing

Get answers on our Discord Community

Join our Discord community to connect with others! Get your questions answered and stay informed.

Join Discord Community
Discord