How to Review and Update Snapshots Without Breaking Your Test Suite

How to Review and Update Snapshots Without Breaking Your Test Suite

Snapshot updates are routine maintenance — but routine doesn't mean thoughtless. The difference between a team that benefits from snapshot testing and one that doesn't comes down to how updates are handled. A careless update covers up a regression. A thoughtful one confirms an intentional change and keeps the baseline accurate.

Understanding What --updateSnapshot Actually Does

When you run jest --updateSnapshot (or jest -u), Jest rewrites every failing snapshot to match the current output. It also removes obsolete snapshots — files where the test no longer exists. What it doesn't do is check whether the changes are intentional.

That's your job. The flag should always be preceded by reading the diff.

The safest pattern:

# Step 1: See the failures
jest

<span class="hljs-comment"># Step 2: Read the diff in terminal
jest --verbose 2>&1 <span class="hljs-pipe">| grep -A 50 <span class="hljs-string">"Snapshot name:"

<span class="hljs-comment"># Step 3: Satisfy yourself that every change is intentional
<span class="hljs-comment"># Step 4: Update
jest --updateSnapshot

For targeted updates on a single test file:

jest components/Button.test.js --updateSnapshot

For a single test by name:

jest -t "renders primary button" --updateSnapshot

Targeted updates reduce the risk of accidentally updating unrelated snapshots that failed for other reasons.

Reading Snapshot Diffs

Jest's terminal diff output shows additions in green and removals in red. The format is straightforward:

Snapshot name: "renders error alert 1"

- Snapshot  - 1
+ Received  + 1

  <div>
    <div
-     class="alert alert--error"
+     class="alert alert--warning"
    >

This diff is telling you a class name changed from alert--error to alert--warning. Before updating, you need an answer: did you intentionally change the alert variant logic, or did something go wrong?

For complex diffs, the terminal output can be hard to read. Two options:

Open the .snap file directly. Snapshot files are plain text. Open them in your editor, which gives you syntax highlighting and the ability to search.

Use the Jest watch mode diff view. Running jest --watch provides an interactive mode with a cleaner diff display and the ability to update individual failing tests by pressing u.

jest --watch
# Press 'u' to update failing snapshots interactively

Watch mode is particularly useful during active development when you're iterating on a component and updating snapshots repeatedly.

Reviewing Snapshot Diffs in PRs

Snapshot files committed to version control show up as diffs in pull requests. This is by design — snapshot changes are code changes and should be reviewed.

What to look for in a snapshot diff review:

  1. Does the change match the PR description? If a PR says "fix button hover color" and the snapshot diff shows structural markup changes, something unexpected happened.
  2. Is the scope of the change what you'd expect? A change to a Button component should affect button snapshots. If it's also affecting Modal and Form snapshots, the change has unexpected reach.
  3. Are there deletions alongside additions? A snapshot that changes class="btn btn--primary" to class="btn btn--primary btn--large" is an addition. A snapshot that completely restructures the markup is a much bigger change that deserves more scrutiny.
  4. Are new snapshots being created? New test files creating new snapshots should be reviewed just like new tests. What state is being captured? Is it useful?

PR review comment template:

Ask PR authors to annotate snapshot changes with a one-liner in their PR description:

Snapshot changes:
- Button.test.js.snap: added `aria-label` attribute to button (accessibility improvement)
- Modal.test.js.snap: removed wrapper div that was refactored away

This takes 30 seconds to write and saves reviewers from having to infer intent from the diff.

CI Policies for Snapshots

Snapshot failures in CI block the build — that's the intended behavior. But there are additional policies worth implementing to keep snapshot testing healthy.

Fail on obsolete snapshots. By default, Jest warns about obsolete snapshots but doesn't fail. Enable --ci mode in your CI pipeline to treat obsolete snapshots as failures:

jest --ci

In --ci mode, Jest also disables interactive watch mode and makes the runner non-interactive. Importantly, it will fail if any new snapshots are created (because new snapshots mean test authors didn't commit the snapshot file). This catches cases where developers run tests locally without committing the .snap file.

Separate snapshot update PRs. Some teams establish a policy that snapshot updates should be committed in the same PR as the code change — never in a follow-up "fix snapshots" PR. This ensures snapshot changes are reviewed alongside the code that caused them.

Require snapshot explanation for large diffs. In your PR template, add a conditional requirement: "If more than 5 snapshot files changed, explain each change." Large snapshot changes are high-risk and deserve extra attention.

Organizing Snapshot Directories

Jest's default behavior places .snap files in __snapshots__ directories adjacent to test files:

src/
  components/
    Button/
      Button.jsx
      Button.test.js
      __snapshots__/
        Button.test.js.snap

This default is reasonable. Snapshots live close to the tests that create them, making the relationship clear.

Alternative: centralized snapshot directory. Some teams prefer a single top-level __snapshots__ directory for easier management:

// jest.config.js
module.exports = {
  snapshotResolver: './snapshotResolver.js',
};
// snapshotResolver.js
module.exports = {
  resolveSnapshotPath: (testPath, snapshotExtension) =>
    testPath.replace('/src/', '/__snapshots__/') + snapshotExtension,
  resolveTestPath: (snapshotFilePath, snapshotExtension) =>
    snapshotFilePath.replace('/__snapshots__/', '/src/').slice(0, -snapshotExtension.length),
  testPathForConsistencyCheck: 'src/components/Button.test.js',
};

Centralized snapshots make it easy to audit snapshot count and size across the project. The tradeoff is that the connection between test and snapshot is less obvious.

Keep snapshot directories committed and clean. Snapshot files belong in version control. Stale snapshot files — for tests that no longer exist — should be cleaned up regularly:

jest --updateSnapshot  # also removes obsolete snapshots

Run this periodically or as part of your release process to prevent snapshot directory sprawl.

Automated Snapshot Review Hints

Some teams use tooling to flag potentially problematic snapshot updates:

Size thresholds. A custom Jest reporter or a CI script can check snapshot file sizes and flag unusually large snapshots for manual review.

Diff percentage warnings. If a snapshot diff exceeds a certain percentage of the total snapshot size, surface it as a warning in the PR. Large percentage changes indicate significant structural shifts.

Snapshot count tracking. Track snapshot count over time. Rapid increases in snapshot count — without corresponding increases in component count — indicate snapshot overuse.

None of these are strictly necessary, but they provide early warning before snapshot debt becomes unmanageable.

The Update Workflow at Scale

For large codebases with hundreds of snapshots, a mass update after a global refactor can be daunting. A structured approach:

# 1. Run tests to see the full scope
jest --json > test-results.json
<span class="hljs-built_in">cat test-results.json <span class="hljs-pipe">| jq <span class="hljs-string">'.testResults[] | select(.status=="failed") <span class="hljs-pipe">| .testFilePath'

<span class="hljs-comment"># 2. Group failing tests by component or feature area
<span class="hljs-comment"># 3. Review and update by area, not all at once
jest src/components/forms/ --updateSnapshot
jest src/components/navigation/ --updateSnapshot

<span class="hljs-comment"># 4. Run the full suite to confirm no unexpected failures
jest

Updating by area keeps each update reviewable. A focused update to form components is easier to validate than a global update across 50 files.

The goal is always the same: every snapshot update should be explainable. If you can't say why a snapshot changed, that's a gap in understanding that could be hiding a real problem.

Read more