The power of Snapshot Testing in Vue.js

#Testing

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 🙂

Remember you can read this tip online (with copy/pasteable code), and don’t forget to share VueDose with your colleagues, so they also know about these tips as well!

See you next week.

Alex

Do you want to sponsor a VueDose tip? Send an email to info@vuedose.tips and have more info!

Start saving time and get a tip about the Vue ecosystem every week, right in your inbox.