Snapshot Testing in React Storybook
Snapshot testing is a way to test your UI component without writing actual test cases. Here’s how it works:
- A snapshot is a single state of your UI, saved in a file.
- You have a set of snapshots for your UI components.
- Once you add a new UI feature, you can generate new snapshots for the updated UI components.
- Then you can diff old and new snapshots to identify affected states of your components with that feature.
With this, we could test our UI code without writing specific test cases.
Anyway, you can’t rely on snapshot tests for 100% of your test requirements. You may need to write actual test cases to check user interactions.
This is not something exactly new, but the React version of snapshot testing is pretty interesting.
This cool React feature was recently introduced via Facebook’s Jest testing framework. Snapshot testing with Jest is super convenient to use, and tests run so quickly. Kudos to the Facebook engineering team for another useful tool.
Read more about React’s snapshot testing in this blog post.
Snapshots and Storybook
With Jest, you need to write a test suite like the one below to generate snapshots.
import renderer from 'react-test-renderer';test('Link renders correctly', () => {
const tree = renderer.create(
<Link page="http://www.facebook.com">Facebook</Link>
).toJSON();
expect(tree).toMatchSnapshot();
});
This is very similar to a list of stories in a Storybook.
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import Button from '../index';storiesOf('Button', module)
.add('default view', () => (
<Button>Hello</Button>
))
.add('some emojies as the text', () => (
<Button>😀 😎 👍 💯</Button>
))
Jest snapshot testing is written in a modular way, whereas other tools could pick and use just the snapshot testing feature. So we integrated Jest snapshot testing into Storybook. It’s a perfect match.
That will save the many developer hours you may have used to write UI test code.
Introducing StoryShots
If you already using Storybook, you already have a collection of stories in one of your storybook. This means you are all set to go.
If not you can use sample project like, React Button.
First of all, update @kadira/storybook to the latest version.
npm update @kadira/storybook
After that, you need to add the following NPM module into your app.
npm i -D @kadira/storyshots
Then add a NPM script as follows:
"scripts": {
"test-storybook": "storyshots"
}
Then run the following command:
npm run test-storybook
Here is the result of running it on our React Button project. You should see a similar output.
Since this is the first time you run it, it won’t find any previous snapshots to compare against. Therefore, it just saves a bunch of snapshots in your Storybook config directory.
Now, make some changes to one of your components and run snapshot tests again with:
npm run test-storybook
It’ll indicate an error and show you a diff view like this:
If all of those changes are intentional, you can update snapshots by invoking the following command. (with the -u option).
npm run test-storybook -- -u# Here, we use "--" before adding our actual options.
# That’s because of the use of NPM scripts. In NPM scripts, you can provide options after "--".
Interactive mode
Sometimes a code change could affect a large number of stories. It would be easier if you could go through the list of stories one by one and update only the necessary snapshots instead of all.
Use the -i option to run snapshot tests interactively.
npm run test-storybook -- -i
Watch mode
You can also watch code changes and run snapshot tests for every change. You can simply do this by passing the -w option as shown below:
npm run test-storybook -- -w
With StoryShots, we are running Storybook stories in a server environment. We try our best to mimic a browser environment inside the server. It works in most cases, but it’s challenging.
So, we have some options and features which help to get rid of these challenges.
Have a look at our Github Repo to learn more about these features.
Future Improvements
This is just the start. We’ve planned for a lot of cool features. Here are some notable features:
Integrate with the Storybook UI
With this, you can identify stories which have been changed from any UI code change. You could also inspect the diff right inside the Storybook UI.
You’ll also be able to update snapshots using a button (or a shortcut command) in Storybook.
Support for Additional Drivers
Jest’s snapshot testing is just one solution for snapshot testing. We will have two more solutions shipped as drivers. They are:
- Browser snapshots — This will get snapshots by rendering your UI on a real browser.
- Image snapshots — This will get snapshots as images so we can test CSS and style changes as well
I think this is something you’d love to use with Storybook.
Give it a try and let us know how we can improve StoryShots.