Writing Test In Vuejs Applications Using Jest

Getting started with Writing Test In Vue Applications


In this article, we will learn how to write test in vue using Jest as a test runner.

So what is exactly is Jest?… Jest is a delightful JavaScript Testing Framework that focuses on simplification of unit testing.

A unit test is a method that invokes another piece of code and checks the correctness of some assumptions.

If these written assumptions turn out to the wrong then the test has failed.

Before we write any test in vuejs, let’s write some simple javascript tests using jest.

So to do that let’s create a directory and generate a package.json for storing our application dependencies.

Let’s open our terminal and create a folder on our desktop for our application:

cd desktop
mkdir jest-test && cd jest-test
npm init -y

What we just did was to create a new folder jest-test in the desktop directory and the ran the npm init -y to generate a pacakge.json file for our application.

Now we can install Jest as a dev dependency in our application.

To install Jest run:

npm i jest -D

After successfully installing Jest, lets head over to the package.json file and modify the scripts object to this:

"scripts": {
    "test": "jest"
}

After doing this let’s create a file calculate.js and add the following codes:

let sum = (a,b) => {
  return a + b
} 
module.exports = {
    sum
}

Let’s create a folder called test and then create a file calculate.test.js inside the folder.

mkdir tests && cd tests
touch calculate.test.js

We will use the calculate.test.js file to test the calculate.js file. Now lets write a simple test to check the sum of two numbers:

const {sum} = require("../calculate")
test("Should Calculet the sum of two numbers",()=> {
    expect(4).toBe(sum(2,2))
})

We, first of all, require the sum method in the calculate.js file and after that, we define the test.

The first parameter in the test function is the name of the test while the call back function callback function that executes the test.

Running this code will pass the test because of the sum of 2 and 2 is 4.

To run the test type npm run test on the terminal and you will get an output of this :

wisdom-ekpot:tests wisdomekpot$ npm run test

