Alex Krolick

@alexkrolick

Oh snap, snapshots! Unit & integration testing with Jest & Enzyme

A screenshot journey

React Devtools — Inspiration

Using Webpack’s “watch mode” is a great way to develop web apps. As you edit code, the app rebuilds and automatically reloads the page.

Did you know Jest also has a watch mode?

Snapshot-Driven Development

jest --watch

Watch mode lets you develop iteratively using snapshots of your components in different states as a way to confidently refactor and add features.

In watch mode, Jest automatically re-runs your tests when files change. You can inspect changes and update snapshots with one keypress by pressing “u”. Cool!

Let’s walk through a scenario: Adding tests to a simple app boostrapped with create-react-app.

The App component

The first test

Adding a snapshot

Refactoring the header into its own component: updated snapshot

Adding props and condtional logic to the new Header component: snapshot fails

Adding props and condtional logic to the new Header component: updated snapshot

Shallow rendering

To avoid coupling the Header implementation to the App component, we can use Enzyme’s shallow render and Enzyme-To-JSON to snapshot only the top level render tree.

Switching to a shallow snapshot: snapshot fails

Switching to a shallow snapshot: updated snapshot

Moving beyond snapshots — .find() and Markers

As you add more snapshot tests you may discover that some become brittle, need to be updated to often, or that you want to assert about more specific results than what high-level snapshotting provides.

To make DOM tests more resilient you can use “test markers” (special classes or data tags that are only meaningful to tests). For example, the Header component can be rendered into different states but it might be nice to assert that something specific appears when logged in and something else when logged out. Add a test marker and use Enzyme DOM traversal methods like .find to assert that they appear when expected.

Shallow rendering the Header in different states

Adding test marker tags (data-test="xyz") and .find()

Zoomed in on the marker implementation

At this stage we might consider removing the snapshots altogether since we’ve identified and expected what we care about.

Testing Stateful Components

Next up:

  • Testing stateful components using Enzyme (component.setState)
  • Mocking dependencies as an alternative to shallow rendering (jest.mockFn())
  • Test harnesses for React Context and other globals

Discussions around the web — when to use snapshots

Adding Jest & Enzyme

yarn add --dev react-test-renderer jest enzyme enzyme-adapter-react-16 jest-enzyme enzyme-to-json

Follow the Enzyme setup instructions for your environment.

Demo App

https://github.com/alexkrolick/snapshot-testing-demo

More by Alex Krolick

Topics of interest

More Related Stories