Testing Library Jest Dom is a powerful tool for testing Next.js applications. It provides a set of utilities for rendering and testing components in isolation.
To get started, you'll need to install the required packages, including `@testing-library/jest-dom` and `@testing-library/react`. These packages provide the necessary tools for rendering and testing components.
The `render` function from `@testing-library/react` is used to render components in isolation. This function returns a container element that can be used to query the component's DOM.
You can use the `fireEvent` function to simulate user interactions, such as clicking a button. For example, `fireEvent.click(button)` will simulate a click on the button element.
Create Next.js App
To create a Next.js app, you can use the official Next.js documentation which provides a simple and straightforward guide.
First, make sure you have Node.js installed on your machine. Then, run the command `npx create-next-app my-app` in your terminal to create a new Next.js project.
You can also use a cheat sheet repo like Next.js + Jest + React Testing Library for a quick reference. This repo has a dedicated page for creating a Next.js app with Jest and React Testing Library.
Testing with Jest
Testing with Jest is a crucial part of ensuring your Next.js application is stable and reliable. You can configure eslint with Jest and React Testing Library by installing eslint plugins for jest and react-testing-library.
To write tests, create test files for your components, pages, or other units of code, and write tests to verify their behavior. This involves creating test files, which is a straightforward process.
For example, you can use a cheat sheet repo for Next.js + Jest + React Testing Library to get started. Note that you can check the official react testing library docs for a quick cheat sheet.
Here's a suggested order of priority when querying the DOM using React Testing Library:
- getByRole('button', { name: /click me/i })
- getByLabelText('First Name')
- getByPlaceholderText('Enter your first name')
- getByText('Click me')
- getByDisplayValue('John')
- getByAltText('Profile picture')
- getByTitle('Close')
- getByTestId('my-element')
Note that you should only use getByTestId as a last resort, and assign data-testid='my-element' to the element that you need to find.
Run Tests
After you've written your tests, it's time to run them to see if your code is working as expected.
Create test files for your components, pages, or other units of code, and write tests to verify their behavior. This is where you'll find out if your code is robust and reliable.
To run tests, Jest provides a simple command that you can execute in your terminal.
Write Tests
Writing tests is an essential part of the development process. It helps ensure that your code works as expected and catches any bugs or issues before they become a problem.
To start writing tests, you'll need to create test files for your components, pages, or other units of code. This is where the magic happens, and you get to verify the behavior of your code.
You can use Jest, a popular testing framework, to write your tests. It's a great tool that's widely used in the industry, and it integrates well with other tools like React Testing Library.
One thing to keep in mind is that you'll need to write tests before you can run them. It's a bit counterintuitive, but it's an important step in the testing process.
Here are some userEvent methods that you can use to simulate user interactions:
- userEvent.click(element) - click an element
- userEvent.hover(element) - hover over an element
- userEvent.unhover(element) - unhover over an element
- userEvent.type(element, text) - type text into an element
- userEvent.clear(element) - clear text from an input or textarea
- userEvent.selectOptions(element, values) - select options in a select element
- userEvent.upload(element, fileOrFiles) - upload a file or files to an element
- userEvent.tab() - tab to the next focusable element
- userEvent.keyboard(text) - type text using the keyboard
To write effective tests, you'll need to understand how to use the testing library's screen methods. For example, you can use getAllByRole('button') to get an array of all buttons in the DOM.
Remember to add data-testid attributes to your elements when you're testing them. This will make it easier to select and interact with them in your tests.
Library Overview
The Next.js library is a popular choice for building server-rendered and statically generated React applications. It provides a robust set of features for building fast and scalable applications.
Next.js integrates seamlessly with Jest and Jest-DOM, making it easy to write unit tests and integration tests for your application. To get started, you'll need to install the necessary packages, including `@testing-library/jest-dom` and `jest`.
With Next.js, you can easily render components in isolation and test their behavior using Jest and Jest-DOM. For example, you can use the `render` function from `@testing-library/react` to render a component and test its output.
Query Type
The Testing Library offers a variety of ways to query elements in the DOM, making it easier to write efficient tests.
You can query elements by their role, such as a button, using the getByRole method, which returns a single element matching the specified role.
For example, getByRole('button') will return the first button element in the DOM.
The Testing Library also allows you to query elements by their label text, placeholder text, text, display value, alt text, title, or test id.
Here are the different types of queries you can use:
- ByRole - query by role
- ByLabelText - query by label text
- ByPlaceholderText - query by placeholder text
- ByText - query by text
- ByDisplayValue - query by display value
- ByAltText - query by alt text
- ByTitle - query by title
- ByTestId - query by test id
These queries can be used in conjunction with other methods, such as getAllByRole, to retrieve multiple elements matching a specific query.
Library Priority
When writing tests, it's essential to follow a specific order of priority when querying the DOM. This order is suggested by the Testing Library, and it's based on accessibility guidelines.
The recommended order of priority is: get by role, then label text, placeholder text, text content, display value, alt text, title, and finally data-testid.
Here's a breakdown of the order:
- Get by role (e.g., getByRole('button', { name: /click me/i }))
- Get by label text (e.g., getByLabelText('First Name'))
- Get by placeholder text (e.g., getByPlaceholderText('Enter your first name'))
- Get by text content (e.g., getByText('Click me'))
- Get by display value (e.g., getByDisplayValue('John'))
- Get by alt text (e.g., getByAltText('Profile picture'))
- Get by title (e.g., getByTitle('Close'))
- Get by data-testid (e.g., getByTestId('my-element')) - use this as a last resort and only when necessary.
Remember, you should only use get by data-testid as a last resort, and it's best to assign data-testid to the element that you need to find.
Customizing the Test Environment
To customize the test environment, you can create a custom render function with wrapped context. This is done by importing your custom render function in your test files, specifically in @/test-utils, instead of the one from @testing-library/react.
You can also add other providers to your custom render function. This allows you to tailor the test environment to your specific needs.
To write tests, create test files for your components, pages, or other units of code, and write tests to verify their behavior.
Configure ESLint with Jest and React
To configure ESLint with Jest and React, you'll need to install a few plugins. Install eslint-plugin-jest and eslint-plugin-testing-library to get started.
These plugins will help you catch issues as you write tests with Jest and React Testing Library. You can install them separately or together using npm or yarn.
To integrate the plugins with ESLint, update your .eslintrc.json file with the following configuration:
- "next/core-web-vitals": Applies ESLint rules for Next.js projects to help optimize for Core Web Vitals.
- "plugin:jest/recommended": Includes a set of recommended Jest rules.
- "plugin:jest/style": Enforces style conventions for Jest tests.
- "plugin:testing-library/react": Activates rules specific to React Testing Library.
This configuration will apply the rules to your project's codebase, helping you catch issues and write better tests.
Create a Custom Render Function with Context
Creating a custom render function with context is a great way to tailor your test environment to your needs. You can do this by wrapping your context in a custom render function.
To use your custom render function, simply import it in your test files instead of the default one from @testing-library/react. This is a straightforward process, as explained in the documentation.
You can also add other providers to your custom render function, giving you even more control over your test environment.
Here's a simple way to think about it: you're essentially creating a custom wrapper around your context, which you can then use in your tests.
In practice, this means you can import your custom render function in @/test-utils, rather than the default one. This is a small change, but it can make a big difference in the flexibility and customization of your test environment.
To get started, you can check out the official React Testing Library docs for a quick cheat sheet on Next.js + Jest + React Testing Library.
Debugging and Troubleshooting
Debugging and troubleshooting can be a challenge, especially when working with complex frameworks like Next.js. Use debug() to log the HTML of a component to the console, which can help identify issues.
If getBy* methods fail, it's likely that the element is not rendered yet, so consider using findBy* instead. This can save you a lot of time and frustration.
Here are some additional tips to keep in mind:
Simulate Server Error
To simulate a server error, you can use the `server.resetHandlers()` method to set up a new behavior for a route, such as returning an error.
You'll still need to add the error handling logic in your component, as this method only sets up the server behavior.
This can be a helpful way to test how your application handles server errors, and ensure that your error handling logic is working as expected.
By simulating a server error, you can identify and fix issues with your application's error handling more efficiently.
To do this, follow these steps:
- Use `server.resetHandlers()` to set up a new behavior for a route.
Debugging Tips
Use the debug() function to log the HTML of a component to the console, which can be super helpful for identifying issues.
If getBy* methods fail, it's likely because the element hasn't been rendered yet, so consider switching to findBy* instead.
You'll need to use await when calling userEvent methods, so don't forget that crucial detail.
To run only one test, use test.only(), and to skip a test altogether, use test.skip().
Here are some common debugging techniques to keep in mind:
Jest's mock function, jest.mock(), doesn't actually do anything – it just tells Jest to mock the prop to avoid errors.
Sources
- https://github.com/emanuelefavero/next-jest-testing-library
- https://www.tarascodes.com/jest-nextjs
- https://www.geeksforgeeks.org/unit-testing-in-next-js-ensuring-code-quality-in-your-project/
- https://www.marcusoft.net/2022/11/nextjs-testing-async-react-components.html
- https://medium.com/@miyushanrodrigo/mastering-testing-in-next-js-with-jest-and-react-testing-library-f7b6a17d3cf5
Featured Images: pexels.com