EXAMPLE OF A TEST CASE
Consider a mobile application, let's say, of Coding Ninjas. Now it has a UI component called the login page. Here, when the test is run, it will take a snapshot. Then, we will compare the reference snapshot file stored alongside the trial. Here are two cases if the test fails. One, it will fail if two snapshots will not match, and second, when the difference is something unexpected, like with the new version of UI, the reference snapshot needs to be updated.
EXAMPLE OF SNAPSHOT TESTING WITH JEST
Let's take an example where we will test the react components. Here, we can use a test renderer to generate a serializable value for the React tree quickly.
import React from 'react';
import renderer from 'react-test-renderer';
import Link from '../Link';
it('renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.codingninjas.com">CodingNinjas</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});

You can also try this code with Online Javascript Compiler
Run Code
Now Jest will create a snapshot like this when it will run for the first time.
exports[`renders correctly 1`] = `
<a
className="normal"
href="http://www.codingninjas.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Coding Ninjas
</a>

You can also try this code with Online Javascript Compiler
Run Code
Jest uses an excellent format to make snapshots human-readable during code review. It simply compares the output with the previous snapshot. If it's a match, then the test case will be passed. Next, an error will be thrown when the test renderer finds any code bug; this needs to be rectified by updating the referred snapshot or changing the implementation.
UPDATING SNAPSHOTS
The test case will fail when a snapshot runs and a code identifies a bug. We need to ensure that the snapshot tests pass successfully to fix this. Now, let's see that the snapshot test is failing due to an implementation change, and it is pointing to a different address of a link component.
// Here test case with a Link to a different address
it('renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.twitter.com">Twitter</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});

You can also try this code with Online Javascript Compiler
Run Code
If the address is pointed to the correct link, the output will be printed, and if it's changed or given incorrect, the snapshot will be failed. The following output will be printed by Jest in case of ambiguity.

Rendering: Therefore, when we update a component to point to a different address, we expect the changes in the snapshot of this component. However, the snapshot test case failed because the snapshot for the updated part no longer matches the snapshot artifact for the test case. We need to run Jest with a flag to regenerate snapshots to update the snapshot artifacts.
jest -updateSnapshot
We can run this command and accept the changes. We can also use the equivalent single-character -u flag to regenerate snapshots. That's how it will restore the snapshot artifacts for all failing snapshot tests. We can limit the snapshot test cases' re-generation, bypassing an additional --testNamePattern flag to re-record snapshots; it is only for those tests that match the pattern.
INLINE SNAPSHOTS
Inline snapshots act the same way as external snapshots (.snap files), except the values are written automatically back into the source code. Here, we can get the benefits of automatically generated snapshots without switching to an external file to ensure the correct values were written.
Example
Start by writing a test, calling .toMatchInlineSnapshot() with no arguments:
it('renders correctly', () => {
const tree = renderer
.create(<Link page="https://codingninjas.com">Coding Ninjas Site</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot();
});

You can also try this code with Online Javascript Compiler
Run Code
Now, when the next time we will call Jest the tree will be checked and a snapshot will be written as the argument to toMatchInlineSnapshot:
it('renders correctly ', () => {
const tree = renderer
.create(<Link page="https://codingninjas.com">CodingNinjas Site</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot(`
<a
className="normal"
href="https://codingninjas.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Coding Ninjas Site
</a>
');
});

You can also try this code with Online Javascript Compiler
Run Code
We can even update the snapshots with --updateSnapshot or using u key in --watch mode.
SOME BEST PRACTICES
Snapshot is a tool to identify unexpected interface changes within the application – whether that interface is an API response, UI, logs. As with any testing technique, there are some best practices you should be aware of to make efficient use of it.
1. Treating snapshots as a code
Commit snapshots and review them as part of our code review process. This means treating snapshots as any other type of test or code in your project. We need to make sure that our snapshots are readable by keeping them focused and short. Our motive is to make it easy to review snapshots in pull requests and fight against the habit of regenerating when test suites fail instead of examining the root causes of their failure.
2. Tests should be deterministic
The tests should be deterministic, and it's highly required. Running the same tests so many times on a component that has not changed should produce the same results every time. We are responsible for ensuring that the generated snapshots do not include platform-specific or other non-deterministic data.
3. Use descriptive snapshot names
Always make sure that we use descriptive tests or snapshot names for snapshots. The best words describe the expected snapshot content. This makes it helpful for reviewers to ensure that the snapshots are validated during the review process and makes it better for us to know whether or not an outdated snapshot is a correct behavior before updating.
FAQs
-
Why is snapshot testing necessary?
To make sure that UI works fine when in use. We need to do snapshot testing.
-
Are Snapshot testing and unit testing the same?
No, both are entirely different. As in snapshot testing, we are just concerned about the look and feel of our application, whereas in unit testing, we check the complete functionality of our application.
-
Is it necessary to commit snapshot files?
Yes, as snapshots will represent the state of the source modules at any given point in time. That’s why commission of snapshot files is required.
-
Why is snapshot testing different from visual regression testing?
As snapshot testing doesn't work pixel by pixel like visual regression testing. Instead, in snapshot testing, values are serialized, stored within text files, and approximated using algorithms.
KEY TAKEAWAYS
We tried to brief you about snapshot testing for a React component in this blog. You have learned various steps to accomplish this through this blog while this testing gets done.
Snapshot testing is defined as one of many different testing tools. Hence, it plays a significant role in creating a project. Through this blog, you have explored the basics of snapshot tests; there is a lot you can learn about writing better snapshot tests. Keep on practicing.
Do check out our other testing blogs that will help you be better at the testing part, which is a part of the development of any application. A few of the blogs you can go through are some exciting testing blogs like Usability Testing, Performance Testing, etc. Do upvote the blog if you found it worth reading.