Creando React Native Apps con Enzyme

Adrián Ferrera González
Lean Mind
Published in
7 min readSep 4, 2018
Photo by Zoltan Tasi on Unsplash

Como desarrollador, una de las cosas que más valoro de JavaScript es el hecho de poder desarrollar cualquier tipo de solución (móvil, web, sistemas…) sin perder la esencia y el conocimiento del lenguaje que estoy usando.

Tras llevar varios años desarrollando en plataformas web, el cambiar al desarrollo de aplicaciones móviles, haciendo uso de React Native me ha parecido sumamente interesante, pues he podido aplicar todo mi conocimiento y mis líneas de trabajo de la misma forma que lo venía haciendo hasta ahora, esto incluye el desarrollo dirigido por pruebas (TDD).

Pero como de costumbre, antes de empezar a contar la solución, haremos una breve introducción de conceptos.

React Native

Se trata de una librería creada por la gente de Facebook, que nos permite desarrollar aplicaciones móviles Android e iOS nativas con JavaScript.

Está basada en la librería de React, también creada por Facebook, pero a diferencia de ella, no trabajaremos sobre web. Lo que haremos será generar nuestro código y que este se ejecute en el dispositivo, llamando directamente a las funcionalidades nativas, tales como visualización de componentes, uso de cámara, sensores, etc.

¿La principal ventaja? únicamente tendremos que desarrollar una aplicación que se podrá ejecutar en cualquier plataforma, manteniendo las características nativas de cada una, y sin suponer un coste de rendimiento como ocurría en las aplicaciones híbridas, en las cuales se porta el código desarrollado en HTML5, CSS3 y JavaScript a los dispositivos móviles, donde este es interpretado y mostrado a través de un WebView.

Enzyme

Una parte indispensable que se debe llevar a cabo en cualquier desarrollo es la elaboración de tests. Una de las librerías de testing más icónicas a día de hoy para React, es la desarrollada por Airbnb: Enzyme. Al igual que su hermano mayor, React Native puede hacer uso de ella para comprobar determinadas tareas, como son: la renderización, llamada de eventos, montaje de componentes, etc.

La principal diferencia que vamos a encontrar es que esta librería, se ha desarrollado pensando en web, y por lo tanto la manipulación de elementos que no son HTML, va a diferir levemente y para determinados comportamientos de la misma, requeriremos de una configuración adicional.

Además, adelantaré que hay determinados métodos que a día de hoy NO SON COMPATIBLES, pero a pesar de ello, podremos testear nuestra aplicación casi por completo, con la misma naturalidad que en web.

Creando el proyecto

La forma más rápida con la que crear el proyecto será haciendo uso del cliente de react-native. Para ello, debemos tenerlo instalado como herramienta global create-react-native-app.

$ npm install -g create-react-native-app

Una vez instalada, solamente tendremos que usarla para crear nuestro proyecto con el nombre que deseemos:

$ create-react-native-app my-test-app-enzyme

Al tratarse de una aplicación móvil, esta deberá ser desplegada en un terminal. Existen varias opciones dependiendo de nuestros recursos y de la plataforma: Utilizar SDK de Android, Genimotion, Xcode, conectar el terminal… Pero la más sencilla será utilizar Expo.

Con ello cuando compilemos se nos facilitará un código QR que permitirá abrir la aplicación directamente en nuestro dispositivo.

Así pues, vamos a verificar que la aplicación se ha creado correctamente:

$ npm start
First Screen

El código está disponible en: https://github.com/adrian-afergon/my-test-app-enzyme/tree/Step-One

Instalando Enzyme

Una vez configurado nuestro entorno y arrancada nuestra aplicación, podemos proceder a instalar enzyme para testear la pantalla que se nos ha mostrado por defecto.

create-react-native-app ya habrá instalado Jest, no obstante podemos utilizar cualquier otra librería de test con la que nos sintamos más cómodos.

Para utilizar enzyme debemos instalar las siguientes dependencias:

$ npm install --save-dev enzyme enzyme-to-json enzyme-adapter-react-16 react-dom

Como mencionamos anteriormente, Enzyme está diseñado para manejar el DOM de HTML, sin embargo, react-native renderizará componentes nativos, es por ello, que deberemos transformar los componentes nativos a algo que la librería pueda entender.

El código está disponible en: https://github.com/adrian-afergon/my-test-app-enzyme/tree/Step-Two

Creando nuestro test

En nuestra aplicación ya se ha creado un fichero denominado App.test.js, el cual nos permite probar dicho componente con la herramienta de react-test-render.

Esta herramienta es adecuada para tests sin mucha complejidad, pero nosotros queremos ir un paso más allá, por lo que vamos a comenzar a configurar nuestro propio test tratando de duplicar esta lógica con Enzyme.

