Snapshot Testing — When & How to Use (2026)
In this tutorial, you'll learn about Snapshot Testing. We cover key concepts, practical examples, and best practices.
Snapshot testing is a technique where you capture the output of a component or function at a point in time and compare future runs against that captured snapshot to detect unexpected changes.
What You'll Learn
You'll understand how Jest snapshot testing works, the difference between inline and file snapshots, when snapshots help versus hurt, how to handle false positives, and best practices for keeping snapshots maintainable.
Why Snapshot Testing Matters
Components change frequently during development. Manually verifying that a UI change didn't break unrelated parts is tedious. Snapshots automate this — if the output changes unexpectedly, the test fails. At DodaTech, Doda Browser uses snapshot tests to catch unintended UI regressions across its tab management and settings panels.
Snapshot Testing Learning Path
flowchart LR A[Jest Testing Framework] --> B[Snapshot Testing] B --> C[Testing React Apps] B --> D[Visual Regression Testing] style B fill:#f90,color:#fff
How Snapshot Testing Works
When you run a snapshot test for the first time, Jest creates a snapshot file. On subsequent runs, it compares the new output to the saved snapshot. If they differ, the test fails.
// Component snapshot test
import { render } from '@testing-library/react';
import UserProfile from './UserProfile';
test('renders user profile correctly', () => {
const { container } = render(
<UserProfile name="Alice" email="alice@example.com" />
);
expect(container).toMatchSnapshot();
});
First run — snapshot created:
Snapshot 1 written
✓ renders user profile correctly (15 ms)
Second run — passes if unchanged:
✓ renders user profile correctly (3 ms)
If the component changes, the test fails:
Snapshot 1 failed
✓ renders user profile correctly (3 ms)
- Snapshot
+ Received
- <div>Alice</div>
+ <div>Alice Smith</div>
Inline vs File Snapshots
Jest supports two snapshot modes:
| Aspect | Inline Snapshot | File Snapshot |
|---|---|---|
| Storage | In the test file | In __snapshots__/ directory |
| Update | Auto-updated by Jest | Run with --updateSnapshot |
| Review | Visible in diffs | Separate file review |
| Best for | Small, stable output | Large, complex output |
Inline Snapshot
test('formats greeting correctly', () => {
expect(formatGreeting('Alice')).toMatchInlineSnapshot();
});
Jest replaces toMatchInlineSnapshot() with the actual value:
test('formats greeting correctly', () => {
expect(formatGreeting('Alice')).toMatchInlineSnapshot(`"Hello, Alice!"`);
});
File Snapshot
test('renders profile card', () => {
const { container } = render(<ProfileCard user={user} />);
expect(container).toMatchSnapshot();
});
Snapshot saved to __snapshots__/ProfileCard.test.js.snap.
When Snapshots Help
Snapshots are useful for:
- UI component output: Verify that component HTML doesn't change unexpectedly
- Error messages: Capture and monitor error formatting
- Configuration outputs: Track config file generation
- Serialization: Monitor API response formatting
- Large data structures: Quick check that output matches expected shape
When Snapshots Hurt
Avoid snapshots for:
- Frequently changing UI: Tests fail constantly, reducing trust
- Large snapshots: Over 100 lines — reviewers can't spot changes
- Testing behavior: Snapshots test output, not behavior or logic
- Binary or non-deterministic output: Random values, timestamps, IDs
- CSS or styling details: Too brittle, prefer visual regression tests
Handling False Positives
Snapshots can fail for reasons that aren't bugs:
// This snapshot will fail every time because of timestamps
test('renders timestamp', () => {
const { container } = render(<Timestamp />);
expect(container).toMatchSnapshot(); // Bad idea
});
Solutions: Mock non-deterministic values or exclude them from the snapshot.
// Better: mock the date
jest.useFakeTimers();
jest.setSystemTime(new Date('2026-01-01'));
test('renders timestamp', () => {
const { container } = render(<Timestamp />);
expect(container).toMatchSnapshot();
});
jest.useRealTimers();
Best Practices
1. Keep Snapshots Small
If a snapshot exceeds 50 lines, consider splitting the component.
2. Review Snapshots in PRs
Blindly updating snapshots hides real bugs. Always review the diff.
npx jest --updateSnapshot # Use carefully — review changes first
3. Commit Snapshot Files
Snapshot files belong in version control. Don't add __snapshots__ to .gitignore.
4. Use Descriptive Test Names
Without clear names, failed snapshots are hard to debug.
// Good
test('renders error state with retry button', () => {
expect(container).toMatchSnapshot();
});
// Bad
test('snapshot 1', () => {
expect(container).toMatchSnapshot();
});
5. Combine with Specific Assertions
Don't rely solely on snapshots. Add targeted assertions for key behaviors.
test('renders profile and shows user name', () => {
const { container, getByText } = render(<Profile user={user} />);
expect(container).toMatchSnapshot();
expect(getByText('Alice')).toBeInTheDocument(); // Specific assertion
});
Common Mistakes
1. Auto-Updating Without Review
Running --updateSnapshot for all failures can hide real regressions.
2. Giant Snapshots
Hundred-line snapshots are never reviewed. They become noise.
3. Snapshot Testing Stateful Components
Components with internal state changes produce non-deterministic snapshots.
4. No Context in Snapshot Names
When a snapshot fails, the error should tell you which behavior broke.
5. Snapshot Testing Third-Party Components
You don't control third-party output. Their updates break your tests.
6. Using Snapshots Instead of Unit Tests
Snapshots verify output, not behavior. Use unit tests for logic.
7. Not Cleaning Up Obsolete Snapshots
When a component is removed, its snapshot file remains. Delete it.
Practice Questions
1. What is the difference between inline and file snapshots?
Inline snapshots are stored inside the test file; file snapshots are stored in __snapshots__/ directory. Inline snapshots are easier to review in diffs.
2. When should you NOT use snapshot testing? For frequently changing UI, large outputs, non-deterministic values, or when testing behavior rather than output.
3. How do you update all snapshots in Jest?
Run npx jest --updateSnapshot or npx jest -u. Always review the changes afterward.
4. Why should you commit snapshot files? Snapshots are the expected output — they need to be versioned so the team can review changes.
5. Challenge: Refactor a component to reduce snapshot size. Take a component that generates a 100-line snapshot and refactor it into smaller sub-components with smaller, focused snapshots.
Mini Project: Snapshot Testing a Notification Component
// Notification.jsx
function Notification({ type, message, onDismiss }) {
const colors = {
success: 'green',
error: 'red',
info: 'blue',
warning: 'orange',
};
return (
<div className={`notification ${colors[type]}`} role="alert">
<span className="icon">{type === 'error' ? '✕' : '✓'}</span>
<p>{message}</p>
{onDismiss && (
<button onClick={onDismiss} aria-label="Dismiss">
×
</button>
)}
</div>
);
}
// Notification.test.jsx
import { render } from '@testing-library/react';
import Notification from './Notification';
test('renders success notification with dismiss button', () => {
const { container } = render(
<Notification type="success" message="Saved!" onDismiss={() => {}} />
);
expect(container).toMatchSnapshot();
});
test('renders error notification without dismiss', () => {
const { container } = render(
<Notification type="error" message="Failed!" />
);
expect(container).toMatchSnapshot();
});
FAQ
What's Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro