Appearance
Tests
Currently we are using Vue 3 + Typescript on the most recent repositories and Vue 2 on older ones. This changes the test framework we are using when making unit tests which this guide will cover. But as a start; we go through the similarities and a high-level guide on why, what, which structure and what library we use.
Why we test
It will achieve our users to be contentful and have a good performance experience using our applications. On the other hand, for us the developers, it will save a lot of time to resolve bugs or when adding new features it will not break previous behaviors of the code.
What to test
You can test the components' behavior, such as whether
- an event was emitted
- a data property was correctly updated
- a computed property is correctly calculated.
Structure
We aim to use the AAA-structure. Arrange, Act, Assert.
Each test should start with an arrange section, then the act section, and finally the assert section. Sections don't generally overlap (with few exceptions).
js
it('should return 5 when given 2 and 3', () => {
let adder = new Adder();
let sum = adder.add(2,3);
expect(sum).toBe(5);
})it('should return 5 when given 2 and 3', () => {
let adder = new Adder();
let sum = adder.add(2,3);
expect(sum).toBe(5);
})The Arrange section is where the initial state is setup. A good unit test tests only a single state change. So we want to put our code into the initial state. That's what the arrange is for.
Next comes the Act section where we execute some kind of state change or computation. In our example we call the add method in the Act section.
Finally comes the Assert section. Here we assert that the resulting state, or computation is what we expect. This is where we cause the test to fail if we get an unexpected result, or pass if we get the expected result. In the example we expect the sum to be 5. Notice that each section is easy to identify. Whitespace helps.
This also makes tests predictable and improves readability. If every test has some uniformity like this, then dealing with any test, whether you wrote it or not, becomes easier.
Library
Currently we are using @vue/test-utils library, which provides a set of utility functions for testing Vue components
Vue 3 with Vitest:
This component library uses Vue 3 with vitest.
An example:
ts
import { mount } from '@vue/test-utils';
import { describe, it, expect, vi } from 'vitest';
import FTNavbar from '@/components/FTNavbar/FTNavbar.vue';
function factory(props) {
const wrapper = mount(FTNavbar, {
props,
global: {
stubs: ['router-link', 'fa'],
},
});
return wrapper;
}
describe('FTNavbar.vue', () => {
it('should render a breadcrumb of type text', async () => {
const props = { breadcrumbs: [{ type: 'text', text: 'Migrations' }] };
const wrapper = factory(props);
expect(wrapper.find('.breadcrumb').exists()).toBe(true);
expect(wrapper.find('.breadcrumb').text()).toBe('Migrations');
});
it('should not render a hidden breadcrumbs', async () => {
const props = {
breadcrumbs: [{ type: 'text', text: 'Migrations', hidden: true }],
};
const wrapper = factory(props);
expect(wrapper.find('.breadcrumb').exists()).toBe(false);
});
});import { mount } from '@vue/test-utils';
import { describe, it, expect, vi } from 'vitest';
import FTNavbar from '@/components/FTNavbar/FTNavbar.vue';
function factory(props) {
const wrapper = mount(FTNavbar, {
props,
global: {
stubs: ['router-link', 'fa'],
},
});
return wrapper;
}
describe('FTNavbar.vue', () => {
it('should render a breadcrumb of type text', async () => {
const props = { breadcrumbs: [{ type: 'text', text: 'Migrations' }] };
const wrapper = factory(props);
expect(wrapper.find('.breadcrumb').exists()).toBe(true);
expect(wrapper.find('.breadcrumb').text()).toBe('Migrations');
});
it('should not render a hidden breadcrumbs', async () => {
const props = {
breadcrumbs: [{ type: 'text', text: 'Migrations', hidden: true }],
};
const wrapper = factory(props);
expect(wrapper.find('.breadcrumb').exists()).toBe(false);
});
});