Pruebas unitarias en Vue.js con Jest
En un post anterior vimos los Componentes de un solo archivo en Vue.js. Resulta que cuando tu aplicación va creciendo se hace en extremo necesario que comiences a probar cada componente con el fin de que los cambios futuros no afecten la funcionalidad actual. Vue es un framework testeable, lo cual nos facilita probar los componentes creados con facilidad. En este post, vas a aprender lo necesario para configurar tu etorno de pruebas unitarias y lanzar tu primer unit test en Vue.js.
Instalación del etorno de pruebas
Lo primero que debes tener es instalado es la librería oficial de Vue.js para las utilidades de testing la cual es @vue/test-utils. Esta librería aporta lo necesario para montar los componentes, ejecutarlos entre otras cosas. Lo siguiente que debes instalar es una librería de testing propiamente en la cuál podamos realizar aserciones, es decir, verificar que un valor es el esperado. En este post como ya lo habrás notado vamos a utilizar Jest, el cuál es un framework de pruebas de Facebook.
Instalación manual
Si instalaste el Scaffolding de aplicación en Vue.js con el preset [Vue 2] babel, eslint o cualquier otro que no incluyera las pruebas, debes instalar las tools de vue para pruebas y el plugin de Jest.
npm i --save-dev @vue/test-utils @vue/cli-plugin-unit-jest
Lo siguiente que debes hacer es crear el archivo jest.config.js en la raíz de la aplicación el cuál será la configuración de jest.
module.exports = {
preset: "@vue/cli-plugin-unit-jest",
};
También es recomendable crear un script de npm que facilite la ejecución del comando. Esto lo puedes agregar en el archivo package.json en la sección de scripts.
"scripts": {
...
"test:unit": "vue-cli-service test:unit",
}
Finalmente crear una carpeta el sigueinte árbol de carpetas en donde se alojarán nuestros tests.
mkdir -p tests/unit
Instalación con vue-cli
Si vas a empezar una aplicación desde cero puedes utilizar vue-cli e instalar los features manualmente en donde deberás agregar Unit Testing y escoger Jest. A continuación te muestro un ejemplo de cómo crear una app con vue-cli seleccionando Jest como test framework.
# vue create my-app
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
❯ Manually select features
? Check the features needed for your project:
◉ Choose Vue version
◉ Babel
◯ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◯ Vuex
◯ CSS Pre-processors
◉ Linter / Formatter
❯◉ Unit Testing
◯ E2E Testing
Después de preguntarte por la versión de Vue y el linter si has seleccionado este último, verás la opción de selección de Jest.
? Pick a unit testing solution:
Mocha + Chai
❯ Jest
Escribiendo nuestro primer test
Para escribir nuestro primer test debemos tener previamente un componente. Vamos a utilizar entonces un componente sencillo de una Card en Boostrap.
<template>
<div class="card" style="width: 18rem;">
<h1 class="text-center">
<slot name="title"></slot>
</h1>
<div class="card-body">
<p class="card-text text-center">
<slot></slot>
</p>
</div>
</div>
</template>
Este componente utiliza Slots. El primer slot es un Slot nombrado y el segundo es el slot por defecto. Lo que esperaríamos de este componente es que renderize los slots cuando son utilizados. Para probar esto vamos a crear el archivo Card.spec.js en la carpeta de pruebas unitarias. Todos los archivos con la terminación .spec.js será interpretados como archivos de pruebas. Veamos entonces la prueba sobre este componente.
import Card from "@/components/Card.vue";
import { mount } from "@vue/test-utils";
describe("Card.vue", () => {
it("renders slots when passed", () => {
const content = "<span>Content</span>";
const title = "<span>Title</span>";
const wrapper = mount(Card, {
slots: {
default: content,
title: title,
},
});
expect(wrapper.html()).toMatch(title);
expect(wrapper.html()).toMatch(content);
});
});
En las dos primeras líneas estamos importando el componente como tal y la función de vue para montar el componente. Después de esto verás la función describe que será la descripción del test, en general debería ser el mismo nombre del componente que estás probando. La función it será la encargada de cada test individual. Como vez el primer argumento de esta función es la descripción del test. Veamos ahora que va dentro del test escrito.
En primer lugar definimos dos constantes las cuales serás respectivamente los slots del título y el slot por defecto.
const content = "<span>Content</span>";
const title = "<span>Title</span>";
En la siguiente sentencia montamos propiamente el componente y pasamos los slots.
const wrapper = mount(Card, {
slots: {
default: content,
title: title,
},
});
Finalmente verificamos que el contenido html que renderiza el componte contiene los slots.
expect(wrapper.html()).toMatch(title);
expect(wrapper.html()).toMatch(content);
Para ejecutar las pruebas puedes correr el siguiente comando:
npm run test:unit
Obtendrás un resultado similar al siguiente:
# vue-cli-service test:unit
PASS tests/unit/Card.spec.js
Card.vue
✓ renders slots when passed (102ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.166s
Ran all test suites.