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
- 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. - Subsequent runs: The current output is compared against the saved snapshot.
- 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
- If the change was intentional, update the snapshot with
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
-uwithout 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
-
toMatchSnapshotis for detecting changes in output - Limit its use to small, stable components
- For verifying behavior, use queries like
getByRoletogether with matchers such astoBeInTheDocument/toHaveTextContent
