Testing en componentes de Vue.js

0
317

Índice de contenidos

1. Introducción

En este tutorial aplicaremos los principios de TDD al desarrollo de componentes en Vue.js, asumiendo un conocimiento intermedio de Vue.js y un entendimiento básico de tests unitarios.

Vamos a usar las librerías de testing Vue-Test-Utils y Jest, y Typescript para el tipado estático.

Vue Test Utils es la librería de testing oficial para Vue.js. Nos da mucha facilidad a la hora de montar componentes, simular eventos de usuario, renderizado superficial, modificar el estado y los props de componentes y más.

Jest es el motor de tests mantenido y usado por Facebook. La mayor ventaja de Jest sobre otros frameworks de tests es la velocidad y que no es necesario configurar casi nada para usarlo.

Typescript es un superset de Javascript de Microsoft que introduce muchas características nuevas al lenguaje. Puede que la más notable sea el fuerte tipado estático.

TDD o Test-driven development es un proceso de desarrollo de software que sigue un ciclo muy corto:

  1. Se definen los requerimientos del software.
  2. Se crean tests para cubrir esos requerimientos.
  3. Se implementa el software para pasar los tests.

Si se necesita ampliar el software, se repite el mismo proceso. No se puede crear software que no tenga tests cubriéndolo.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 15’ (2,5 GHz Intel Core i7, 16GB DDR3)
  • Sistema operativo: macOS Sierra 10.12.6
  • Entorno de desarrollo: Visual Studio Code
  • Versión de Vue: 2.5.17

3. Creación del proyecto.

Vamos a usar Vue CLI 3, una herramienta de terminal que nos ayuda a la hora de
crear la estructura de carpetas del proyecto.

Para instalarlo de forma global es tan sencillo como:

Ahora que tenemos el CLI instalado, abrimos el terminal en nuestra carpeta de proyectos y lo ejecutamos:

O si no queremos instalar el CLI globalmente:

El CLI nos preguntará si queremos crear un proyecto predeterminado o queremos personalizarlo. Nosotros vamos a elegir manualmente.

Estas son las opciones que he elegido para este proyecto:

El CLI nos pedirá algunos detalles más sobre la configuración que hemos elegido:

Lo más importante a destacar en esta parte es que vamos a usar Jest.

4. Definición de los requerimientos.

Antes de ponernos a picar código como locos, debemos definir unos requerimientos claros.

A riesgo de ser cliché, vamos a desarrollar una aplicación de tareas, o la infame Todo List. Estos son los requerimientos de la aplicación.

  • Debe tener una lista de items. Cada item tendrá:
    • Un título
    • Un botón con texto ‘complete’. Cuando sea clicado:
      • El título debe ser tachado.
      • El botón debe ser deshabilitado y su texto cambiar a ‘completed’.
  • Debe tener un campo de entrada de texto.
  • Debe tener un botón.
    • Si la entrada de texto está vacía, el botón debe estar deshabilitado.
    • Si la entrada de texto no está vacía, cuando sea clicado:
      • Debe añadir un nuevo item con el título de la entrada de texto.
      • Debe vaciar la entrada de texto.

Personalmente, en esta etapa me suele ayudar mucho dibujar la aplicación en papel o en una herramienta de prototipado de interfaces, para ver claramente los componentes que voy a necesitar.

De la especificación podemos deducir que vamos a necesitar dos componentes:

  • TodoList: un contenedor que guardará y modificará el estado de los hijos.
  • TodoItem: un componente que recibirá por props lo que debe renderizar.

5. Las bases de Testing en componentes.

A la hora de testear componentes, no necesitamos hacer testing de características de Vue, asumimos que estas va a funcionar normalmente.

Nuestro objetivo es asegurar que la lógica que nosotros introducimos sigue el comportamiento especificado. Debemos testear:

  • Lifecycle hooks: comprobar que una función es llamada cuando el componente se monta, se destruye…
  • Métodos: comprobar que el retorno es el esperado o que se ha cambiado el estado correctamente.
  • Watchers: cuando se modifica un prop o método, asegurar que el watcher es invocado.
  • Propiedades computadas: comprobar que el retorno es el esperado.

Snapshots

Los snapshots son ‘fotos’ de nuestro componente renderizado. Cada vez que pasemos los tests de un componente, una nueva ‘foto’ es sacada.

El motor de tests nos avisará si la nueva foto coincide con la anterior. Si no es así, nos avisará.

Esto nos sirve para asegurarnos de que los cambios que hacemos que hacemos “por debajo” de un componente no afectan a la forma en la que este se renderiza. Son “gratis” (muy sencillos de implementar) y está bien tenerlos en todos los componentes que tengan algo de HTML a renderizar.

Mount y ShallowMount

mount() y shallowMount() son las funciones que nos permiten montar nuestro componente dentro de los tests.

Mount nos montará el componente y todos los componentes hijos mientras que shallowMount solo montará el componente en cuestión.

Por lo general es recomendable usar shallowMount antes que mount porque mantiene los tests aislados y unitarios y se tarda menos en ejecutar el test.

Usa mount cuando quieras probar la integración entre distintos componentes.

Triggers

Para simular la interacción con el usuario, podemos disparar eventos de muchos tipos con trigger().

6. Desarrollo de un componente. TodoItem.

Testing.

Este es un componente muy tonto, no tiene lógica de negocio, solo de vista.

Vamos a comprobar:

  • El componente renderiza el mismo ‘snapshot’ que la última vez.
  • Si ‘isCompleted’ es ‘false’, el texto del botón es ‘complete’.
  • Si ‘isCompleted’ es ‘true’, el texto del botón es ‘completed’.
  • Si ‘isCompleted’ es ‘true’, el botón debería deshabilitarse.

Creamos el fichero TodoItem.spec.ts en la carpeta de tests y nos ponemos a ello.

Implementación.

Ahora que nuestros tests cubren todo el comportamiento del componente, podemos empezar la implementación.

Para probar que nuestra implementación pasa los tests, usamos:

7. Desarrollo de un contenedor. TodoList.

Testing.

Este es un contenedor con algo de lógica y que contiene todos los TodoItems a renderizar.

Vamos a comprobar:

  • El componente renderiza el mismo ‘snapshot’ que la última vez.
  • Si la entrada de texto está vacía, el botón debe estar deshabilitado.
  • Si la entrada de texto no está vacía, cuando el botón sea clicado:
    • Debe añadir un nuevo TodoItem con el título de la entrada de texto.
    • Debe vaciar la entrada de texto.

Creamos el fichero TodoItem.spec.ts en la carpeta de tests y nos ponemos a ello.

Implementación.

Ahora que los tests cubren todo el comportamiento del contenedor, podemos empezar la implementación.

Para probar que nuestra implementación pasa los tests, usamos de nuevo:

8. Conclusiones.

Vue Test Utils nos permite testear la funcionalidad de una aplicación Vue de principio a fin.

En este tutorial nos hemos centrado en el testing de componentes, pero también se puede testear otras partes de Vue como Vue-Router o Vuex.

Échale un vistazo!

El testeo del software es tan importante en el backend como en el frontend, no dejes mal a tus colegas ‘fronteros’ y testea como el que más!

Puedes clonar y probar el proyecto con:

O descargarlo desde Github:

Proyecto en Github

9. Referencias.

Dejar respuesta

Please enter your comment!
Please enter your name here