Primeros pasos con Testing library

0
273
testing library logo image

Índice de contenidos

  1. ¿Que es Testing Library?
  2. ¿Que planteamiento hay detrás de la librería?
  3. ¿Que bibliotecas lo componen?
  4. Ejemplo de uso en una aplicación
  5. Conclusiones

¿Que es Testing Library?

Testing Library es una familia de bibliotecas de código abierto desarrolladas por Kent C. Dodds y una serie de colaboradores. La finalidad de las mismas es ayudar a escribir tests más intuitivos y fáciles de mantener en nuestras aplicaciones. Se enfoca en la experiencia del usuario final, simulando cómo un usuario real interactúa con la interfaz de usuario (UI) de tu aplicación.

¿En qué se diferencia de otras bibliotecas de testing?

  • Se enfoca en la UI: Testing Library te permite escribir pruebas que se basan en cómo se ve y funciona la UI, en lugar de cómo está implementada internamente.
  • Más legible: Las pruebas escritas con Testing Library son más fáciles de leer y entender, ya que se asemejan al lenguaje natural que un usuario usaría para describir las acciones en la UI.
  • Menos mantenimiento: Al no depender de detalles de implementación, las pruebas son más robustas y requieren menos mantenimiento a medida que la aplicación cambia. Esto también hace que los test sean agnósticos del Framework que se esté utilizando.

¿Cuáles son los beneficios de usar Testing Library?

  • Enfoque centrado en el usuario: Esta biblioteca se centra en probar el comportamiento de los componentes desde la perspectiva del usuario. Esto significa que las pruebas se escriben de manera que imitan cómo los usuarios interactúan con la aplicación, lo que conduce a pruebas más realistas y útiles.
  • Pruebas más robustas y mantenibles: Al adoptar un enfoque centrado en el usuario, las pruebas tienden a ser más robustas y menos propensas a romperse debido a cambios en la implementación interna de los componentes. Esto se debe a que las pruebas se basan en el comportamiento visible del componente en lugar de detalles de implementación específicos.
  • Facilidad de uso y aprendizaje: Las bibliotecas de pruebas están diseñadas para ser fáciles de usar y aprender. Siguen principios simples y proporcionan una API intuitiva que facilita la escritura de pruebas, incluso para aquellos que no tienen experiencia previa en pruebas automatizadas.
  • Integración con herramientas de desarrollo: Las bibliotecas de pruebas suelen integrarse bien con otras herramientas de desarrollo populares, como herramientas de generación de informes de cobertura de código, herramientas de CI/CD (integración continua/entrega continua) y entornos de desarrollo.
  • Comunidad activa y soporte: Las bibliotecas de pruebas populares como Testing Library tienen comunidades activas que proporcionan soporte, documentación y recursos adicionales para ayudar a los desarrolladores a escribir y mantener pruebas de manera efectiva.

¿Que planteamiento hay detrás de la librería?

kent c dods twitter phrase image

Esta frase de Kent C. Dodds indica cual es la metodología que se plantea con testing library, donde nuestros test van a reflejar el comportamiento que tendría un usuario real al interactuar con nuestra aplicación.

Al hacer uso de este conjunto de librerías, estas, por los métodos y utilidades que nos ofrecen a la hora de trabajar con las mismas, nos van a hacer trabajar de la manera que esperan ellos, que es con test que replican la interacción de un usuario con una página web. Por ejemplo, un usuario no va a conocer cual es el id de un elemento en nuestra aplicación, o que clase tiene, por lo que en este conjunto de librerías no vamos a tener un getById, o getByClassName. Este tipo de funciones no aportan mucha confianza, ya que se pueden dar por bueno un test en el que un elemento puede tener un id, estar oculto, y dar positivo en un test que compruebe que existe, este test no nos aporta ningún valor.

En la documentación de la librería nos indican los principios que se han seguido para plantear las utilidades de esta librería.

¿Que bibliotecas lo componen?

Testing Library cuenta con una gran variedad de bibliotecas que nos permiten realizar tests en diferentes frameworks de siguiendo la metodología que ellos indican junto con algunas utilidades para replicar la interacción real del usuario. En esta sección hablaré de unas pocas de ellas.

React Testing Library

React Testing Library es una de las librerías de Testing Library que se utiliza para probar componentes de React. Proporciona funciones de utilidad ligeras sobre react-dom y react-dom/test-utils, de una manera que fomenta buenas prácticas en los test.

Por ello, en lugar de lidiar con instancias de componentes de React, nuestras pruebas trabajarán con nodos DOM reales. Las utilidades que esta biblioteca proporciona facilitan la consulta del DOM de la misma manera que lo haría el usuario. Por ejemplo, encontrar elementos de formulario por su texto de etiqueta o encontrar enlaces y botones por su texto tal como lo haría un usuario. También expone una forma recomendada de encontrar elementos, mediante un data-testid como una utilidad a utilizar para elementos donde el contenido de texto y la etiqueta no tienen sentido o no son prácticos.

