Skip to content

Jest Snapshot Best Practices

Snapshot testing is powerful but easy to misuse. This lesson rounds up practical best practices for keeping your snapshots small, meaningful, and genuinely useful over time.

Keep Snapshots Small and Focused

A snapshot of an entire page or a deeply nested component tree is hard to review meaningfully — a reviewer scanning a 200-line diff is far more likely to rubber-stamp it than genuinely check correctness. Smaller, more targeted snapshots (of a single component, or a specific transformed object) are easier to actually review.

If a snapshot keeps needing updates for unrelated reasons (a shared header component changes and every page snapshot breaks), that's a sign the snapshot boundary is too broad.

// Too broad: entire page, breaks on unrelated header changes
expect(render(<HomePage />).container).toMatchSnapshot();

// Better: focused on just the component being tested
expect(render(<PriceTag amount={19.99} />).container).toMatchSnapshot();

A focused snapshot only changes when the specific component it targets actually changes.

Normalizing Non-Deterministic Data

expect({
  id: user.id,
  name: user.name,
  createdAt: expect.any(String), // ignore the exact timestamp
}).toMatchSnapshot();
  • Use expect.any(Constructor) inside a snapshot to ignore a specific field's exact value while still checking its type.
  • Alternatively, strip or replace dynamic fields (timestamps, UUIDs) with fixed placeholder values before snapshotting.
  • Custom snapshot serializers can format specific types (like Date) consistently across a whole suite.
  • Never snapshot raw Math.random() or Date.now() output directly.

Snapshot Best Practices Cheat Sheet

A checklist for healthy, maintainable snapshot tests.

Practice Why
Keep snapshots small and focused Easier to review meaningfully
Normalize non-deterministic fields Avoids flaky, unrelated failures
Commit .snap files to version control Enables diff-based review
Review every snapshot diff before updating Prevents accepting real regressions
Combine with explicit assertions when clarity matters Some behaviors are clearer with .toBe()
Delete obsolete snapshots Keeps the suite clean and trustworthy

Custom Snapshot Serializers

Jest lets you register custom serializers (via expect.addSnapshotSerializer() or the snapshotSerializers config option) to control exactly how specific types are printed in a snapshot, which helps keep output consistent and readable across an entire suite, especially for domain-specific objects.

expect.addSnapshotSerializer({
  test: (value) => value instanceof Money,
  print: (value) => `Money(${value.formatted})`,
});

Combining Snapshots with Explicit Assertions

Snapshots aren't a replacement for explicit assertions — for a critical piece of business logic, an explicit expect(total).toBe(135) documents intent more clearly than a snapshot diff ever could. Use both together: a snapshot for overall shape, plus explicit assertions for the specific values that matter most.

Common Mistakes

  • Snapshotting an entire page or app instead of a focused component or value.
  • Letting non-deterministic fields (timestamps, random IDs) leak into snapshots unnormalized.
  • Treating a passing snapshot as proof of correctness without ever reviewing the original diff.
  • Never deleting obsolete snapshots for tests or components that no longer exist.

Key Takeaways

  • Smaller, focused snapshots are easier to review and less prone to unrelated breakage.
  • Normalize timestamps, random IDs, and other non-deterministic fields before snapshotting.
  • Custom serializers keep snapshot output consistent and readable for domain-specific types.
  • Pair snapshots with explicit assertions for the most business-critical values.

Pro Tip

Whenever you're about to snapshot an entire rendered page, pause and ask if a smaller, more targeted snapshot of just the changed component would be both more useful and easier to review.