> jest-test@1.0.0 test /Users/wisdom/Desktop/jest-test
> jest

 PASS  tests/calculate.test.js (6.232s)
  ✓ Should Calculet the sum of two numbers (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        18.715s
Ran all test suites.

Now let’s see how a failed test would look like. Modify the test function to this:

const {sum} = require("../calculate")
test("Should Calculet the sum of two numbers",()=> {
    expect(4).toBe(sum(1,1))
})

Running npm run test on the terminal would return a failed test because of the sum of 1 and 1 is not 4.

wisdom-ekpot:tests wisdomekpot$ npm run test

> jest-test@1.0.0 test /Users/wisdom/Desktop/jest-test
> jest

 FAIL  tests/calculate.test.js
  ✕ Should Calculet the sum of two numbers (9ms)

  ● Should Calculet the sum of two numbers

    expect(received).toBe(expected) // Object.is equality

    Expected: 2
    Received: 4

      1 | const {sum} = require("../calculate")
      2 | test("Should Calculet the sum of two numbers",()=> {
    > 3 |     expect(4).toBe(sum(1,1))
        |               ^
      4 | })

      at Object.<anonymous> (tests/calculate.test.js:3:15)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        15.186s
Ran all test suites.

Now, let’s write another test to calculate the sum of two floating numbers. To do this, let’s add the following codes to the calculate.test.js file.

test("Should calculate the sum of two floating numbers",()=> {
    let result = sum(0.2,0.1);
    expect(result).toBeCloseTo(0.3);
});

Running npm run test will pass the test because the sum of 0.2 and 0.1 is close to 0.3.

Now, let’s use the describe method to convert multiple test cases to become a simple test case. To do that, modify the calculate.test.js test cases to this:

describe("Sum Test Cases",()=> {
test("Should Calculet the sum of two numbers",()=> {
    expect(4).toBe(sum(2,2))
})
test("Should calculate the sum of two floating numbers",()=> {
    let result = sum(0.2,0.1);
    expect(result).toBeCloseTo(0.3);
})
})

Running the npm run test will output this on the terminal:

wisdom-ekpot:tests wisdomekpot$ npm run test

> jest-test@1.0.0 test /Users/wisdom/Desktop/jest-test
> jest

 PASS  tests/calculate.test.js
  Sum Test Cases
    ✓ Should Calculet the sum of two numbers (5ms)
    ✓ Should calculate the sum of two floating numbers (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.447s, estimated 5s
Ran all test suites.

Now that we understand some basic testing concepts, let’s move onto writing tests for our vue applications.

Let’s start by creating a new VUE CLI application. let’s create a new directory jest-test and then move into that directory. This is where we will be creating our vue application.

mkdir vue-test && cd vue-test
vue create vue-testing

Running the vue create vue-testing will create a new vue application. Before that, you will be asked some questions to set up the application.

Step 1

Step 1 -terminal output

Choose “Manually select features” and click enter so that we can be explicit about which libraries we want to include in our new project.

Step 2

Step 2 -terminal output

In this step, we need to select Unit Testing to add the appropriate libraries to our project.

To select and control an item on the list you can use your arrows to move up and down and then press the spacebar when you want to select/deselect a feature.

Step 3

Test In Vue
Step 3 -terminal output

Select `ESLINT + standard config as linter/formatting config 

Step 4

Step 4 -terminal output

Select lint on save as additional lint config

Step 5

Test In Vue
Step 5 -terminal output

Select Jest as the testing framework. We will be using jest as our test runner.

Step 6

Test In Vue
Step 6 -terminal output

Select package.json file for your config store

Step 7

Test In Vue
Step 7 -terminal output

If you want to save this as a preset you can by typing Y, if not type N and press enter.

When the Vue CLI finishes creating our application, we’ll open up the vue-testing folder in our text editor.

Looking at the package.json, we’ll see that Jest and vue-test-utils were installed by default.

To run the vue app run the following codes on the terminal:

cd vue-testing
npm run serve

After compiling, it will be outputted on the terminal that the application is running on port http://localhost:8080/.

Note that the port number might differ on some local machines.

Accessing http://localhost:8080/  on our browser we will have this displayed:

Test In Vue
Vue application

Now that we have successfully created the vue application, let’s start writing some tests. Before we do that, let’s clean up the UI. To do this head over to src/components/HelloWorld.vue and replace the code with this:

<template>
  <div>Testing App</div>
</template>
<script>
/* eslint-disable */
export default {};
</script>

After doing this lets head over to the tests/unit/example.spec.js  file, this is where we will be writing the test for our application.

By default we will see this in the file:

import { mount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      propsData: { msg }
    })
    expect(wrapper.text()).toMatch(msg)
  })
})

Now this test here checks if the component has rendered a props.msg.

We no longer need this because we have cleaned up the HelloWorld.vue file. So let’s modify it.

let’s write a simple test that will check that the component has been set up successfully. Now modify the file to this:

import { mount } from "@vue/test-utils";
import HelloWorld from "@/components/HelloWorld.vue";
describe("HelloWorld.vue", () => {
  test("Component setup successfully", () => {
    expect(true).toBe(true);
  });
});

After modifying it, we run the test by typing the npm run test: unit in the terminal. We will get this back in the terminal

wisdom-ekpot:vue-testing wisdomekpot$ npm run test:unit

> vue-testing@0.1.0 test:unit /Users/wisdom/Desktop/jest-test/vue-test/vue-testing
> vue-cli-service test:unit

 PASS  tests/unit/example.spec.js (20.397s)
  HelloWorld.vue
    ✓ Component setup successfully (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        37.477s
Ran all test suites.

In our HelloWorld.vue component, let’s add some codes that will increment a number is clicked:

<template>
  <div>
    <p>Counter:{{ counter }}</p>
    <button @click="counter++">Increment</button>
  </div>
</template>
<script>
/* eslint-disable */
export default {
  data: () => ({
    counter: 0
  })
};
</script>

Now that we have this component, let’s write some tests for some assumptions in this component.

So let’s define another test condition inside the described method.

This test will check if the value of the button will be incremented when the button is clicked.

test("Increments the value of the counter when button is clicked",()=> {

})

We will start by creating a wrapper using the result of the mount with the HelloWorld component passed as a parameter.

The first test will be to ensure the component state counter has a value of 0. To test that will use the expect assertion:

expect(wrapper.vm.counter).toBe(0);

Another test we are to write is to check that the counter value increments by 1 when the button is clicked. To do this we can use the find method.

The find method takes a selector and returns the first node that matches the selector. Then we can use the node instance to listen to when the button has been triggered.

const button = wrapper.find("button");
button.trigger("click");
expect(wrapper.vm.counter).toBe(1);

The test function should look like this at the end:

test("Increments the value of the counter when button is clicked", () => {
    const wrapper = mount(HelloWorld);
    expect(wrapper.vm.counter).toBe(0);
    const button = wrapper.find("button");
    button.trigger("click");
    expect(wrapper.vm.counter).toBe(1);
  });

Running npm run test:unit will output this on the console:

wisdom-ekpot:vue-testing wisdomekpot$ npm run test:unit

> vue-testing@0.1.0 test:unit /Users/wisdom/Desktop/jest-test/vue-test/vue-testing
> vue-cli-service test:unit

 PASS  tests/unit/example.spec.js (14.655s)
  HelloWorld.vue
    ✓ Component setup successfully (7ms)
    ✓ Increments the value of the counter when button is clicked (58ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        25.977s
Ran all test suites.

Conclusion

Unit tests are a crucial part of continuous integration. They make your code a lot more reliable by focusing on small, isolated entities and making sure they always behave as expected. You can confidently iterate on your project without fear of breaking things.


Share on social media

//