Snapshot Testing: Example and Its Benefits

Snapshot Testing: Example and Its Benefits

Snapshot testing has recently become widely popular in front-end development. And for a good reason.

As an instrument, snapshot allows running the app through rigorous testing, increasing the test coverage, automating manual processes when writing scripts, and more.

So, today we’ll detail the snapshot technology and explain how it works in simple words.

First Things First – What Is Snapshot Testing

Snapshot testing was born due to the need to simplify the process of writing tests for react components. If you’ve ever written detailed and thorough tests, you probably know that it is a time-consuming process. So, snapshot testing serves a critical mission – to help developers quickly and efficiently generate tests.

In a nutshell, snapshot testing is a process of taking “an image” of the system and rendering the components into text (a snapshot). Once the components are snapped, this technology will compare the recorded snapshots during future executions.

Unlike many other UI testing methods, this method never asserts the correct behavior of the application functionality. Instead, it carries output comparison. In other words, this technology ensures your output behaves the way it is supposed to, without any ‘surprises’ rather than showing whether the code works.

Snapshot Testing of the Demo Project Based on Angular and Jest

Let’s see how Snapshot Testing works through an example – our Angular demo project tested with the Jest framework. You can find more details in the project repository.

We created a simple app that contains a list of Secret Agents. You can see their names and hire them. The app allows you to swap the layout from right to left and left to right and sort the agents by name.

Snapshot Testing: Example and Its Benefits

There are two components in the app:

1.A container with the title, two buttons (SWAP LAYOUT and SORT BY NAME), looping through a cycle for our Secret Agents, and component (map) rendering.

2.Cards for every Secret Agent.

HTML Code Testing the Hard Way

Want to know the difference between snapshot testing and traditional testing methods? We’ll show you its perks by testing the card component. And first, let’s see how traditional testing will cope with the task.

So, every time we apply SWAP LAYOUT, our card layout has to change. Literally, the title and the button switch their positions.

Snapshot Testing

The code snippet you’ll find below allows you to perform those actions. As you see, it has the Secret Agent card and two containers. Depending on the condition, this or that template will be rendered.

Snapshot Testing Benefits

Left-to-right layout test

So, let’s write the first test for the left-to-right layout. In this way, we’ll check whether the title is located before the button. So, we expect H4-tag to be next to the button, which we’ve selected earlier.

Take a look at the code below, and you’ll find the it() function, which has two parameters. The first parameter is the title that explains the purpose of the test. The second parameter is the predicate, where we mock our Secret Agent and the layout. Then, we re-render the component to get the required DOM and get the title and layout using .querySelector.

Snapshot Testing: Example

We’ll write the same test to check if the button is located on the left.

Snapshot Testing: Example

As you run these tests, you’ll see the results.

Snapshot Testing: Example

Right-to-left layout test

Let’s write the same test for the right-to-left layout. The syntax is the same, but we’ve changed the component layout into right-to-left and the validation that our title should be after the button.

Snapshot Testing: Example

Again, here is the code for checking whether the H4 tag is positioned before the button.

Snapshot Testing: Examples

As we run the test, we’ll see four results testifying that all functions work flawlessly.

Snapshot Testing

No-layout mode test

Let’s test one more case when no layout mode is specified.

Snapshot Testing

In this case, the default layout should be left-to-right.

Snapshot Testing: Example

There would be six tests, and you’ll see their results. In our case, all of them are successful.

Snapshot Testing: Example

Change Request: Add Agency

Let’s assume that we’ve got the change request to add an agency to the card. In other words, we’ve got to add the agency that would be located between the secret agent name and the button.

Snapshot Testing: Examples

Besides, as you swap layout, the agency should remain at the same place, while the button should go left and the agent name should be moved to the right side.

Snapshot Testing: Examples

 

 

 

That’s what we updated in the code to bring those changes to life. As you can see, we used an old code but added the <p> tag line containing information about the agency between the containers.

Snapshot Testing: Example

But as we run the test, we’ll fail all of them. The results are pretty straightforward, agree? As we were writing the test, we didn’t expect the <p> tag to be located between the agent name and the button, so we used next sibling / previous sibling selectors.

