What a nice feeling to get to write a tip right after the Vue.js Amsterdam! It was a boost, thanks to everyone that were so kind, friendly and curious about VueDose. Just so you know, if you’d like to write a tip here, just let me know!

To give you an impression on how Vue Amsterdam went, just see this picture taken by my friend GustoJS and his amazing camera.

Alex Adrian VueAmsterdam

Now let’s get serious and start with the tip!

Testing is still one of the most controversial dev topics, and deep vs shallow rendering is no exception. In this tip I want to make my point on why and when to use each of them.

Deep Rendering

Deep rendering, as the name states, renders all component tree given a root component.

In order to illustrate it, given this UserList.vue component:

<template>
  <ul>
    <li v-for="user in users" :key="user">
      {{ user }}
    </li>
  </ul>
</template>

<script>
  export default {
    props: {
      users: Array
    }
  };
</script>

That you use in an App.vue component like this:

<template>
  <div>
    <h3>User List</h3>
    <UserList :users="['Rob Wesley']" />
  </div>
</template>

<script>
  import UserList from "./UserList";

  export default {
    components: { UserList }
  };
</script>

Then it will give us the combined DOM Tree of both components:

<div>
  <h3>User List</h3>
  <ul>
    <li>
      Rob Wesley
    </li>
  </ul>
</div>

In order to check that, you can use Jest Snapshots. If you don’t know much about Snapshots, check the article The power of Snapshot Testing that goes deeper into them.

When using @vue/test-utils, the official Vue.js testing library, you can perform deep rendering by using the mount method.

With these clues, you can imagine the previous snapshot was taken from a test with a shape like this:

import { mount } from "@vue/test-utils";
import App from "@/App";

describe("App.vue", () => {
  it("Deeply renders the App component", () => {
    const wrapper = mount(App);
    expect(wrapper.html()).toMatchSnapshot();
  });
});

Shallow Rendering

Opposite to deep rendering, shallow rendering only renders the component that you’re testing without going into deeper levels.

To implemente shallow rendering, you can use the shallowMount method from @vue/test-utils.

If you rewrite the previous test to use shallow rendering:

import { shallowMount } from "@vue/test-utils";
import App from "@/App";

describe("App.vue", () => {
  it("Shallow renders the App component", () => {
    const wrapper = shallowMount(App);
    expect(wrapper.html()).toMatchSnapshot();
  });
});

You’ll see that the generated snapshot is:

<div>
  <h3>User List</h3>
  <userlist-stub users="Rob Wesley"></userlist-stub>
</div>

What happened? Basically Jest has created the <userlist-stub> tag automatically instead of creating and rendering the UserList component.

Notice one point: the UserList component wasn’t even created, meaning the component isn’t used at all. Not their props, not their lifecycle hooks… nothing. You’ll see now why that’s important.

What to Use and When

Taking back some testing theory, a test should be:

  • Independant from others
  • Focus on testing one thing
  • Easy to maintain and stable over the time
  • Valuable

And as you may see already, when you use deep rendering you’re already violating the first three points, since every time a child component changes, you’ll test will fail.

Additionally, imagine a child component performs side effects, like interacting with the store or calling an API. That could be even worse since the results might be unexpected.

That’s why, my take on this is: Use shallowMount most of the time.

The question is: When not to use it?. I’ll use mount just in those cases that you’re testing a group of components as a unit, treating them as molecules.

Think of UserList and UserListItem, or Tab, TabGroup and TabItem. For those cases, it makes sense to use deep rendering when you want to test the interaction of the whole group working together.

Follow Up

To end up I wanted to share that I’ll be giving the workshop Vue.js Testing for Everyone in Vue Day Italy, Verona, on 4th April.

In that workshop you’ll be able to learn all the techniques and best practices to test a Vue.js App, step by step and in the most practical way. Definitely we’ll cover this content in a much deeper way.

That’s it for today’s tip!

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 soon.

Don't miss anything! Continue reading on VueDose

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

Latest Vue Jobs