Intro to React Testing Library
The @testing-library family of packages helps you test UI components in a user-centric way.
The @testing-library is the primary testing library suggested by Sage Architects.
> The principle behind the library: > The more your tests resemble the way your software is used, the more confidence they can give you.
> Jest is a testing framework.
> React Testing Library is just a library used with Jest to provide new testing functionality similar to Enzyme.
Querying
- Queries are the methods that Testing Library gives you to find elements on the page.
screenis an object which has access to every query.- There are 3 different types of query
get,findandquery. - Query methods follow a naming pattern of
getBy...,findBy...,queryBy...etc. There are alsoAllversions of each to find multiple matches.
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App";
describe("App", () => {
beforeEach(() => {
render();
});
test("has correct UI", () => {
// Title is on the page
expect(screen.getByText(/Title/i)).toBeInTheDocument();
// The create button is not disabled
const createButton = screen.getByText("Create");
expect(createButton).not.toBeDisabled();
});
});
Firing Events
- Use
fireEventto trigger events on elements found with queries. fireEventdispatches exactly the events you tell it to and just those – even if those exact events never had been dispatched in a real interaction in a browser.
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App";
describe("App", () => {
beforeEach(() => {
render();
});
test("adding a new post", () => {
// Populate the form inputs
const textInput = screen.getByLabelText("Title");
fireEvent.change(textInput, { target: { value: "New Post Title" } });
// Find and click the create button
const createButton = screen.getByText("Create");
fireEvent.click(createButton);
// Check the post was created and is visible
expect(screen.getByText(/New Post Title/i)).toBeInTheDocument();
});
});
User Events
userEventdispatches the events like they would happen if a user interacted with the document directly.- Using
userEventoverfireEventis a better way of testing user interaction with components. userEventis imported from a separate package@testing-library/user-event
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import "@testing-library/jest-dom";
import App from "./App";
describe("App", () => {
beforeEach(() => {
render();
});
test("adding a new post", async () => {
// Populate the form inputs
const textInput = screen.getByLabelText("Title");
await userEvent.click(textInput);
await userEvent.type(textInput, "New Great Post Title");
// Find and click the create button
const createButton = screen.getByText("Create");
await userEvent.click(createButton);
// Check the post was created and is visible
expect(screen.getByText(/New Great Post Title/i)).toBeInTheDocument();
});
});
Waiting for Async Methods
waitForis a useful async method which will wait for your expectations to pass. Use when you haveasyncactions.
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App";
describe("App", () => {
beforeEach(() => {
render();
});
test("deleting all posts", async () => {
// Find and click the clear posts button
const clearButton = screen.getByText("Clear Posts");
fireEvent.click(clearButton);
// Check post is gone after deletion
await waitFor(() => {
// Check the posts were destroyed and are not visible
// Use queryByX methods to determine element does not exist
expect(screen.queryByText(/Post Title/i)).toBeNull();
expect(screen.queryByText(/Post Body/i)).toBeNull();
});
});
});
Debugging
- Calling
screen.debug()will print the HTML for the component. E.G
<div>
<div class="app">
...
...
...
</div>
</div>
Useful Testing Library Links
- Queries – Methods to find elements on the page.
- Query within – How to search for an element within a found element.
- Firing Events – Use the
fireEventmethod to fire different events on elements.- User Events – Use the
userEventmethod to fire different events on elements.
- User Events – Use the
- Async Method – Methods for dealing with asynchronous code.
- waitFor –
waitForis a useful async method which will wait for your expectations to pass.
- waitFor –
- Debugging– Some additional debugging options
- Can still use the
debug()method console.log(screen.debug());
- Can still use the
One thought on “Introduction to User-Centric UI Testing with React Testing Library”