Cutting corners during testing can lead to false confidence and, ultimately, a faulty app. Learn how to test Vue components using Vue Testing Library.

Testing is crucial in the development of any application. Cutting corners during the testing phase can lead to false confidence and, ultimately, a faulty app.

In this tutorial, we’ll demonstrate how to test Vue components using Vue Testing Library. While there are countless other testing libraries we could use, I’m a proponent of testing your application the way your users would use it, and that’s precisely what Vue Testing Library aims to do.

Vue Testing Library a member of the Testing Library family, which includes React Testing Library, DOM Testing Library, and more. It builds upon Vue Test Utils, the official testing library for Vue, and DOM Testing Library, which enables it to use features from the Testing Library family.

Prerequisites

To follow along with this tutorial, you should have:

  • Node > 8.0.0 and npm > 6 installed on your machine
  • Vue CLI > 4 installed on your machine
  • A basic understanding of Vue
  • A basic understanding of testing using Jest

Setup

Since we’ll be creating and testing single-file components, you’ll need to create a new Vue project using the Vue CLI.

Run the command below to set up a new Vue project.

vue create testing-vue-components.

We can stick to the default Vue configurations since we’ll be installing any additional dependencies by ourselves.

Vue Testing Library can be used with a lot of testing frameworks, but we’ll use Jest for this tutorial.

Install jest and Vue Testing Library.

npm i --save-dev jest @testing-library/vue

Since we’ll be writing ES6, we need to use Babel to handle the compilation for us. Vue already ships with a Babel configuration, so we just need to install babel-jest and configure Jest to transform .js files using Babel.

npm i --save-dev babel-jest

Again, because we’re writing single-file components, we need to configure Jest to load .vue files. The vue-jest package helps with that.

npm install --save-dev vue-jest@4.0.0-beta.3

Finally, update the package.json to contain the necessary configuration.

"jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "transform": {
      "^.+\\.js$": "babel-jest",
      ".*\\.(vue)$": "vue-jest"
    }
  },

Testing simple components

When a user loads a page, they should be able to see the component, so the first thing to test should be that the component renders.

Consider this simple Counter component, which provides two buttons for counting and shows the number of counts:

// Counter.vue
<template>
  <div>
    <h3>Count: {{ counter }}</h3>
    <div class="button-container">
      <button @click="increment">Add</button>
      <button @click="decrement">Subtract</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Counter',
  data() {
    return {
      counter: 0,
    };
  },
  methods: {
    increment() {
      this.counter++;
    },
    decrement() {
      this.counter--;
    },
  },
};
</script>

To test the component, create a Counter.js file in the tests directory.

import Counter from '../Counter.vue';
import { render } from '@testing-library/vue';
test('It renders correctly', () => {
  const { getByText } = render(Counter);
  getByText('Count: 0');
});

The getByText helper checks that there is a text with the specified argument in the document. In our counter component, the initial state of counter is set to 0, so without clicking any button, we should have Count: 0 rendered to the document.

Other actions that a user might perform include clicking on both buttons, so we need to test those as well.

import Counter from '../Counter.vue';
import { render, fireEvent } from '@testing-library/vue';

test('It correctly responds to button clicks', async () => {
  const { getByText } = render(Counter);
  // Check initial state
  getByText('Count: 0');

  // Get buttons.
  const addButton = getByText('Add');
  const subtractButton = getByText('Subtract');

  // Click the Add button.
  await fireEvent.click(addButton);
  // Counter should be updated.
  getByText('Count: 1');

  // Click the subtract button.
  await fireEvent.click(subtractButton);
  // Counter should be updated.
  getByText('Count: 0');
  // Further clicks
  await fireEvent.click(addButton);
  await fireEvent.click(addButton);
  await fireEvent.click(addButton);
  await fireEvent.click(addButton);
  getByText('Count: 4');
  await fireEvent.click(subtractButton);
  await fireEvent.click(subtractButton);
  getByText('Count: 2');
});

Using getByText, we can get the buttons and click them just as a normal user would.

As the name implies, fireEvent is used to dispatch different events on elements. We’re awaiting events here because Vue updates the DOM asynchronously, hence all the events dispatched from fireEvent returns a promise which will get resolved on the next tick.

#vue #testing #developer

How to Test Vue Components using Vue Testing Library
8.75 GEEK