Esta biblioteca fomenta que tus aplicaciones sean más accesibles y permite acercar tus test a como usaría tus componentes un usuario real, lo que permite que tus pruebas aporten más confianza en que tu aplicación funcionará cuando la use un usuario real.

Esta biblioteca es un reemplazo para Enzyme. Si bien puedes seguir estas pautas usando Enzyme en sí, hacer cumplir esto es más difícil debido a todas las utilidades adicionales que Enzyme proporciona (utilidades que facilitan la prueba de detalles de implementación).

En este tutorial únicamente voy a hablar de la librería de React Testing Library, pero existen muchas más para los diferentes Framework con los que trabajamos hoy en día, podéis verlo en la página de la documentación de Testing Library.

Jest-DOM

La biblioteca Jest-DOM es una extensión de Jest desarrollada por Testing Library para facilitar las pruebas de interfaz de usuario en aplicaciones web. Jest-DOM proporciona una serie de funciones y utilidades para simular el comportamiento del DOM en entornos de testing. Permite a los desarrolladores escribir pruebas que interactúan con los elementos de la interfaz de usuario de manera similar a como lo haría un usuario real.

Entre sus características principales se incluyen las aserciones para verificar el estado y la apariencia de los elementos del DOM, como comprobar si un elemento está presente, si tiene ciertos estilos aplicados o si contiene cierto texto. Un ejemplo de estas aserciones podría ser toBeInDocument, que comprueba que el elemento está presente en el DOM o no, o toBeVisible, que comprueba que un elemento sea visible, aquí tenéis una lista de todos que hay.

Jest-DOM se integra bien con Jest y otras herramientas de Testing Library, como React Testing Library, lo que lo hace especialmente útil para proyectos que utilizan estas tecnologías.

User Event

User Event es una biblioteca complementaria para Testing Library que simula las interacciones del usuario al emitir los eventos que ocurrirían si la interacción se llevara a cabo en un navegador.

La pregunta que puede surgir sería, ¿por qué es necesaria esta librería si Testing Library ya cuenta con una función integrada, que es fireEvent, para esto?

Diferencias con fireEvent

fireEvent ejecuta eventos del DOM, mientras que User Event simula interacciones completas, que pueden provocar múltiples eventos y realizar verificaciones adicionales en el proceso.

La función integrada fireEvent de Testing Library es una envoltura ligera alrededor de la API de dispatchEvent del navegador, que permite a los desarrolladores activar cualquier evento en cualquier elemento. Sin embargo, el navegador suele realizar más acciones además de simplemente activar un evento durante una interacción. Por ejemplo, cuando un usuario escribe en un cuadro de texto, el elemento debe estar enfocado, luego se disparan eventos de teclado e input, y se manipulan la selección y el valor en el elemento mientras se escribe.

User Event nos permite describir una interacción de usuario en lugar de un evento específico. Añade verificaciones de visibilidad e interactividad en el proceso y manipula el DOM exactamente como lo haría un usuario en el navegador. Por dar un ejemplo, el navegador no permitiría que un usuario hiciera clic en un elemento oculto o que escribiera en un cuadro de texto deshabilitado.

Por ello es recomendable utilizar User Event para probar la interacción con tus componentes, en este artículo nos dan otro ejemplo de porque deberíamos utilizarlo.

No obstante, habría que recalcar que no todas las interacciones que puede realizar un usuario se han implementado en esta librería. En estos casos, puedes emplear fireEvent para desencadenar los eventos específicos en los que se basa tu software.

Ejemplo de uso en una aplicación

Para empezar, mostraré como era el planteamiento que se hacían los test en una aplicación web antes de la llegada de Testing Library. Este ejemplo lo haré en React, y haré uso de una librería que se utilizaba antes de la llegada de Testing Library llamada Enzyme, para todos ejemplos que mostraré en esta sección, he creado una aplicación básica TODO, donde tengo un input en el que escribo un texto, un botón para añadirlo a una lista en la que cada elemento contará con un botón para eliminarlo esa misma lista.

imagen de aplicacion todo basica

En primer lugar mostraré unos test básico que he planteado con Enzyme

imagen de test hecho con enzyme

En este test estamos planteando el comportamiento básico de la aplicación, donde escribimos un texto en el input, hacemos click en el botón de Add y se añade un nuevo elemento en una lista con el texto que hemos escrito anteriormente.

