Qué probar y qué NO probar en React: evita tests inútiles

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.


El error común: Querer probar todo en React

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.


Por qué probar todo parece una buena idea

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.


Cómo nacen los tests frágiles y costosos de mantener

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.


Qué si vale la pena probar en React

Hay ciertas señales que podemos seguir para saber que si vale la pena probar en nuestras aplicaciones React.


Comportamiento visibles para el usuario

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.


Flujos críticos de la aplicación

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.


Lógica de negocio dentro de componentes

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.


Estados importantes y transiciones relavantes

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.


Componentes reutilizables

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.


Qué no debería probar en React

De igual manera, hay varías señales que podemos seguir para saber qué no deberíamos probar dentro de nuestras aplicaciones React.


Detalles de implementación interna

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.


Librerías externas y código que no controles

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.


Estilos, clases CSS y estructura del DOM

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.


Hooks o componentes triviales sin lógica real

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.


Cómo decidir qué probar antes de escribir un test

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.


Flujos críticos

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.


Complejidad de los flujos críticos

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.


Pensar en comportamiento, no en componentes

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.


Probar desde la perspectiva del usuario

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.


Conclusió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.


Hub Testing en React