Skip to main content

Snapshot testing

Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.

A typical snapshot test case renders a UI component, takes a snapshot, then compares it to a reference snapshot file stored alongside the test. The test will fail if the two snapshots do not match: either the change is unexpected, or the reference snapshot needs to be updated to the new version of the UI component.

Creating a snapshot test

The following code provides an example of a snapshot test using Jest. Imagine: you have a component in your application that renders a link to Facebook. You use this component in multiple pages of your application and you want to make sure that the link to Facebook remains intact and renders similarly across the board. For this you write the following snapshot test:

import React from 'react';
import renderer from 'react-test-renderer';
import Link from '../Link.react';

it('renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.facebook.com">Facebook</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});

First off, we see we require a package called react-test-renderer which we will install using the terminal command npm i --save-dev react-test-renderer.

Notice how snapshot tests are structured similarly to unit tests: they follow the same it, (describe), expect formulation.

The first time this test is run, Jest creates a 'snapshot' of the HTML-output created by React when a Link component is applied with the props you have supplied. This Link component renders as an <a> element with a number of props, which is then converted into JSON format using the .JSON() method, called without arguments:

exports[`renders correctly 1`] = `
<a href="/">
Homepage
</a>
`;

The above is stored as a snapshot file, in a dedicated snapshots folder. Great. We're done here, right?

Detecting unwanted changes

Not so fast amigo. We don't write tests just for the sake of writing tests. We want to use them to our advantage. Say the following occurs: somewhere in your application, some unaccounted factor has supplied your Link component with a different prop and title, which inadvertently leads users of your application to this website instead of your intended url and renders a different link title altogether.

This kind of thing may easily go unnoticed without the use of screenshot tests, that monitor your app for UI changes accross different pages and components.

Updating screenshots for intended UI changes

While developing or updating an application, UI changes are obviously going to occur intentionally. For example, the lead UX may decide to invert the brand color, which will mean all button colors will need to undergo a color change from red to blue - alert: all your snapshot tests have failed! But have you really failed, or have the tests failed?

Relax. In this case you haven't failed, the tests were just expecting you to stick with the old brand color. This situation therefore requires you to update the snapshots to expect a different test outcome. Updating snapshots can be done via the terminal, using the command jest --updateSnapshot.