Jest: How to Update Snapshot Tests

By Michael T. Andemeskel

October 6th, 2021

image

Snapshot tests are a great way to test UI without manually checking every element is visible, styled, and in the right place. Each snapshot test has a snapshot, JSON, JS, or HTML file, that usually lives in this directory /__snapshots__. These snapshots serialize the UI at the time of your choice and save it into this directory to be used for future comparison. Every time the snapshot test runs, a new snapshot is generated and compared to a saved snapshot in \__snapshots__. This is how snapshot tests detect changes in the UI but what if you intended the change? How would you update the saved snapshots to reflect intended changes?

This is the workflow I use to ensure that snapshot tests are updated with the intended changes:

  • *Run the snapshot test, make sure it passes — if it does not pass, find the problem and fix it, don’t change the UI until the test passes.

  • Change the UI.

  • Rerun the snapshot test, it should fail, and in that failure, it should detect the UI changes you've made — if it fails for other reasons, then you’ve probably introduced a bug into the code that needs to be fixed.

  • Update the snapshot files.

  • Rerun the snapshot test; it should pass — if it fails, you probably updated the wrong snapshot files.

  • Commit the changes to the UI and the snapshot files.

*This breaks Test Driven Development since we can’t write the tests ahead of time. Snapshot tests are not meant to drive development; therefore TDD does not apply to them. Also, it is a waste of time to anticipate what the snapshots will look like and edit the snapshots manually.

Run the Snapshot Test

I use yarn but you can also use npm to run the snapshot tests:

yarn jest tests/snapshot_tests

I’m using Vue, so the test command uses the Vue CLI, which ensures important Vue environment variables are loaded and work in NodeJS. The Vue CLI eventually does call jest:

yarn vue-cli-service test:unit tests/snapshot_tests

The output should be:

Change the UI

I made a trivial change in the wording of a label.

Before:

<label for="invoiceNumber">Select {{ reference_label }}</label>

After:

<label for="invoiceNumber">{{ reference_label }}</label>

Rerun the Snapshot Test — Confirm it Fails on the Changes

The label was changed from Select {{ reference_label }} to {{ reference_label }}. I expect the snapshot test to catch this change, so rerun the test and you should get:

Two things to notice here:

  • The snapshot name Transaction Form renders correctly 1 is taking from the test suit name Transaction From plus the test case name renders correctly and Jest appends a 1  — I assume to avoid duplicates?

  • The snapshot points out where the failure occurs in the rendered HTML but not in the Vue code. You will need to go to the line number provided below the failure output (the link highlighted in blue at the bottom of the screenshot) for the cause of the bug. Nonetheless, this is a great way to see what the UI change looks like and determine if the change is a bug or intended.

Update the Snapshot Files

This will overwrite the existing snapshot with a new one with the UI changes you made.

Using Jest:

yarn jest tests/snapshot_tests/TransactionForm.spec.js -u

Using Vue CLI:

yarn run vue-cli-service test:unit 'tests/snapshot_tests/TransactionForm.spec.js' -u

-u is short for --updateSnapshot.

Rerun the Snapshot Test — It Should Pass

Using Jest:

yarn jest tests/snapshot_tests/TransactionForm.spec.js

Using Vue CLI:

yarn run vue-cli-service test:unit 'tests/snapshot_tests/TransactionForm.spec.js'

Commit the Changes

Now that the UI is updated, the snapshots are updated, and the tests are passing, you need to commit all the changes:

  • The UI changes, of course.

  • The updated snapshot file.

Snapshot tests only work if you store and share the snapshots with your teammates. Therefore you need to commit the snapshots. That being said, they are large files, and they can clutter your pull requests. I usually skip reviewing the entire snapshot. Instead, I rely on screenshots of the UI change and finding the UI change in the snapshot.

Obsolete Snapshots

Sometimes you will run into obsolete snapshots when running snapshot tests:

This means somewhere in your, tests you renamed a test suite or case, and Jest can’t map the snapshot test to the snapshot file because the names don’t match. Remember snapshot files are identified by the test suite name plus the test case name.

Fix this by updating the snapshot file. This will override the old snapshot with the new one with the correct name. You will need to do this every time you change the test’s suite or case names.

Sources

  • Overview of snapshot tests in Jest

  • Vue CLI unit test docs

  • Obsolete snapshot tests



Continue Learning