We were able to write some unit tests for
Button
component in previous lesson. What if I tell you that we're able to cover all parts with almost 2 lines of testing code? Let's check how snapshot tests works and what you can achieve and what you can lose with them.Creating snapshot test
Sometimes if you're writting presentational component you'll produce big
DOM
tree. How to test such components? You can try to compare generated properties with expected ones.
const { container } = render(<Button />);
const button = container.queryByClassName()
// We already know that it's fragile test.
// If order of generated classes change - test will cause false negative.
expect(button?.className).toBe(
'button button-size-2 button-rounded button-outlined button-secondary my-button'
);
What if you need to verify other properties like
style
object. It may be really complex object, you can check how complex in following article
. To achieve it fast someone smart invented snapshot testing.Imagine you are playing a computer game and you saved your progress. Bravo! It's a snapshot test. Now every time you lose you can start from a safe moment.
So how it works in
jest
and React
? You need to replace previous test with following one:
const { asFragment } = render(<Button />);
// Button is already rendered.
// asFragment() creates big string with generated HTML nodes.
// toMatchSnapshot() saves generated string and now it's base for comparision.
expect(asFragment()).toMatchSnapshot();
When you run
test
command the __snapshots__
directory will be generated near your test file. Inside you can find following snapshot file: Check the following gif to understand how you can use snapshots in daily basis:
Truth about snapshot testing
You may be thinking now - great I will use this new approach everywhere. This will be a big mistake 🚀. These tests must be used carefully. They're easy to write but hard to maintain. They will fail always when something change so you need to manually check these changes. They're are useful to prevent "any" regression but when overused they cause headaches.
Also, they're much more fragile than previous test with
className
check. If you change button to span - they will fail. If you add additional property to component - they will fail. You need to go through changes and check they are valid or not. To avoid problems with maintenance create snapshot tests only if:
A very important point is namely that if our snapshot is saved when the component is not working properly, such tests begin to be a problem. You need to be careful and focused when using them.
To understand what damage they can cause - it is enough to change the snapshot of the component at the moment when it works incorrectly, and then push these changes to the repository. Good luck with fixing and reviewing hundreds and thousands of such tests.
I personally use them very rarely. I prefer to have more complex test code, and even implementation-dependent, than to rely on something that checks any change.
How to work with snapshot tests?
Check out the list below:
Look at following test file to understand how I'm using snapshots:
We learned today snapshot tests and how useful/harmful they can be at one time. Tests should be reliable, stable and should answer the question - whether something works or not, so snapshots should be used with caution.
If you enjoyed it, be sure to visit us on
Linkedin
where we regularly upload content from programming.- 1. Basics
10 minutes
Software testing
2 m
Grouping the tests
1 minute
The usage of describe and it
2 m
The best practices for naming tests
2 m
Types of tests
3 m
- 2. Mastering unit testing
31 minutes