Snapshot testing captures a serialized version of a value — often a rendered component or a large object — and compares it against a saved reference on every future run. This lesson explains how snapshots work and when they're the right tool.
How toMatchSnapshot() Works
The first time expect(value).toMatchSnapshot() runs, Jest serializes value and saves it to a .snap file next to your test. On every subsequent run, Jest compares the current value's serialization against the saved snapshot; if they differ, the test fails and shows a diff.
This is especially useful for UI component output and large, structured data (like API response shapes) where writing individual field-by-field assertions would be tedious and less likely to catch unintended changes elsewhere in the structure.
function formatReceipt(order) {
return {
items: order.items,
total: order.total,
generatedAt: '2024-01-01', // deterministic for this example
};
}
test('formats a receipt', () => {
const receipt = formatReceipt({ items: ['book'], total: 20 });
expect(receipt).toMatchSnapshot();
});
The first run creates __snapshots__/receipt.test.js.snap; future runs compare against it automatically.
Snapshot files live in a __snapshots__ folder next to the test file, named <testfile>.snap.
Each snapshot is keyed by its test name, so multiple snapshots in one file don't collide.
Snapshot files should be committed to version control and reviewed like code in pull requests.
Never hand-edit a .snap file directly; regenerate it with Jest's update flag instead.
Snapshot Testing Cheat Sheet
The essentials of Jest's snapshot testing workflow.
Action
Command / Method
Create/compare a snapshot
expect(value).toMatchSnapshot()
Run tests, creating new snapshots
npx jest (first run auto-creates)
Update snapshots after an intentional change
npx jest -u
Snapshot file location
__snapshots__/<file>.snap
React component snapshot
expect(component.toJSON()).toMatchSnapshot()
Remove obsolete snapshots
npx jest -u (also prunes unused snapshots)
When Snapshot Testing Is a Good Fit
Snapshots shine for output that is complex, structured, and expected to change deliberately over time as a whole — React component trees, generated configuration objects, or serialized API responses. They save you from writing (and maintaining) dozens of individual field assertions.
Rendered component output (with React Test Renderer or Testing Library).
Large, structured objects where the entire shape matters.
Generated output like formatted reports, templates, or configuration.
When Snapshots Are the Wrong Tool
Snapshots are a poor fit for output containing non-deterministic values (timestamps, random IDs) unless you specifically normalize them first, and they can encourage a habit of blindly running -u without actually reviewing what changed — which defeats the entire purpose of the test.
Good Fit
Poor Fit
Stable, structured output
Output with timestamps/random IDs
Component rendering
Simple primitive return values (use .toBe())
Reviewed diffs in PRs
Snapshots nobody actually reviews
Common Mistakes
Snapshotting output that contains a real timestamp or random ID, causing spurious failures.
Running jest -u reflexively without reading the diff to confirm the change is actually intended.
Using a giant snapshot for a value that would be clearer as a few explicit .toBe()/.toEqual() assertions.
Not committing .snap files to version control, breaking the whole point of comparing against history.
Key Takeaways
.toMatchSnapshot() saves a serialized value and compares against it on future runs.
Snapshot files live in __snapshots__ and should be committed and code-reviewed.
Snapshots are best for complex, structured, deterministic output.
Always review a snapshot diff before updating it — never update blindly.
Pro Tip
Treat a snapshot diff in a pull request exactly like a code diff: read it carefully. A snapshot test only protects you if a human actually looks at what changed before approving the update.
You now understand the fundamentals of snapshot testing. Next, learn about inline snapshots and when they're more convenient than file-based ones.