Una guía práctica para probar aplicaciones de React con Jest

Publicado: 2022-03-10
Resumen rápido ↬ La creación de una aplicación que funcione bien requiere buenas pruebas; de lo contrario, saber si su aplicación funciona como se espera sería cuestión de conjeturas y suerte. Jest es una de las mejores herramientas disponibles para probar aplicaciones React. En este artículo, aprenderá todo lo que necesita para crear una prueba sólida para sus componentes y aplicaciones de React.

En este artículo, le presentaré una herramienta de prueba de React llamada Jest, junto con la popular biblioteca Enzyme, que está diseñada para probar componentes de React. Le presentaré las técnicas de prueba de Jest, que incluyen: ejecución de pruebas, prueba de componentes de React, prueba de instantáneas y simulación. Si es nuevo en las pruebas y se pregunta cómo comenzar, este tutorial le resultará útil porque comenzaremos con una introducción a las pruebas. Al final, estará listo y funcionando, probando aplicaciones React usando Jest y Enzyme. Debe estar familiarizado con React para poder seguir este tutorial.

Una breve introducción a las pruebas

La prueba es una revisión línea por línea de cómo se ejecutará su código. Un conjunto de pruebas para una aplicación comprende varios bits de código para verificar si una aplicación se ejecuta correctamente y sin errores. Las pruebas también son útiles cuando se realizan actualizaciones en el código. Después de actualizar un fragmento de código, puede ejecutar una prueba para asegurarse de que la actualización no interrumpa la funcionalidad que ya se encuentra en la aplicación.

¿Por qué prueba?

Es bueno entender por qué hacemos algo antes de hacerlo. Entonces, ¿por qué probar y cuál es su propósito?

  1. El primer propósito de las pruebas es prevenir la regresión. La regresión es la reaparición de un error que se había corregido previamente. Hace que una característica deje de funcionar según lo previsto después de que ocurra un determinado evento.
  2. Las pruebas aseguran la funcionalidad de componentes complejos y aplicaciones modulares.
  3. Se requieren pruebas para el desempeño efectivo de una aplicación o producto de software.

Las pruebas hacen que una aplicación sea más robusta y menos propensa a errores. Es una forma de verificar que su código haga lo que usted quiere que haga y que su aplicación funcione según lo previsto para sus usuarios.

¡Más después del salto! Continúe leyendo a continuación ↓

Repasemos los tipos de pruebas y lo que hacen.

Prueba de unidad

En este tipo de prueba, se prueban unidades o componentes individuales del software. Una unidad puede ser una función, método, procedimiento, módulo u objeto individual. Una prueba unitaria aísla una sección de código y verifica su corrección, para validar que cada unidad del código del software funciona como se espera.

En las pruebas unitarias, los procedimientos o funciones individuales se prueban para garantizar que funcionen correctamente, y todos los componentes se prueban individualmente. Por ejemplo, probar una función o si una declaración o bucle en un programa funciona correctamente estaría dentro del alcance de las pruebas unitarias.

Prueba de componentes

La prueba de componentes verifica la funcionalidad de una parte individual de una aplicación. Las pruebas se realizan en cada componente de forma aislada de otros componentes. En general, las aplicaciones de React se componen de varios componentes, por lo que la prueba de componentes trata de probar estos componentes individualmente.

Por ejemplo, considere un sitio web que tiene diferentes páginas web con muchos componentes. Cada componente tendrá sus propios subcomponentes. La prueba de cada módulo sin considerar la integración con otros componentes se conoce como prueba de componentes.

Hacer pruebas como esta en React requiere herramientas más sofisticadas. Entonces, necesitaríamos Jest y, a veces, herramientas más sofisticadas, como Enzyme, que discutiremos brevemente más adelante.

Prueba de instantánea

Una prueba de instantánea se asegura de que la interfaz de usuario (UI) de una aplicación web no cambie inesperadamente. Captura el código de un componente en un momento en el tiempo, para que podamos comparar el componente en un estado con cualquier otro estado posible que pueda tener.

Aprenderemos sobre las pruebas de instantáneas en una sección posterior.

Ventajas y desventajas de las pruebas

La prueba es excelente y debe hacerse, pero tiene ventajas y desventajas.

Ventajas

  1. Previene regresiones inesperadas.
  2. Permite al desarrollador concentrarse en la tarea actual, en lugar de preocuparse por el pasado.
  3. Permite la construcción modular de una aplicación que de otro modo sería demasiado compleja de construir.
  4. Reduce la necesidad de verificación manual.