Al mirar este test vemos que lo estamos planteando mucho desde el punto de vista de la implementación, es decir, lo primero que estamos haciendo es buscar un elemento «input», que sea de tipo «text», y luego un botón. Posteriormente estamos simulando un evento de tipo change que va a tener un target con valor foo. Posteriormente vamos a tener que simular la acción de click en un botón y buscar un elemento de tipo «p» cuyo texto contenido sea «foo». Al ver esto, podemos apreciar que tenemos que conocer muchos detalles de la implementación de nuestra aplicación para poder hacerlo correctamente y quizás esta no es la manera más apropiada de plantear los test, ya que no van a ser los programadores que han hecho los test los que van a utilizar la aplicación, sino los usuarios.

Por lo que vamos a plantearlo ahora de otra manera, esta vez haciendo uso de la librería de Testing Library.

imagen de test hecho con testing library

Este test se ha hecho con la librería de Testing Library, y ahora podemos ver más claras algunas cosas en el planteamiento del test, es decir, en este caso estamos buscando un elemento asociado a un label cuyo texto es Add todo, algo que podría replicar muy bien lo que haría un usuario. Este mismo vería el texto y haría click en el input, en el siguiente caso lo mismo, estamos buscando un elemento con el rol de botón cuyo texto contenido es el texto Add, vamos a interactuar con cada uno de estos y al final vamos a buscar el texto que hemos añadido en el botón.

Esta manera de hacer los test me parece mucho más clara, ya que estamos poniendo en los mismos el flujo real que seguiría el usuario, sin tener en cuenta detalles de implementación. Este test se puede seguir mejorando, para que quede mucho legible, porque aún queda algún detalle de implementación, como por ejemplo cuando lanzamos el evento de change en el input, indicando el target y valor. Otro punto a tener en cuenta es la aserción que tenemos al final, donde comprobamos que sea truthy ¿Que puede significar esto? No es muy descriptivo.

Vamos a mejorar un poco el test actual, ahora haciendo uso de las librerías de testing library de @testing-library/user-event y @testing-library/jest-dom.

imagen de test hecho con testing library haciendo uso de bibliotecas extra

Ahora podemos apreciar que hemos cambiado el fireEvent por userEvent, el evento de change que teníamos antes ha cambiado por un type, donde únicamente indicamos el elemento en el que hemos realizado la acción y el texto que hemos escrito, sin entrar en detalles de implementación. Por otro lado, en nuestra aserción, hemos cambiado el toBeTruthy() por un toBeInDocument(), que deja mucho más claro lo que estamos comprobando.

Con estos pequeños cambios hemos llegado a un test mucho más legible y que se explica por sí mismo, sin entrar en detalles de implementación. Esto solo es un ejemplo ligero de todas las cosas que se pueden hacer con esta librería, pero que nos ha servido para ver que aporta a la hora de hacer test.

Conclusiones

El artículo presenta una visión exhaustiva de Testing Library, una familia de bibliotecas diseñadas para mejorar la calidad y la eficiencia de las pruebas en el desarrollo de software. La principal premisa es adoptar una metodología centrada en el usuario, que simula las interacciones que un usuario real tendría con la interfaz de usuario de la aplicación. Esta aproximación se aleja de las pruebas basadas en detalles de implementación y se enfoca en las acciones que el usuario final realizaría, lo que conduce a pruebas más realistas y significativas.

Testing Library ofrece una serie de beneficios clave. En primer lugar, promueve pruebas más legibles y comprensibles, ya que la sintaxis se asemeja al lenguaje natural y evita la dependencia de detalles internos de la implementación. Esto facilita la colaboración entre desarrolladores y mejora la mantenibilidad de las pruebas a lo largo del tiempo. Además, al estar centradas en el usuario, estas pruebas son más robustas y menos propensas a romperse debido a cambios en la aplicación.

La facilidad de uso y aprendizaje es otro aspecto destacado de Testing Library. Las bibliotecas están diseñadas para ser accesibles incluso para aquellos sin experiencia previa en pruebas automatizadas, lo que reduce la barrera de entrada para adoptar prácticas de prueba efectivas. Además, estas bibliotecas se integran fácilmente con otras herramientas de desarrollo populares, lo que facilita su incorporación en los flujos de trabajo existentes.

Por último, la comunidad activa y el soporte son aspectos fundamentales para el éxito de Testing Library. Al ser un proyecto de código abierto, cuenta con una amplia base de usuarios y contribuyentes que proporcionan soporte, documentación y recursos adicionales. Esto garantiza que los desarrolladores puedan encontrar ayuda y orientación cuando la necesiten, lo que aumenta la confianza en la adopción de estas herramientas en proyectos reales.

En resumen, usar Testing Library es una buena idea debido a su enfoque centrado en el usuario, que conduce a pruebas más legibles, robustas y significativas. Además, su facilidad de uso, integración con herramientas de desarrollo y soporte de la comunidad hacen que sea una opción atractiva para mejorar la calidad y la eficiencia del proceso de prueba en el desarrollo de software.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad