I'm writing tests for this function that generates a formatted list of this elements given. Before Jest snapshotting, when I wrote this kind of test, I would console log the results and then copy/paste it into my assertion like this. Then I commit the code with git commit -am add assertion and move on. Doing this makes it so people don't accidentally break the formatting when making changes. Now let's say the formatting needs to change, let's say we want to indent each item in the list with two spaces.
We'll see that our test is broken, which is what we expected. Now let's update the list output in the test. Now when we go to make our changes in the pull request, the diff will look like this. It's pretty clear for code reviewers to see what's going on here, and they can confidently approve the pull request. Now let's try using Jest snapshot testing to improve this workflow. Let's go ahead and reset ourselves to where we were before we added that first assertion with git reset --hard add ^.
Now we'll start Jest watch made again. Instead of logging out the results of formatting lists and pasting it into our assertion, let's use Jest API to take a snapshot of the formatted list with expect(formattedList).toMatch(snapshot). When our tests run, we'll see the snapshot summary indicate that we wrote one snapshot and one test file. If we look at our file system now, we have a new snapshots directory with a corresponding .snap file for our test.
If we open that up we can see that Jest effectively did the same kind of copy/paste we did, except that Jest did it for us. Let's go ahead and add all of our changes with git add -a, and then commit this with git commit -m add list test snapshot. Now let's say we need to update the format to indent the items with two spaces again. Let's go ahead and fire up Jest watch mode, now we'll make our change and save the file. Jest has rerun our test and we have our error.
This time, the error is indicating that the problem is the received value doesn't match the stored snapshot. If we look at our snapshot summary, we can see that it's telling us to either fix our code, or update the snapshot by pressing the U key. Because we know this is the change that we want, we'll press the U key. With that our tests are now passing and our snapshot summary tells us that he snapshot was updated. Let's look at the git diff for this pull request now.
It looks almost identical to the last time we make these changes, except this time we didn't have to do any copy/paste or manual updating of the screen. Snapshot testing works great for anything that can be serialized, or example objects, arrays, or even React components. Let's make a change teach of these, and see the snapshot diff. We'll add a property to the object, remove an item from the array, and add a word in our React component.
With Jest rerunning our tests we'll see the snapshot diff right in our console. If we're happy with these changes we can simply hit the U key, or we can fix our code until it matches the snapshot. We'll just go ahead and update the snapshot for all of these. Now let's go ahead and take a look at the git diff. This is what code reviewers will see when we make our pull requests. The impact of our changes is very clear by looking at this git diff.
One thing to note is that if you're not running Jest in watch mode, you can still update the snapshots by running Jest with -update snapshot flag, or with the -U for short.
In review, to use snapshot testing with Jest, you simply pass your serializable variable into expect and invoke toMatch(snapshot) on it. Then you develop normally, and update snapshots as needed. When you're ready to push your changes, make sure to include the updated snapshots in your pull requests, so reviewers can see how your changes impact the output.