Snapshot Testing: Example

Snapshot Testing

Once you revisit the code to make updates, those changes might cause something to break. So, every time we would be applying any changes to the code, our tests would fail, and we would have to refactor them. These issues would occur after every change request, and it would be inefficient to refactor tests in terms of time input and results sooner or later.

HTML Code Testing Using Snapshots

Let’s go back to where we didn’t have any agency tags and tested the swap layout.

Snapshot Testing

We rolled back the code, so there is no <p>Agency</p> tag out there.

Snapshot Testing

Let’s write the test to check the components’ HTML using snapshots. The code looks pretty much the same. We mock the agent, set the layout, and wait till it renders. Then we expect the render that would be sent to DOM to match the snapshot. Below you can see the piece of code for the left-to-right layout.

Snapshot Testing

The same thing for the right-to-left

Snapshot Testing guide

and no layout modes.

Snapshot Testing guide

 

The test results would be the following:

Snapshot Testing how to

Snapshot Testing: How To guide

Let’s take a look at what happened during the tests.

So, What Happened?

As we start the test, the availability of snapshots would be checked first. The snapshot gets generated automatically as we run the first test. In this case, the test is successfully completed.

You can find the snapshot along with other testing files. It is a file that contains text rendered from HTML, including information about the test title and its value.

Snapshot Testing: Example and Its Benefits

Change Request: Add Agency

Let’s see how snapshot testing would work on the condition when we add a new Agency tag.

So, we add the <p> tag between the containers, just like in the previous case.

Snapshot Testing

But the test will fail again, meaning that something in the code is broken. But the greatest advantage of snapshot testing is that it shows the changes that could have caused the test failure.

how does Snapshot Testing works

Snapshot Testing

This drives us to two conclusions. First one, this change is expected. We added the <p> tag and that’s the way it should go. And the second one is that this change might be unexpected, and we have no clue how the <p> tag was added to the code.

What’s Next?

So, we start another snapshot test. According to the algorithm, it would first define whether there is a snapshot among the files. Since this is our second test, the snapshot has been already created. After this, we compare the first and second snapshots if they match or not.

  • On condition the snapshots match (meaning no changes in the code were made), the test would be successfully completed.
  • When the snapshots don’t match, you’ll see the failure in the test results. But Tthis is not the end, as the next actions will depend on whether the snapshot changes are expected or not.
  • If the changes are unexpected, the testing ends, and we’ve got to go back to the code and figure out what caused the error.
  • In case the changes are expected, and we deliberately change the code, we update the snapshot by clicking the ‘U’ button on the keyboard to update the snapshot. That’s it. The test will be marked as successfully completed.

So, snapshots make testing much easier. You can easily track code changes and fix errors. Also, it is easier to update the components when they change. Compared to a traditional testing method, snapshot testing increases test coverage.

Mocking Objects

Let’s get back to our demo project, but this time test the container’s functionality – Sort by name.

Snapshot Testing

Snapshot Testing

We use the basic sorting method, so let’s see how it works through traditional and snapshot testing methods.

Snapshot Testing how to

Testing the Traditional Way

We save the sorting results to variable and then expect the sorted agents to be equal to something. We are still uncertain about this since there are several options how can we get the sorting result.

Snapshot Testing guide

We can either do it manually, which is not a good idea. Or we can bring the result to the console, then mock it, and…

Snapshot Testing tutorial

… add the result in this way. This is a common practice for sorting, searching, or other features.

Snapshot Testing tutorial

We’ll pass the test as we run it.

Snapshot Testing: Example

Change Request: Add New Agent

But what test results would we get once we’ve got to change the request and add a new agent?

Snapshot Testing guide

On running the test, we’ll fail it. So, we’ve got to fix it somehow.

Snapshot Testing manual processes loop

testing with Snapshot

To fix this issue, we go to the test file, give comments, bring the result to the console, mock and paste it, run the test once again, and that’s it. We passed the test. But it might not be the way you want to fix the issues.