Desventajas

  1. Necesita escribir más código, así como depurar y mantener.
  2. Las fallas de prueba no críticas pueden hacer que la aplicación sea rechazada en términos de integración continua.

Introducción a la broma

Jest es un maravilloso marco de prueba de JavaScript que se centra en la simplicidad. Se puede instalar con npm o Yarn. Jest encaja en una categoría más amplia de utilidades conocidas como corredores de prueba. Funciona muy bien para aplicaciones React, pero también funciona muy bien fuera de las aplicaciones React.

Enzyme es una biblioteca que se utiliza para probar aplicaciones React. Está diseñado para probar componentes y permite escribir aserciones que simulan acciones que confirman si la interfaz de usuario funciona correctamente.

Jest y Enzyme se complementan muy bien, por lo que en este artículo usaremos ambos.

Proceso de ejecutar una prueba con Jest

En esta sección, instalaremos Jest y escribiremos pruebas. Si es nuevo en React, le recomiendo que use Create React App, porque está lista para usar y viene con Jest.

 npm init react-app my-app

Necesitamos instalar Enzyme **** y enzyme-adapter-react-16 con react-test-renderer (el número debe basarse en la versión de React que está usando).

 npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer

Ahora que hemos creado nuestro proyecto con Jest y Enzyme, necesitamos crear un archivo setupTest.js en la carpeta src del proyecto. El archivo debería verse así:

 import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() });

Esto importa Enzyme y configura el adaptador para ejecutar nuestras pruebas.

Antes de continuar, aprendamos algunos conceptos básicos. Algunas cosas clave se usan mucho en este artículo, y deberá comprenderlas.

  • it or test Pasaría una función a este método, y el ejecutor de pruebas ejecutaría esa función como un bloque de pruebas.
  • describe Este método opcional es para agrupar cualquier número de sentencias it o test .
  • expect Esta es la condición que la prueba necesita para pasar. Compara el parámetro recibido con el comparador. También le da acceso a una serie de comparadores que le permiten validar diferentes cosas. Puedes leer más sobre esto en la documentación.
  • mount Este método representa el DOM completo, incluidos los componentes secundarios del componente principal, en el que estamos ejecutando las pruebas.
  • shallow Esto representa solo los componentes individuales que estamos probando. No renderiza componentes secundarios. Esto nos permite probar los componentes de forma aislada.

Creación de un archivo de prueba

¿Cómo sabe Jest qué es un archivo de prueba y qué no lo es? La primera regla es que cualquier archivo que se encuentre en cualquier directorio con el nombre __test__ se considera una prueba. Si coloca un archivo JavaScript en una de estas carpetas, Jest intentará ejecutarlo cuando llame a Jest, para bien o para mal. La segunda regla es que Jest reconocerá cualquier archivo con el sufijo .spec.js o .test.js . Buscará los nombres de todas las carpetas y todos los archivos en todo su repositorio.

Vamos a crear nuestra primera prueba, para una miniaplicación de React creada para este tutorial. Puedes clonarlo en GitHub. Ejecute npm install para instalar todos los paquetes y luego npm start para iniciar la aplicación. Consulte el archivo README.md para obtener más información.

