toMatchSnapshot in React Testing Library

toMatchSnapshot is a matcher in Jest (and Vitest). Used together with React Testing Library, it saves a component's output as a "snapshot" and detects differences in later test runs.

Basic Usage

import { render } from '@testing-library/react'; import { Button } from './Button'; test('Button renders as expected', () => { const { container } = render(<Button label="Submit" />); expect(container).toMatchSnapshot(); }); 

How It Works

  1. First run: The rendered result (DOM structure) is saved to a file such as __snapshots__/Button.test.tsx.snap. The test always passes at this point.
  2. Subsequent runs: The current output is compared against the saved snapshot.
  3. If there is a difference: The test fails and the diff is displayed.
    • If the change was intentional, update the snapshot with jest -u (or --updateSnapshot)
    • If it was unintentional, fix the code

Example of a saved snapshot:

exports[`Button renders as expected 1`] = ` <div> <button class="btn" > Submit </button> </div> `; 

When to Use It

  • Checking the output of small, static components that rarely change
  • Detecting unintended markup changes (regressions)
  • Output with a fixed structure, such as error messages or formatted data

Caveats and Downsides

  • It's easy to lose sight of what is being verified: It only tells you that "the output changed," not whether the behavior is correct.
  • Large snapshots become meaningless: When diffs are big, they tend to get updated with -u without being reviewed.
  • It depends on implementation details: It frequently breaks due to things like class name changes.
  • It doesn't fit well with the Testing Library philosophy of testing behavior from the user's perspective.

Recommended Alternatives and Complements

In many cases, user-focused assertions are more robust.

import { render, screen } from '@testing-library/react'; test('the button is displayed', () => { render(<Button label="Submit" />); expect(screen.getByRole('button', { name: 'Submit' })).toBeInTheDocument(); }); 

Related: Inline Snapshots

For small outputs, toMatchInlineSnapshot() lets you write the snapshot directly in the test code (it's written automatically on the first run).

expect(container).toMatchInlineSnapshot(); 

Summary

  • toMatchSnapshot is for detecting changes in output
  • Limit its use to small, stable components
  • For verifying behavior, use queries like getByRole together with matchers such as toBeInTheDocument / toHaveTextContent