← Volver al blog Post

Creando React Native apps con Enzyme

Publicado originalmente en Medium.

Como desarrollador, una de las cosas que más valoro de JavaScript es poder construir soluciones muy distintas sin perder la esencia del lenguaje ni la forma de trabajar. Cuando di el salto desde desarrollo web a aplicaciones moviles con React Native, una de las cosas que mas me intereso fue precisamente esa continuidad. Tambien podia mantener una linea de trabajo basada en TDD.

Antes de entrar en la solucion, conviene repasar un poco de contexto.

React Native

React Native es una libreria creada por Facebook para desarrollar aplicaciones Android e iOS nativas con JavaScript. Se apoya en React, pero en lugar de renderizar HTML en el navegador, genera interfaces que terminan usando componentes nativos del dispositivo.

Eso permite compartir buena parte del conocimiento y del flujo de trabajo que ya traemos de React web, pero con una experiencia mas cercana a una app nativa que a una aplicacion hibrida montada sobre WebView.

Enzyme

Una parte indispensable de cualquier desarrollo es la bateria de tests. Durante mucho tiempo una de las librerias mas populares para testear componentes React fue Enzyme, creada por Airbnb. Tambien puede utilizarse con React Native para comprobar renderizado, montaje de componentes o respuesta a eventos.

La diferencia importante es que Enzyme fue pensada para web. Por eso, cuando trabajamos con componentes nativos, algunas interacciones no son exactamente iguales y cierta configuracion adicional resulta necesaria. Incluso hay metodos habituales en React web que aqui no estan disponibles.

Aun asi, se puede cubrir una parte muy amplia del comportamiento de la aplicacion sin perder demasiada naturalidad.

Creando el proyecto

La forma mas rapida de arrancar un proyecto, en el momento del articulo, era usar create-react-native-app:

npm install -g create-react-native-app
create-react-native-app my-test-app-enzyme

Despues de crear la aplicacion podemos arrancarla con:

npm start

Una forma muy comoda de probarla es Expo, que facilita abrir la app en un dispositivo real mediante un codigo QR.

Instalando Enzyme

Una vez que la aplicacion base funciona, podemos instalar las dependencias necesarias para usar Enzyme:

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

create-react-native-app ya incluye Jest, asi que el punto de partida de testing ya existe. Lo que toca ahora es adaptar Enzyme para que pueda entender la salida renderizada por React Native, ya que no se trata de un DOM HTML normal.

Creando nuestro test

El proyecto genera un App.test.js por defecto usando react-test-renderer. Ese test es una buena base para una comprobacion sencilla, pero la idea aqui es ir un paso mas alla y replicar esa logica con Enzyme.

Antes de tocar nada, conviene verificar que el test inicial funciona:

npm run test

Si queremos trabajar con feedback continuo:

npm run test -- --watch

Con eso confirmado, el siguiente paso puede ser tan simple como aplicar TDD y pedir desde el test algo que aun no existe en la interfaz. Por ejemplo, comprobar que hay un Button en pantalla. Primero escribimos el test, vemos el fallo, y despues implementamos el boton hasta llevar el estado de rojo a verde.

Ese ejercicio ya demuestra algo importante: con Enzyme podemos validar estructura y presencia de componentes tambien en React Native.

Simulando eventos press

La parte interesante no es solo verificar si algo se pinta, sino comprobar como responde la interfaz a las acciones de la persona usuaria.

Aqui aparece una diferencia clave con el uso de Enzyme en web: el metodo simulate() no esta disponible de la misma forma para estos componentes nativos. Para un press, una estrategia razonable es localizar el Button, acceder a su nodo y ejecutar directamente la callback expuesta en sus props, por ejemplo onPress().

Eso por si solo solo demuestra que el test no se rompe. Para que realmente tenga valor necesitamos poder observar una consecuencia de esa accion.

Una forma sencilla de hacerlo es permitir que el componente reciba por props el metodo que debe ejecutar al pulsar el boton. Asi podemos inyectar un mock desde el test y comprobar que se invoca correctamente. El ejemplo del articulo usa un caso deliberadamente simple, pero la idea es la misma que despues aplicariamos para delegar llamadas a clientes REST, acciones de Redux o cualquier otra logica externa.

Simulando eventos change

El evento de cambio en un campo de texto tiene la misma filosofia. Primero introducimos el elemento en la vista y despues probamos su reaccion.

En este caso, en lugar de disparar onPress(), lo que hacemos es invocar onChangeText() pasando un valor simulado. De nuevo, el componente debe estar preparado para recibir o delegar ese comportamiento de una forma que podamos observar desde el test.

La leccion importante es que, cuando los mecanismos directos de simulacion no existen o no son comodos, inyectar callbacks y verificar efectos observables sigue siendo una estrategia valida y practica.

Conclusion

Testear una aplicacion React Native con Enzyme requiere aceptar algunas diferencias respecto a React web, pero sigue siendo una forma muy util de verificar comportamiento de manera automatizada.

La ventaja no es solo tener mas cobertura. En desarrollo movil, compilar, desplegar y probar manualmente en un dispositivo suele ser un proceso mas lento que en web. Si la aplicacion cuenta con una buena bateria de tests, el ciclo de desarrollo se acelera y ganamos seguridad para introducir cambios.

En resumen:

  • Podemos reutilizar buena parte de la mentalidad y las practicas de testing de React.
  • Algunos eventos no se simulan igual que en web.
  • Inyectar callbacks mediante props ayuda a comprobar comportamiento real.
  • Una cobertura razonable reduce mucho el coste de validacion manual.

Si estas empezando a testear una app React Native, Enzyme puede servirte como puente natural desde el ecosistema React tradicional.

  • react-native
  • enzyme
  • testing
  • tdd