Gabriel Jiménez | Hace 21 días
En este capítulo, aprenderemos porque probar todo puede ser un error, qué si y qué no vale probar en nuestras aplicaciones React, y finalmente, cómo decidir que probar antes de escribir un test.
Una de las preguntas que nos hacemos cuando nos adentramos en el mundo de las pruebas es: ¿Qué debería probar? Si no tenemos las bases solidas desde un inicio, comenzaremos con querer probar todo —UI, lógica de negocio, CSS, flujos críticos.
Cuando escribimos pruebas se suele pensar que tan solo con escribir pruebas, ya no tendremos bugs en nuestras aplicaciones, esto es incorrecto. Los bugs siempre van a exigir, así tengamos toda nuestra aplicación con pruebas al 100 %. Las aplicaciones suelen depender de servicios externos que muchas veces no vamos a tener el control sobre ellos.
Entonces, ¿debo o no escribir pruebas para todo? La respuesta corta es no, no deberíamos probar todo. Como en la vida diaria, debe existir un balance.
Una de las consecuencias de querer probar todo es que, comencemos a escribir pruebas por escribir o porque donde trabajamos es un requerimiento de la empresa. La desventaja es que, solemos llegar a pensar en los tests como algo que debemos de hacer solo por hacer y no en algo que aporta valor al desarrollo.
Hay ciertas señales que podemos seguir para saber que si vale la pena probar en nuestras aplicaciones React.
El usuario es el actor principal al que debemos de enfocarnos, por esa razón es importante validar que esta recibiendo el feedback correcto al realizar alguna acción en nuestras aplicaciones. Estos feedback pueden ser desde notificaciones al guardar algún formulario hasta errores de formato.
En nuestras aplicaciones tendemos a tener dos tipos de flujos: flujos críticos y flujos secundarios. Los flujos críticos son aquellos que permiten a un negocio ser rentable. Por ejemplo, una aplicación que ofrece seguros para carros, debe asegurarse que sus flujos críticos para que un usuario obtenga un seguro estén probados.
Mucho del código que escribimos pertenece de alguna forma a la lógica del negocio. Sin embargo, es importante separarla por severidad — alta, media o baja.
Por ejemplo, supongamos, que tenemos un componentes que permite crear, listar y ver productos. Si tuviéramos que separar la lógica del componente por severidad tendríamos algo como: crear - alta, media - listar y baja - ver. Dicho esto, es importante asegurarnos de probar la creación de productos y en caso que el listado tenga bastante lógica de negocio se podría pensar en probarlo.
Para ejemplificar mejor un estado importante y transacciones relavarte dentro de nuestras aplicaciones React, usemos el siguiente ejemplo:
Supongamos, tenemos un listado de ordenes, donde las ordenes tienen estados (pagado, en espera de pago, en espera de enviar) y cada orden debe tener acciones propias del estado. El estado “En espera de pago” puede tener las acciones de “Realizar pago”, al hacer clic se muestra una nueva pantalla donde se pide la información del pago.
Lo que probaríamos sería que cada orden tenga las acciones correspondientes por estado y que cada acción te transición hacia la acción correspondiente.
Para facilitar el desarrollo en React y en general, creamos componentes reutilizables que permiten encapsular lógica y evitan código repetido. Estos componentes son importantes que los probemos, porque se usan en diferentes lados de nuestra aplicación y a veces suelen tener varías responsabilidades — no debería ser así, pero pasa.
De igual manera, hay varías señales que podemos seguir para saber qué no deberíamos probar dentro de nuestras aplicaciones React.
Con implementación interna me refiero a no querer probar que una variable tenga cierto valor al realizar alguna acción — ya sea un clic o llenar algún campo. Esto hace que nuestras pruebas sean frágiles y difíciles de probar, ya que la implementación suele cambiar conforme vayamos agregando o modificando código.
Este es uno de los errores más comunes, tratar de probar librerías externas o código que no controlamos. Normalmente, este tipo de código, ya debería estar probado por sus creadores — si bien nos va. En ese caso, no es necesario esforzarnos en probarlo, si no más bien en como se comunica con nuestra lógica de negocio, por ejemplo:
Una librería de notificaciones, no nos debería importar si se renderiza en pantalla. Esa responsabilidad le corresponde a los creadores de la librería. En su lugar, nosotros debemos probar que la notificación se dispare con el mensaje correcto cuando guardamos un formulario o realicemos alguna acción en específico.
Lo único importante para el usuario final es poder usar nuestros servicios. No le importa como este desarrollada, ni como se vea. Dicho esto, probar estilos, clases CSS y estructura del DOM es innecesario, por que no arrojan suficiente valor al usuario.
Mucho del código que escribimos, suele ser código simple, con darle una mirada podemos saber que esta haciendo. Por ejemplo, un listado de productos que tienen pocas columnas sin lógica que mostrar.
Antes de escribir un test, es importante pensar y decidir qué comportamiento realmente importa. No todos los flujos tienen el mismo impacto ni el mismo riesgo.
No es lo mismo tener un flujo para registrar una venta, que el flujo para registrar un nuevo elemento de un catálogo. Los flujos críticos son aquellos que permiten al usuario usar nuestros servicios y son a estos, los que deberíamos poner atención.
Ya localizando los flujos críticos, ahora debemos de categorizarlos por complejidad. Esto va a depender mucho de tu experiencia laborando. Sin embargo, en mi experiencia, son aquellos flujos críticos donde el usuario tiene mucha interacción. Por ejemplo, cuando intentamos comprar un boleto de avión.
Ya categorizado los flujos críticos, el siguiente paso es no pensar en qué componente probar, sino en qué hace el usuario y qué resultado espera. La implementación de las pruebas debe partir del comportamiento del usuario final, no de la estructura interna de los componentes ni de cómo estén compuestos.
Es importante cada que hagamos un test simularlo desde la perspectiva de un usuario y no como desarrollador. De esta forma, podemos detectar posibles bug, errores reales de uso y escenarios que podrían frustrar al usuario al interactuar con la aplicación.
Saber que y que no probar en nuestras aplicaciones React, nos facilita poder agregar y modificar sin miedo a romper funcionalidad existentes. Las pruebas son un gran aliado a la hora de escribir pruebas, pero igual pueden ser un mal aliado si no se realizan con precaución.
Si quieres aprender más sobre como probar tus aplicaciones React, visita mi hub Testing en React.