Jest snapshot testing pros and cons, updating snapshots, when to use them, and an introduction to Storybook for visual component testing.
Snapshot & Visual Testing
Snapshot testing captures the rendered output of a component (or any serialisable value) and saves it to a file. Subsequent test runs compare the current output against the saved snapshot - if they differ, the test fails. This sounds like a safety net but can become a maintenance burden if used carelessly.
This chapter covers Jest's built-in snapshot mechanism, its trade-offs, and how Storybook can complement or replace snapshots for visual component testing.
Jest Snapshot Testing
How It Works
On the first run, toMatchSnapshot() writes the snapshot to a .snap file next to the test. On every subsequent run, it compares the current value to the saved file.
First run creates __snapshots__/Badge.test.tsx.snap:
If you change the component - even adding a CSS class - the test fails until you update the snapshot.
Updating Snapshots
Updating snapshots should be a deliberate decision, not a reflex. Always read the diff before updating to confirm the change is intentional.
Inline Snapshots
Instead of writing to a .snap file, toMatchInlineSnapshot() writes the snapshot directly into the test source file. This keeps the expected output close to the assertion:
Inline snapshots are self-updating: jest -u rewrites the string in the source file. They are better than external snapshots because reviewers can see the expected HTML in the pull request diff.
Snapshot Testing for Non-HTML Values
Snapshots are not limited to React output. They work on any serialisable JavaScript value:
Property matchers are passed as the first argument; each matched field is serialised in the snapshot as e.g. Any<String>. The same form works with toMatchSnapshot:
This lets you snapshot the stable parts of the response while ignoring volatile fields.
The Pros and Cons of Snapshots
When snapshots help
When snapshots hurt
The Snapshot Anti-Pattern
The most common snapshot mistake is snapshotting an entire page component:
Every time any child component changes, this snapshot breaks. Developers run jest -u without reviewing. The snapshot drifts from reality.
Better approach: test behaviour explicitly in RTL, and snapshot only small, stable leaf components:
Storybook for Visual Testing
Storybook is a tool for developing and documenting UI components in isolation. Each "story" is a component rendered with a specific set of props. Stories serve as:
- A living component catalogue
- A manual QA surface
- A foundation for automated visual regression tests
Setting Up Storybook
This detects your framework (React, Vue, Svelte) and configures Storybook automatically.
Writing Stories
Run the Storybook dev server:
Storybook Interaction Tests
The @storybook/addon-interactions addon lets you write play functions that simulate user interactions inside a story:
These play functions run in the browser and can be executed as part of a CI pipeline. As of Storybook 9, Vite-powered
projects (React/Vue/Svelte with the Vite builder) should use @storybook/addon-vitest instead of the runner below;
the Storybook test runner (test-storybook, see below) remains the supported path for non-Vite builders like Webpack
or Angular.
Storybook Test Runner
The Storybook test runner (backed by Playwright) runs all stories headlessly and executes their play functions:
This gives you automated interaction testing of every story without writing a separate test file.
Visual Regression Testing with Chromatic
Chromatic is a cloud service built by the Storybook team. It renders every story across browsers, takes screenshots, and flags pixel-level differences for human review.
In CI:
The workflow:
- Chromatic runs on every PR
- If a story's screenshot changes, Chromatic asks for review
- A human approves intended changes; unintended ones are flagged as bugs
This workflow is the industry standard for catching visual regressions in component libraries.
Choosing the Right Tool
The practical default for most applications: use RTL for all behaviour tests, Storybook stories for documentation and manual review, and inline snapshots sparingly for stable leaf components. Add visual regression tools when you are maintaining a shared component library or a design system.