App.test.js para escribir nuestra primera prueba. Primero, verifique si nuestro componente de la aplicación se procesa correctamente y si hemos especificado una salida:

 it("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const welcome = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(welcome)).toEqual(true); });

En la prueba anterior, la primera prueba, con shallow , verifica si el componente de nuestra aplicación se procesa correctamente sin bloquearse. Recuerde que el método shallow representa solo un componente, sin componentes secundarios.

La segunda prueba verifica si hemos especificado una salida de etiqueta h1 de "Mostrar cuenta de usuario activa" en nuestro componente de aplicación, con un comparador de bromas de toEqual .

Ahora, ejecuta la prueba:

 npm run test /* OR */ npm test

La salida en su terminal debería ser así:

 PASS src/App.test.js √ renders without crashing (34ms) √ renders Account header (13ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 11.239s, estimated 16s Ran all test suites related to changed files. Watch Usage: Press w to show more.

Como puede ver, nuestra prueba pasó. Muestra que tenemos un conjunto de pruebas llamado App.test.js , con dos pruebas exitosas cuando se ejecutó Jest. Hablaremos sobre las pruebas de instantáneas más adelante y también podrá ver un ejemplo de una prueba fallida.

Omitir o aislar una prueba

Omitir o aislar una prueba significa que cuando se ejecuta Jest, no se ejecuta una prueba marcada específica.

 it.skip("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const header = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(header)).toEqual(true); });

Se omitirá nuestra primera prueba porque hemos usado el método de skip para aislar la prueba. Por lo tanto, no se ejecutará ni realizará ningún cambio en nuestra prueba cuando se ejecute Jest. Solo correrá el segundo. También puede usar it.only() .

Es un poco frustrante hacer cambios en un archivo de prueba y luego tener que ejecutar manualmente npm test nuevamente. Jest tiene una característica agradable llamada modo de observación, que observa los cambios en los archivos y ejecuta las pruebas en consecuencia. Para ejecutar Jest en modo reloj, puede ejecutar npm test -- --watch o jest --watch . También recomendaría dejar Jest ejecutándose en la ventana de la terminal por el resto de este tutorial.

Función de burla

Un simulacro es un duplicado convincente de un objeto o módulo sin ningún funcionamiento interno real. Puede que tenga un poco de funcionalidad, pero en comparación con lo real, es un simulacro. Puede ser creado automáticamente por Jest o manualmente.

¿Por qué debemos burlarnos? La simulación reduce la cantidad de dependencias, es decir, la cantidad de archivos relacionados que deben cargarse y analizarse cuando se ejecuta una prueba. Por lo tanto, usar muchos simulacros hace que las pruebas se ejecuten más rápidamente.

Las funciones simuladas también se conocen como "espías", porque le permiten espiar el comportamiento de una función a la que otro código llama directamente, en lugar de solo probar la salida.

Hay dos formas de simular una función: ya sea creando una función simulada para usarla en el código de prueba, o escribiendo una simulación manual para anular la dependencia de un módulo.

Los simulacros manuales **** se utilizan para eliminar la funcionalidad con datos simulados. Por ejemplo, en lugar de acceder a un recurso remoto, como un sitio web o una base de datos, es posible que desee crear un simulacro manual que le permita usar datos falsos.

Usaremos una función simulada en la siguiente sección.

Prueba de componentes de reacción

La sección combinará todo el conocimiento que hemos adquirido hasta ahora para comprender cómo probar los componentes de React. La prueba implica asegurarse de que la salida de un componente no haya cambiado inesperadamente a otra cosa. La construcción de componentes de la manera correcta es, con diferencia, la forma más eficaz de garantizar el éxito de las pruebas.

Una cosa que podemos hacer es probar los accesorios de los componentes, específicamente, probar si los accesorios de un componente se pasan a otro. Jest y la API de Enzyme nos permiten crear una función simulada para simular si los accesorios se pasan entre componentes.

Tenemos que pasar los accesorios de la cuenta de usuario del componente principal de la App al componente de la Account . Necesitamos proporcionar los detalles de la cuenta de usuario a Account para generar la cuenta activa de los usuarios. Aquí es donde la burla resulta útil, ya que nos permite probar nuestros componentes con datos falsos.

Vamos a crear un simulacro para los accesorios del user :

 const user = { name: "Adeneye David", email: "[email protected]", username: "Dave", };

Hemos creado una función simulada manual en nuestro archivo de prueba y la hemos envuelto alrededor de los componentes. Digamos que estamos probando una gran base de datos de usuarios. No es aconsejable acceder a la base de datos directamente desde nuestro archivo de prueba. En su lugar, creamos una función simulada, que nos permite usar datos falsos para probar nuestro componente.

 describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); }); describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });

Tenemos dos pruebas arriba y usamos una capa de describe , que toma el componente que se está probando. Al especificar los accesorios y valores que esperamos que pase la prueba, podemos continuar.

En la primera prueba, verificamos si los accesorios que pasamos al componente montado son iguales a los accesorios simulados que creamos anteriormente.

Para la segunda prueba, pasamos las propiedades del usuario al componente Account montado. Luego, verificamos si podemos encontrar el elemento <p> que corresponde a lo que tenemos en el componente Account . Cuando ejecutemos el conjunto de pruebas, verá que la prueba se ejecuta correctamente.

También podemos probar el estado de nuestro componente. Verifiquemos si el estado del mensaje de error es igual a nulo:

 it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); }); it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });

En esta prueba, verificamos si el estado del error de nuestro componente es igual a nulo, usando un toEqual() . Si hay un mensaje de error en nuestra aplicación, la prueba fallará cuando se ejecute.

En la siguiente sección, veremos cómo probar los componentes de React con pruebas de instantáneas, otra técnica increíble.

