Skip to content

Commit 4867776

Browse files
authored
Merge pull request #28 from deverebor/feat/vitest-proposal
feat/vitest-proposal
2 parents c12c059 + 57e1964 commit 4867776

File tree

2 files changed

+294
-0
lines changed

2 files changed

+294
-0
lines changed

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ O curso aborda conceitos tanto do Vue 2.x quanto do Vue 3.x
8282
1. [Jest no Vue](/tutorial/7-Testes%20e%20Storybook/1-Jest%20no%20Vue.md)
8383
2. [Cypress no Vue](/tutorial/7-Testes%20e%20Storybook/2-Cypress%20no%20Vue.md)
8484
3. [Storybook](/tutorial/7-Testes%20e%20Storybook/3-Storybook.md)
85+
4. [Vitest](/tutorial/7-Testes%20e%20Storybook/4-Vitest.md)
8586

8687
### Ecossistema Vue
8788

@@ -114,5 +115,6 @@ O curso aborda conceitos tanto do Vue 2.x quanto do Vue 3.x
114115
## Autores
115116

116117
* **Giovane Cardoso (Novout)** - *Freelance Frontend Developer & Member of He4rt Developers* - [Twitter](https://twitter.com/NovoutT)
118+
* **Lucas Souza (deverebor)** - *Frontend Software Engineer at Juntos Somos Mais & Member of He4rt Developers* - [Twitter](https://twitter.com/deverebor)
117119

118120
<p align="center">Made with 💜</p>
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# Vitest
2+
3+
> A ferramenta de testes mais rápida!
4+
5+
## Antes de começar
6+
7+
Assim como no jest para utilizarmos o Vitest precisamos instalar o VueTestUtils, uma ferramenta que nos ajuda por meio de helpers e funcionalidades a testar e montar nossos componentes.
8+
9+
> pode ser utilizado yarn, npm ou pnpm
10+
11+
```bash
12+
npm i @vue/test-utils
13+
```
14+
15+
> apos a instalação do VueTestUtils, vamos instalar o Vitest
16+
17+
```bash
18+
npm i -D vitest
19+
```
20+
21+
## Oque é o Vitest ?
22+
23+
O Vitest é uma ferramenta de testes que utiliza o Vite como base, e por isso é muito mais rápida que o Jest, e também é muito mais simples de configurar.
24+
25+
## Configuração do Vitest
26+
27+
Para rodar os testes é necessário adicionar o seguinte script no package.json:
28+
29+
```json
30+
{
31+
"scripts": {
32+
"test": "vitest",
33+
"coverage": "vitest run --coverage"
34+
}
35+
}
36+
```
37+
38+
## Como utilizar o Vitest ?
39+
40+
Para criar um teste com o Vitest, basta criar um arquivo com a extensão .test.ts ou .spec.ts se o seu projeto é vue + typescript dentro da pasta de testes, e dentro do arquivo, basta importar o método test do Vitest e criar um teste.
41+
42+
```ts
43+
import { shallowMount } from "@vue/test-utils";
44+
import HelloWorld from "@/components/HelloWorld.vue";
45+
import { describe, it, expect } from "vitest";
46+
47+
describe("HelloWorld.vue", () => {
48+
it("renders props.msg when passed", () => {
49+
const msg = "new message";
50+
51+
const wrapper = shallowMount(HelloWorld, {
52+
propsData: { msg }
53+
});
54+
55+
expect(wrapper.text()).toMatch(msg);
56+
});
57+
});
58+
```
59+
60+
Assim como no Jest o Vitest também possui o describe e o it, e também o expect, que é o que utilizamos para fazer as asserções.
61+
62+
> O describe é utilizado para agrupar os testes, e o it é utilizado para criar um teste, e o expect é utilizado para fazer as asserções.
63+
64+
Depois de criar o teste, basta rodar o comando:
65+
66+
```bash
67+
npm run test
68+
```
69+
70+
## Testando componentes
71+
72+
Depois de entender o básico do Vitest, vamos criar um teste para um componente, para isso vamos criar um componente chamado Button.vue dentro da pasta components, e vamos criar um teste para ele.
73+
74+
Vamos criar um componente chamado Button.vue dentro da pasta components, e vamos criar um teste para ele.
75+
76+
```vue
77+
<template>
78+
<div>
79+
<button data-testid="increment-count-button" @click="count++">
80+
Click me
81+
</button>
82+
<span>Count: {{ message }}</span>
83+
</div>
84+
</template>
85+
86+
<script lang="ts">
87+
import { defineComponent } from "vue";
88+
89+
export default defineComponent({
90+
name: "Button",
91+
data() {
92+
return {
93+
count: 0
94+
};
95+
},
96+
97+
computed: {
98+
message() {
99+
return `Count: ${this.count}`;
100+
}
101+
},
102+
103+
methods: {
104+
increment() {
105+
this.count++;
106+
}
107+
}
108+
});
109+
</script>
110+
```
111+
112+
Agora vamos criar um teste para esse componente, para isso vamos criar um arquivo chamado Button.test.ts dentro da pasta tests, e vamos criar um teste para ele.
113+
114+
```ts
115+
import Vue from "vue";
116+
import { shallowMount, Wrapper } from "@vue/test-utils";
117+
118+
import { describe, it, expect } from "vitest";
119+
import Button from "@/components/Button.vue";
120+
121+
interface IButton extends Vue {
122+
message: string;
123+
increment: () => void;
124+
}
125+
126+
describe("Button.vue", () => {
127+
it("should render props.msg when passed", () => {
128+
const wrapper = shallowMount(Button, {
129+
propsData: {
130+
msg: "new message"
131+
}
132+
}) as Wrapper<IButton>;
133+
134+
expect(wrapper.find("button").text()).toMatch("Click me");
135+
});
136+
137+
it("should increment count when button is clicked", async () => {
138+
const wrapper = shallowMount(Button);
139+
140+
await wrapper.find("button").trigger("click");
141+
142+
expect(wrapper.vm.message).toBe("Count: 1");
143+
});
144+
});
145+
```
146+
147+
Que teste grande não é ? Mas vamos entender o que está acontecendo.
148+
149+
Primeiro vamos entender o que é o shallowMount, o shallowMount é utilizado para montar o componente, e ele recebe como parâmetro o componente que queremos montar, e também podemos passar o propsData, que é utilizado para passar os props para o componente.
150+
151+
Depois de montar o componente, podemos utilizar o find para encontrar um elemento dentro do componente, e também podemos utilizar o trigger para disparar um evento, e também podemos utilizar o vm para acessar os dados do componente.
152+
153+
### Vamos entender mais afundo o que está acontecendo no teste
154+
155+
> Porque fizemos uma interface para o componente ?
156+
157+
Porque o componente não tem tipagem, e para que possamos acessar os dados do componente, precisamos tipar o componente, e para isso criamos uma interface para o componente.
158+
159+
```ts
160+
interface IButton extends Vue {
161+
message: string;
162+
increment: () => void;
163+
}
164+
```
165+
166+
Estendemos a interface do Vue para que o componente tenha acesso a todos os métodos e propriedades do Vue. E também criamos uma interface para o componente, e dentro dessa interface criamos as **`computeds`** e **`methods`** que existem no nosso componente.
167+
168+
> shallowMount é utilizado para montar o componente ?
169+
170+
Sim, o shallowMount é utilizado para montar o componente, e ele recebe como parâmetro o componente que queremos montar, e também podemos passar as props, mocks e tudo relacionado ao componente que estamos testando.
171+
172+
```ts
173+
const wrapper = shallowMount(Button, {
174+
propsData: {
175+
msg: "new message"
176+
}
177+
}) as Wrapper<IButton>;
178+
```
179+
180+
Caso seu componente tenha contatos com Vuex ou Vuetify, você pode passar os mocks para o shallowMount, e assim você consegue testar o componente e suas dependências.
181+
182+
```ts
183+
import { createLocalVue, shallowMount, Wrapper } from "@vue/test-utils";
184+
185+
const localVue = createLocalVue();
186+
187+
localVue.use(Vuetify);
188+
localVue.use(Vuex);
189+
190+
describe("Button.vue", () => {
191+
const wrapper = shallowMount(Button, {
192+
localVue,
193+
propsData: {
194+
msg: "new message"
195+
}
196+
}) as Wrapper<IButton>;
197+
198+
// Teste...
199+
});
200+
```
201+
202+
Dessa maneira, você consegue testar o componente com as dependências do vuex como chamadas na store, e também consegue testar o componente com o vuetify como os breaking points.
203+
204+
> Como acessamos os dados do componente ?
205+
206+
Para acessar os dados do componente, podemos utilizar o **`vm`**, e para ter acesso a todas as propriedades do componente, precisamos tipar o componente, e para isso criamos uma interface para o componente.
207+
208+
## Dando um passo além
209+
210+
### Testando renderização do componente utilizando data-testid
211+
212+
Para testar a renderização do componente, podemos utilizar o **`data-testid`**, e para isso precisamos adicionar o **`data-testid`** no elemento que queremos testar.
213+
214+
```vue
215+
<template>
216+
<div>
217+
<button data-testid="increment-count-button" @click="count++">
218+
Click me
219+
</button>
220+
<span>Count: {{ message }}</span>
221+
</div>
222+
</template>
223+
224+
<script lang="ts">
225+
import { defineComponent } from "vue";
226+
227+
export default defineComponent({
228+
name: "Button",
229+
data() {
230+
return {
231+
count: 0
232+
};
233+
},
234+
235+
computed: {
236+
message() {
237+
return `Count: ${this.count}`;
238+
}
239+
},
240+
241+
methods: {
242+
increment() {
243+
this.count++;
244+
}
245+
}
246+
});
247+
</script>
248+
```
249+
250+
Depois de adicionar o **`data-testid`** no elemento, podemos utilizar o **`find`** para encontrar o elemento, e também podemos utilizar o **`trigger`** para disparar um evento.
251+
252+
```ts
253+
import Vue from "vue";
254+
255+
import { describe, it, expect } from "vitest";
256+
import { shallowMount, Wrapper } from "@vue/test-utils";
257+
258+
import Button from "@/components/Button.vue";
259+
260+
interface IButton extends Vue {
261+
message: string;
262+
increment: () => void;
263+
}
264+
265+
const DATA_TEST_ID = {
266+
INCREMENT_COUNT_BUTTON: "[data-testid='increment-count-button']"
267+
};
268+
269+
describe("Button.vue", () => {
270+
it("should render props.msg when passed", () => {
271+
const wrapper = shallowMount(Button, {
272+
propsData: {
273+
msg: "new message"
274+
}
275+
}) as Wrapper<IButton>;
276+
277+
expect(wrapper.find(DATA_TEST_ID.INCREMENT_COUNT_BUTTON).text()).toMatch(
278+
"Click me"
279+
);
280+
});
281+
282+
it("should increment count when button is clicked", async () => {
283+
const wrapper = shallowMount(Button);
284+
285+
await wrapper.find(DATA_TEST_ID.INCREMENT_COUNT_BUTTON).trigger("click");
286+
287+
expect(wrapper.vm.message).toBe("Count: 1");
288+
});
289+
});
290+
```
291+
292+
Usando o data-testid, além de facilitar encontrar o elemento que você deseja testar, você também auxilia na criação de testes e2e(Cypress), pois você consegue identificar os elementos que você deseja testar.

0 commit comments

Comments
 (0)