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
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
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
Select `ESLINT + standard config as linter/formatting config
Step 4
Select lint on save as additional lint config
Step 5
Select Jest as the testing framework. We will be using jest as our test runner.
Step 6
Select package.json
file for your config store
Step 7
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:
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.