All topics
Testingintermediate

Snapshot Testing

Capturing a serialized representation of a value or rendered output and comparing future test runs against that saved baseline, flagging any unexpected differences.

A snapshot test records the output once and compares future runs against it.

Snapshot testing is like a security system that photographs a room's exact layout once and, on every subsequent check, compares a fresh photo against that saved baseline, immediately flagging anything that's moved — but the system is only useful if a human genuinely looks at the flagged differences and decides whether they're expected (someone rearranged furniture on purpose) versus a real problem, rather than reflexively approving every alert without looking.

Key Concepts

1
    it('renders the card', () => {
      const { container } = render(<Card title="Hi" />);
      expect(container).toMatchSnapshot();
    });
2
The first run writes a .snap file. Later runs compare against it, and any difference fails.
.snap
3
What it is good at. Catching unintended changes in output you would not otherwise assert on — a component's rendered markup, a configuration object, a serialised error.
4
Writing explicit assertions for every element of a large structure is tedious and gets skipped. A snapshot covers all of it for one line.
5
What it is bad at, and this is the part that matters.
6
It asserts nothing about correctness. A snapshot of wrong output passes forever. It tells you the output changed, not that it is right.
7
Reviewing becomes automatic. When a large snapshot fails, the tempting response is jest -u to update it. Do that reflexively and the test asserts whatever the code currently does.
jest -u
8
Large snapshots are unreadable. A 400-line snapshot diff is not reviewed carefully by anyone.
9
Which gives the practices that make them useful.
    keep them small          one component, not a whole page
    commit them              they are the expectation
    review the diff          if it cannot be reviewed, it is too big
    inline snapshots         toMatchInlineSnapshot() -- the expected
                             value sits in the test file, where it
                             is visible
10
Inline snapshots are the improvement. The expected output is in the test, so a reviewer sees the change in the diff of the test file rather than in a separate file nobody opens.
11
Where a real assertion is better.
    expect(screen.getByRole('heading')).toHaveTextContent('Hi');
12
That says what matters. A snapshot says "everything is as it was", including the parts that are irrelevant — so it fails on a class name change that broke nothing.
13
The rule of thumb. Snapshots for output that is large, stable and hard to assert piecemeal. Explicit assertions for the behaviour you actually care about. A test file that is only snapshots is usually testing that the code has not changed, which the version control system already records.
14
What the interviewer is probing.1. "What is the main risk of snapshot tests?" Probing: the failure mode. Stalls: "They are slow." Moves up: blind updating — a snapshot regenerated without reading the diff turns a regression into a committed expectation.
15
2. "What makes a good snapshot?" Probing: scope. Stalls: "The whole page." Moves up: small and focused, so a diff is readable; a large snapshot changes on anything and stops being informative.
16
3. "When is an explicit assertion better?" Probing: judgement. Stalls: "Never." Moves up: when you care about one specific property — assert that, rather than freezing everything around it.
17
4. "How do you handle changing values like dates?" Probing: determinism. Stalls: "Ignore the failure." Moves up: mock the clock or use property matchers, or the snapshot fails every run.