So, what’s the problem? Every time there is a change in the code, our tests fail. So, we’ve got to bring the result to the console, mock it, and repeat the test. Whether you add, delete an element or just update the code, you’ve got to go through the loop of manual processes endlessly.

So, let’s automate this process through snapshot testing.

Testing with Snapshots

Instead of mocking the result, we will compare it with the snapshot.

testing with Snapshot

So, once we run the test, we will create the first snapshot file. We turn both Render and an object array into text.

Snapshot Testing

We’ll successfully pass the test.

testing Snapshot

Change Request: Add New Agent

Again, we add a new element – a new agent Dizzy Rider to the object array.

Snapshot Testing

But the test will fail since the snapshots won’t match due to a new object. We can assess whether this object is expected or unexpected and then act based on the result of our decision-making.

Snapshot Testing - how to

We added the fifth element to the object array on our own. So we just hit the ‘U’ button, and the testing ends successfully.

Snapshot Testing guide

As we open the snapshot file, we’ll see five objects instead of four.

Snapshot Testing tutorial

The Pros and Cons of Snapshot Testing

Just like any testing method, snapshot testing has its strong and weak sides.

Pros of Snapshot Testing

We’ve already seen the greatest perks of snapshot testing while testing our demo project, so let’s just sum them up.

Snapshot testing allows you to:

  • Improve tracking changes that affect the application
  • Avoid errors related to manual work
  • Decrease testing time by eliminating manual work
  • Boost test coverage

Due to its nature, snapshot testing works great for apps with already written code. When the code has been tested manually, and we know that it works, we don’t have to write large unit tests. All you’ve got to do is to run the snapshot test and record the first snapshot, which would allow you to compare it with the next versions.

Snapshot testing is also a good solution for refactoring when you’ve got to refactor a class or a method while maintaining its functionality.

Cons of Snapshot Testing

One of the disadvantages of snapshot testing is that there is no test-driven support. But it doesn’t make a big difference since it is very unlikely that developers or testers will be attempting to manually create snapshot files.

The overuse of snapshot testing is not beneficial as well. Replacing unit or functional tests with snapshot testing can be ineffective in certain situations.

Another issue of this testing method is that it can lead to merge conflicts. Every snapshot file should be added to the repository so other developers can have a source to compare the result of their test. As multiple developers work on the same component, this could be the reason for the merge conflict. Resolving merge conflicts can be cumbersome, especially when the snapshot is large.

Wrapping It Up

Snapshot testing is a fantastic tool for ensuring your UI does not change unexpectedly. It has numerous advantages and allows you to increase test coverage, track how changes affect the results, and diminish manual errors in the code.

But just as great as this testing method is, you should use it with caution. You should never accept the changes blindly and know the situations when it is effective. Also, even though snapshot tests are easier to carry, you should never replace unit or functional tests with snapshots. These tests do not testify that the app operates properly. They just prove whether the code hasn’t been changed and how the changes affected it.

Check out the demo code following this GitHub link

Bug Free App – A Myth or Reality?

There’s a reason why the global bug tracking software market expected to reach $601.64 million by 2026. And the reason is very simple – because every digital product has bugs and requires maintenance. Think of it like this: your digital product is like a house. Imagine that you built a house following all standards, using […]

Zorian Fedoryga Avatar
Zorian Fedoryga

27 Jan, 2023 · 6 min read

End-to-End Automated Testing with Cypress

Software development is getting more complicated, so every QA team needs to concentrate on boosting test coverage. To achieve this, it’s essential to use a variety of testing types, such as integration testing, system testing, performance testing, and end-to-end testing, depending on the complexity of your software application and requirements. In case end-to-end testing sounds […]

Marian Turchyn Avatar
Marian Turchyn

8 Sep, 2023 · 7 min read

UI Testing with Selenide

Ensuring your applications work flawlessly is non-negotiable in software development. Poor software quality costs US companies over $2.08 trillion annually due to defects and bugs — impacting businesses across industries. But fear not! We’re here to introduce you to Selenide, a dependable tool for UI testing. Selenide simplifies the complexities of testing, making the process […]

Oleksii Driuk Avatar
Oleksii Driuk

15 Jan, 2024 · 5 min read