Snapshot testing is one of many ways to test your React application. It’s a great way to catch any would-be bugs in the UI of your project. Let’s take a look at how it works.

Definition

To start snapshot testing you need to have the desired app layout already developed. In a nutshell snapshot testing renders the serializabe value of the UI of the component and then takes a snapshot of it for further reference. 

In the futere when we are runnning the tests again, the testing framework renders a new snapshot of the same component and compares it with the old one. If there is a difference between them, the test case will fail.

If that happens then you can be 100% sure that whatever changes you made to your code have indeed affected the UI of the application. Now it’s time for you to take a look and check if those differences were acutally expected. If they were then you need to update the old snapshot to the new one. If they weren’t then you have managed to catch a bug before it hit the production enviroment.

Usage

Let’s strat by installing React Test Renderer library in our application. It will help us with rendering the React components to pure JavaScript objects. Go ahead and run

$ npm i react-test-renderer

in the root directory of your React application.

Next let’s write a simple test component. I’m going to use the User.js that simply renders the provided props to the page.

const User = ({ user }) => {
  return (
    <>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
      <p>Hobby: {user.hobby}</p>
    </>
  )
}

export default User;

Next, let’s go ahead and start writing the test case.

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

it('User renders correctly', () => {
  const user = {
    name: 'Tom',
    age: 32,
    hobby: 'coding'
  }
  const element = renderer.create(<User user={user}/>).toJSON();
  expect(element).toMatchSnapshot();
});

As we can see at the top of the file we’re importing the renderer from the newly installed React Test Renderer library. We’re then creating the props variable user that we’re going to pass to the User component. We’re using the create method available on the renderer and passign the User component as an argument. We’re also saving the output to the element variable.

For out test statement we’re using the toMatchSnapshot method. You can now run

$ npm run test

To run the tests.

If this is the first time that we’re running the test, a new snapshot file will be automatically generated.

test output 1

You should see that a new __snapshots__ directory appeared in your project. Inside you can find User.test.js.snap file. That’s the snapshot for the User component.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`User renders correctly 1`] = `
Array [
  <p>
    Name: 
    Tom
  </p>,
  <p>
    Age: 
    32
  </p>,
  <p>
    Hobby: 
    coding
  </p>,
]
`;

It will be used in the following executions of the User.test.js to run the snapshot testing. Let’s run the test again to the that in action.

test outpu 2

Now let’s see a breaking test. I have made some changes to the User.js file. I now expect that those differences will be picked up by the test.

const User = ({ user }) => {
  return (
    <>
      <p>Name: {user.name}</p>
      <p>Age: {user.age}</p>
    </>
  )
}

export default User;

And the test output.

test output 3

As you can see. The UI output of the current version of User component doesn’t match the saved snapshot. For a developer it can mean one of the two things, they either introduces some planned changes and an update of the snapshot file is expected or they introduced some bugs that need to be investigated.

Avatar photo
👋 Hey, I'm Dawid Budaszewski
Hello! I'm Dawid. I'm a full-stack developer with a couple of years of experience under my belt. I spent most of my career working with React. I also built reacterry.com, an online portal with React coding challenges.

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.