Pruebas de instantáneas

La prueba de instantáneas captura el código de un componente en un momento dado, para compararlo con un archivo de instantáneas de referencia almacenado junto con la prueba. Se utiliza para realizar un seguimiento de los cambios en la interfaz de usuario de una aplicación.

La representación de código real de una instantánea es un archivo JSON, y este JSON contiene un registro de cómo se veía el componente cuando se realizó la instantánea. Durante una prueba, Jest compara el contenido de este archivo JSON con la salida del componente durante la prueba. Si coinciden, pasa la prueba; si no lo hacen, la prueba falla.

Para convertir un envoltorio de Enzyme a un formato que sea compatible con la prueba de instantáneas de Jest, tenemos que instalar enzyme-to-json :

 npm install --save-dev enzyme-to-json

Vamos a crear nuestra prueba instantánea. Cuando lo ejecutamos por primera vez, la instantánea del código de ese componente se compondrá y se guardará en una nueva carpeta __snapshots__ en el directorio src .

 it("renders correctly", () => { const tree = shallow(<App />); expect(toJson(tree)).toMatchSnapshot(); });

Cuando la prueba anterior se ejecuta con éxito, el componente de la interfaz de usuario actual se comparará con el existente.

Ahora, hagamos la prueba:

 npm run test

Cuando se ejecute el conjunto de pruebas, se generará una nueva instantánea y se guardará en la carpeta __snapshots__ . Cuando ejecutemos una prueba posteriormente, Jest verificará si los componentes coinciden con la instantánea.

Como se explicó en la sección anterior, ese método shallow del paquete Enzyme se usa para renderizar un solo componente y nada más. No renderiza componentes secundarios. Más bien, nos brinda una buena manera de aislar el código y obtener mejor información al depurar. Otro método, llamado mount , se usa para representar el DOM completo, incluidos los componentes secundarios del componente principal, en el que estamos ejecutando las pruebas.

También podemos actualizar nuestra instantánea. Hagamos algunos cambios en nuestro componente para que nuestra prueba falle, lo que sucederá porque el componente ya no se corresponde con lo que tenemos en el archivo de instantánea. Para hacer esto, cambiemos la etiqueta <h3> en nuestro componente de <h3> Loading...</h3> a <h3>Fetching Users...</h3> . Cuando se ejecute la prueba, esto será lo que obtendremos en la terminal:

 FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received

Mostrar detalles de la cuenta de usuarios activos

- Cargando... + Obteniendo Usuarios...

7 | it("se procesa correctamente", () => { 8 | contenedor const = superficial ( ); > 9 | expect(toJson(envoltorio)).toMatchSnapshot(); | ^ 10 | }); 11 | 12 | /* it("se renderiza sin fallar", () => { en Objeto. (src/App.test.js:9:27) › 1 instantánea fallida. Resumen de instantáneas › Falló 1 instantánea de 1 conjunto de pruebas. Inspeccione los cambios de su código o presione `u` para actualizarlos. Conjuntos de pruebas: 1 fallido, 1 en total Pruebas: 1 fallida, 1 en total Instantáneas: 1 fallida, 1 en total Tiempo: 92.274s Ejecutó todos los conjuntos de pruebas relacionados con los archivos modificados. Uso del reloj: presione w para mostrar más.

Si queremos que pase nuestra prueba, cambiaríamos la prueba a su estado anterior o actualizaríamos el archivo de instantánea. En la línea de comandos, Jest proporciona instrucciones sobre cómo actualizar la instantánea. Primero, presione w en la línea de comando para mostrar más y luego presione u para actualizar la instantánea.

 › Press u to update failing snapshots.

Cuando presionemos u para actualizar la instantánea, la prueba pasará.

Conclusión

Espero que hayas disfrutado trabajando en este tutorial. Hemos aprendido algunas técnicas de prueba de Jest utilizando la biblioteca de pruebas de Enzyme. También le presenté el proceso de ejecutar una prueba, probar componentes de React, simulacros y pruebas de instantáneas. Si tiene alguna pregunta, puede dejarla en la sección de comentarios a continuación, y estaré encantado de responder a cada una y resolver cualquier problema con usted.

Recursos y lecturas adicionales

  • Documentación de broma
  • Documentación de enzimas
  • “Cómo probar los componentes de React: la guía completa”, Mohammad Iqbal, freeCodeCamp
  • “Probando React con Jest y Enzyme”, Dominic Fraser, CodeClan