The power of Snapshot Testing in Vue.js
If you are into testing, you probably have used Jest: the all-in-one testing framework created by Facebook. Right now is the most popular tool out there and I've been using it since the first time I've tried it.
To test Vue.js components, you also have vue-test-utils written by Edd Yerburg, the official helper library that makes testing Vue.js apps easier.
This is an example of tests using both Jest and vue-test-utils:
it('has a message list of 3 elements', () => {
const cmp = createCmp({ messages: ['msg-1', 'msg-2', 'msg-3'] })
expect(cmp.is('ul')).toBe(true)
expect(cmp.find('.message-list').isEmpty()).toBe(false)
expect(cmp.find('.message-list').length).toBe(3)
})
it('has a message prop rendered as a data-message attribute', () => {
const cmp = createCmp({ message: 'Cat' })
expect(cmp.contains('.message')).toBe(true)
expect(cmp.find('.message').props('message').toBe('Cat')
expect(cmp.find('.message').attributes('data-message').toBe('Cat')
// Change the prop message
cmp.setProps({ message: 'Dog' })
expect(cmp.find('.message').props('message').toBe('Dog')
expect(cmp.find('.message').attributes('data-message').toBe('Dog')
})
As you can see, vue-test-utils gives you many methods you can use to check props, classes, content, search, etc. It gives you methods to change stuff, like setProps
, which is pretty cool.
This test has very specific assertions in the form of "Find an element with a 'message' class and check if it has a 'data-message' set to 'Cat'".
But what if I tell you that... you don't need to do that with Snapshot Testing?
Basically, you can rewrite the previous tests by using snapshots in the following way:
it("has a message list of 4 elements", () => {
const cmp = createCmp({ messages: ["msg-1", "msg-2", "msg-3"] });
expect(cmp.element).toMatchSnapshot();
});
it("has a message prop rendered as a data-message attribute", () => {
const cmp = createCmp({ message: "Cat" });
expect(cmp.element).toMatchSnapshot();
cmp.setProps({ message: "Dog" });
expect(cmp.element).toMatchSnapshot();
});
The value of the tests will remain the same, or it can have even more since sometimes you find non-related regressions in snapshots.
Notice that in this test I've just used toMatchSnapshot
for the assertions, and that's all. That makes testing much easier and quicker since you don't need to check every specific thing.
The dynamics of testing changed: instead of writing specific assertions, you set the component state in any way you need and take snapshots of it.
Snapshots are meant to assert the rendering state: they describe how the component is rendered given a specific state, and in later runs the snapshots are compared to check its validity.
Keep in mind that not always snapshot testing is what you need. It depends on what you need to test.
I can't fit more in a tip, but if you want more information you have the book Testing Vue.js Components with Jest where I added last week a whole section on snapshot testing, including:
- Rethinking in Snapshots
- Why, how and when to use snapshots
- When not use them
- Code examples
Please tell me what you think about it! You can find me on twitter 🙂
Related Articles
Hybrid Rendering: the secret way to smoothly test Vue.js components
Find out how to combine Deep and Shallow Rendering in order to achieve a flexible solution to test your Vue.js combining the best of both worlds.
Mar 7, 2022
Deep vs Shallow Rendering in Vue.js Tests
A short article on how to use deep and shallow rendering in Vue.js and what I suggest to use most of the cases using vue test utils.
Mar 3, 2020
Quick Content Testing using Snapshots in Vue.js
Useful tip about how to use snapshot testing in Vue.js the right way and have consistent and coherent tests in your applications
May 28, 2019
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.