Technical & Organizational Benefits of Storybook Snapshot Testing

Keep updating those snapshots, don’t bother looking at them, and stop complaining about them

Jongleberry
4 min readSep 22, 2021

I’ve heard many complaints about Storybook StoryShots and Jest snapshot testing at work, online, and various Slack groups. Some of the complaints I’ve heard are:

  • It’s annoying because you always have to update the snapshots
  • It makes the git diff very large
  • It doesn’t actually guarantee anything
  • It creates a false sense of security

Some of the points above are just irrelevant—you should never have to worry about large git text diffs as this is what git is optimized for. Others simply miss the organizational, technical, and other benefits of having StoryShots and snapshot testing, which is more important to me as an engineering manager. By always updating snapshots locally, you’ll reap many benefits with the minimal cost of running tests.

StoryShots and snapshot testing do not assert correctness

A snapshot simply stores some states in a moment in time or git history. A changed snapshot means that something has changed, but does not necessarily mean that the functionality is now broken or incorrect like a failing test otherwise would. Thus, I wouldn’t even call it a “test” — it’s more like a validation step. A snapshot “test” failed because the output change and an engineer needs to manually validate it.

StoryShots and snapshot testing is more like static checking

Many people see snapshot testing as a less useful form of unit testing, but a better way too see snapshot testing is as a more useful form of static checking and linting. Linting tools check that your code is valid without executing it whereas snapshot testing checks that your code is valid by executing it; both do not check for correctness. The fact that snapshot testing actually runs your code allows you to find bugs that linting would not be able to find. There are plenty of typos, bad imports, or bad dependencies that I’ve caught with no effort with StoryShots.

StoryShots encourages you to build view components

If you’ve built a complex component with data fetching and rendering, you’ve probably struggled with StoryShots as your component is dynamic and nondeterministic. For example, if your component depends on the current date, your snapshots will start failing the day after you merge your code. StoryShots and snapshot testing encourages making deterministic view components and to pass nondeterministic parameters as props. It encourages building separate data loading components or containers whose functionality can be unit tested separately.

StoryShots is a step towards visual regression testing

With only deterministic view components as stories, your team will be able to rely on visual testing to find visual regressions. With visual regression testing, your HTML DOM structure snapshots will matter much less—just manually validate the visual changes. The organizational benefit with visual regression testing is that you can visually show the changes to non-technical stakeholders like designers and product managers and catch issues sooner.

Snapshot testing encourages engineers to run tests locally

A failed snapshot test means the engineer did not run the test locally (i.e. did not intervene manually), which they should be doing whenever possible. The fact that PRs are failing because snapshots weren’t updated means that the engineer probably didn’t run the tests locally.

Snapshot testing helps you understand the dependency tree

Sometimes you will, in fact, run tests just for your component locally, but in CI, where the entire test suite is ran, you’ll find that your change also affected another component’s snapshots. These snapshot tests are a way to understand the dependency tree and know who are impacted by your changes or whose changes impact you.

Snapshot history is a paper trail for debugging issues

Snapshot histories provide a way for you to debug and issues in your code base. Snapshots allow you to know which PRs changes the structure of certain components, allowing you to more quickly find a culprit for an issue via git during an outage.

StoryShots allows engineers to skip writing their own snapshots

I hear people complaining about StoryShots, but then write their own snapshot tests for their component. This is just adding work on their plate and additional maintenance for the team. When you write a story and add StoryShot testing, you have snapshot testing for free. Of course, StoryShots only handles snapshots for views — non-view snapshots will still need to be done manually (such as tests for a component’s state machine).

How to make snapshot testing better

To avoid complaints in your organization while achieving the marginal benefits of StoryShots, I recommend these changes:

  • Use shallow rendering to avoid large snapshots that are prone to breakage
  • Run StoryShots tests separate from your other tests
  • Always run StoryShots with -u locally
  • Create a CI job that automatically updates snapshots when necessary
  • If any stories or storyshots get annoying, fix it or delete it

--

--