Antes de duplicarlo, verificaremos que el test funciona correctamente:

$ npm run test

Incluso, si lo preferimos, poderlo mantenerlo en funcionamiento constantemente hasta que finalicemos el desarrollo:

$ npm run test -- --watch

Una vez hecho esto deberíamos obtener el siguiente resultado en la consola:

Default test result for App.test.js

A continuación, añadiremos un Botón en nuestra vista sobre el que poder operar. Para ello, ya que estamos, aplicaremos TDD, crearemos un test que nos busque en la vista un elemento Button:

Si ejecutamos el test, en está ocasión nos dará un error, diciéndonos detalladamente que la afirmación de que el botón existe no es correcta:

Button not found for App.test.js

Así pues, podemos proceder a implementar el botón en la vista y ver como nuestro test pasa a verde:

Button founded in view App.js
Button displayed in view

El código está disponible en: https://github.com/adrian-afergon/my-test-app-enzyme/tree/Step-Three

Simulando eventos — Press

La parte esencial de estos tipos de test no es tanto el hecho de verificar si se pintan elementos en la pantalla sin más, sino el de validar comportamientos o respuestas en la interfaz basándonos en las interacciones del usuario.

Esta es una de las partes que más difieren de utilizar “Enzyme-web” frente a utilizarlo en una aplicación nativa, ya que el método simulate() no se encuentra disponible. Así pues, para simular un evento de click, tendremos que utilizar otro tipo de estrategia.

Añadiremos un nuevo test en el fichero App.test.js para demostrar el funcionamiento del mismo:

En esta ocasión, buscaremos el elemento Button, igual que antes. Accederemos a su nodo a través del método .get(0), también nos puede valer el método .first(). Desde él, podremos acceder a las props del componente y ejecutar el método .onPress(). Pero… esto no nos dice si realmente se ha ejecutado el método o no, simplemente nos demuestra que nuestro test no se ha roto.

Para poder realizar este test con algo más de fundamento, deberemos identificar qué es lo que va a hacer nuestro botón:

  • Nuestro botón va a realizar una llamada a otra clase y a ejecutar una lógica interna, como podría ser la llamada a un cliente REST.

Para dar solución a este planteamiento, la forma de testearlo, será dar la posibilidad al componente App para que pueda recibir el método que ejecuta al hacer click, mediante props. Es decir, lo que tenemos que hacer es dar la posibilidad de inyectarle un método mockeado. Para ello, tendremos que modificar nuestro componente de la siguiente manera:

Una vez hecho esto, únicamente tendremos que dirigirnos al test y pasar como parámetro en el constructor del elemento el método mockeado.

Este es un caso NO REAL, simplemente es la forma más sencilla de mostrar como inyectar un mock, ajeno a componentes, Redux, etc.

El código está disponible en: https://github.com/adrian-afergon/my-test-app-enzyme/tree/Step-Four

Simulando eventos — Change

Otro de los eventos más característicos y que no podremos simular de forma sencilla, es el .onChange(). Sin embargo, una vez nos hemos enfrentado de lleno al evento press, este no difiere especialmente.

En primer lugar, crearemos un test que nos busque un TextField en la interfaz, el cual tenga un evento de cambio:

Y por consiguiente en la interfaz:

Ahora bien, si lo que queremos es ejecutar un evento change, le deberemos pasar un evento simulado al método .onChangeText() del componente:

Y por consiguiente nuestra inyección del método change en la vista:

El código está disponible en: https://github.com/adrian-afergon/my-test-app-enzyme/tree/Step-Five

Conclusión

Como hemos demostrado, una forma muy práctica de saber que nuestra aplicación está funcionando constantemente es tener una amplia batería de test que verifiquen el comportamiento de la misma, independientemente de los cambios que realicemos.

Otra de las principales ventajas es que no tenemos que probar la aplicación a mano. En líneas generales la compilación y despliegue de una aplicación móvil en un terminal, no suele ser un proceso rápido, así pues, teniendo una buena cobertura de nuestro código, podemos optimizar muchísimo los tiempos de desarrollo… Y a quien vamos a engañar, nos mola decir que nuestro código tiene un nivel de cobertura alto y es seguro.

Adicionalmente, os dejo mi repositorio de Github, en el que se encuentra disponible todo el código expuesto en este artículo. Podéis encontrar en las distintas ramas, los pasos que hemos ido dando a lo largo del artículo.

Espero que os haya servido de ayuda a la hora e iniciaros en el testing de vuestra aplicación React-Native con Enzyme, si ha sido así, agradecería una valoración positiva.

También podéis poneros en contacto conmigo a través de mis redes sociales de Twitter y LinkedIn:

--

--