Test Driven Development with Jest and React Snapshot Testing

Learning Objective:
By the end of this lesson, students will be able to evaluate component rendering using snapshot testing to make sure changes in UI behavior are intentional and do not introduce bugs.

Snapshot Testing

Snapshot testing is a powerful technique that helps confirm a React component’s rendered output. When you run a snapshot test for the first time, Jest captures the component’s “snapshot” (its HTML structure and content at that moment) and stores it in a folder, typically in __snapshots__. This saved snapshot becomes the “expected” output for future test runs.

How snapshots are created and stored

  1. First Test Run:

    • Jest sees that no snapshot file exists for your test. It then creates a snapshot file in a folder named something like __snapshots__.
    • The snapshot file is usually automatically named to match your test file, which helps keep things organized.
  2. Subsequent Test Runs:

    • Each time you run the tests again, Jest compares the current component output to the stored snapshot.
    • If the two match, the test passes. If they differ unexpectedly, the test fails, alerting you to a potential UI change or bug.

In our React application, snapshots are stored in src/__tests__/__snapshots__ by default, though the exact location can vary based on your project setup.

Why snapshot testing is important

Snapshot testing example

Here’s a simple snapshot test for the App component of our React application:

it('matches snapshot on initial render', () => {
  const app = render(<App />);
  // Verifies the app's initial render matches the saved snapshot
  expect(app.baseElement).toMatchSnapshot();
});

What is happening?

  1. render(<App />): Renders the App component for testing.
  2. app.baseElement: Represents the root element of the rendered component.
  3. toMatchSnapshot(): Compares the current output with the saved snapshot in src/__tests__/__snapshots__. If they don’t match, the test fails.

Testing snapshots after a user Interaction

You can also create snapshots after user actions to make sure that the UI updates as expected.

it('matches snapshot after clicking About', () => {
  const app = render(<App />);

  // Simulate a user interaction
  const aboutButton = screen.getByText('About');
  fireEvent.click(aboutButton);

  // Verify the updated UI matches the snapshot
  expect(app.baseElement).toMatchSnapshot();
});

What is happening?

Updating snapshots

When you make deliberate changes to your component’s rendering, your snapshots will no longer match, causing tests to fail. In this case, you can update the snapshots:

yarn jest --updateSnapshot

or

npm run test -- --updateSnapshot

Important: Always check that the new output is exactly what you want before you update the snapshot. Otherwise, you risk overlooking genuine bugs.