Las mejores formas de probar sus aplicaciones sin servidor

Serverless es más que un modelo de ejecución de computación en la nube. Cambia la forma en que planificamos, creamos e implementamos aplicaciones. Pero también cambia la forma en que probamos nuestras aplicaciones.

Conoce a Alex. Alex es un desarrollador de JavaScript normal, que últimamente se ha centrado en Node.js.

Durante los últimos meses, sus buenos amigos, Anna y Jeff, siempre están hablando de esa cosa sin servidor. Incluso a pesar de que son molestos de vez en cuando, le gusta la idea de aplicaciones sin servidor. Incluso implementó algunas funciones simples en AWS Lambda y Azure en algún momento.

En algún momento, Alex y su equipo obtuvieron un nuevo proyecto. Después de un poco de análisis, Alex pensó que sería la opción perfecta para servidores sin servidor. Presentó la idea a su equipo. Algunos de los miembros del equipo estaban emocionados, a uno de ellos no le gustó, pero la mayoría no tenía una opinión sólida. Entonces, decidieron intentarlo: el proyecto no era demasiado grande y el riesgo era bajo.

El equipo leyó sobre la tecnología sin servidor y tuvo una idea de cómo estructurar su nueva aplicación. Pero nadie estaba seguro de cómo deberían encajar sin servidor en su proceso de desarrollo común.

En ese momento, su proceso se ve así:

  1. Analizan una nueva característica.
  2. Para funciones menos complejas, comienzan con el código, luego lo ejecutan localmente y agregan algunas pruebas al final.
  3. Para funciones más complejas, hacen su versión de TDD: comienzan con pruebas, luego escriben el código y lo prueban localmente.
  4. Cuando la función está lista, pasa a la herramienta de CI que la implementa en el entorno de prueba.
  5. Luego, el equipo de control de calidad adopta una nueva función para otra ronda de pruebas manuales. Si todo se ve bien, la aplicación pasa por CI a producción.

Decidieron comenzar paso a paso y luego resolver los problemas a medida que los encontraban.

Eligieron una pequeña función y, como era simple, comenzaron con el código. Cuando la parte de codificación estuvo lista, se encontraron con el primer obstáculo: ¿cómo se ejecutan las aplicaciones sin servidor localmente?

Pruebas locales

Con las aplicaciones sin servidor, no administra la infraestructura. Suena genial, pero ¿cómo ejecutas tu aplicación localmente? ¿Se puede incluso hacer eso?

Dependiendo de su aplicación y del proveedor sin servidor, puede ejecutar algunas partes de su aplicación localmente. Para hacerlo, puede utilizar algunas de las siguientes herramientas y técnicas:

  • Herramientas principales de Azure Functions (para funciones de Azure)
  • AWS SAM CLI (para aplicaciones AWS Lambda creadas con AWS SAM)
  • Herramientas de terceros (es decir, localstack)
  • docker-lambda para simulación local de AWS Lambda
  • Ejecutar la función Node.js localmente

Por supuesto, la lista no está completa: hay más herramientas y ahora vemos nuevas herramientas casi todos los días.

La mayoría de estas herramientas tienen ciertas limitaciones. Pueden simular funciones sin servidor y algunos otros servicios, como API Gateway. Pero, ¿qué pasa con los permisos, la capa de autenticación y otros servicios?

Las pruebas locales ayudan con validaciones rápidas para asegurarse de que su función funcione. Pero, ¿existe una mejor manera de asegurarse de que su aplicación sin servidor funcione según lo previsto? Sí hay. El primer paso y el más importante es: escribir pruebas.

Entonces Alex y su equipo probaron su primera función localmente, y parecía estar funcionando. Luego pasaron al siguiente paso.

Pruebas automatizadas

Alex y su equipo acaban de cambiar a Jest para probar sus aplicaciones Node.js. Todavía hacen mucho front-end, por lo que quieren usar las mismas herramientas para la pila completa siempre que puedan. ¿Pueden usar Jest para probar aplicaciones sin servidor también? ¿Y qué deberían probar?

Después de una investigación rápida, se dieron cuenta de que pueden usar sus herramientas de prueba favoritas de Node.js. Jest, Jasmine, Mocha y otros funcionan bien con servidores sin servidor.

¿Qué debería probar en una aplicación sin servidor?

Con sus aplicaciones Node.js, Alex y su equipo siguen la pirámide de automatización de pruebas de tres niveles. La pirámide de prueba fue mencionada por primera vez por Mike Cohn en su libro "Succeeding with Agile".

Como define la pirámide de prueba, tienen:

  • Muchas pruebas unitarias, porque son las más baratas (las más rápidas de escribir y ejecutar)
  • Menos pruebas de integración, porque son más caras y tardan más en ejecutarse
  • Algunas pruebas de IU, porque son las más caras (requieren alguna herramienta GUI) y las más lentas de ejecutar

Además de estos, también tienen pruebas manuales basadas en sesiones, realizadas por su equipo de control de calidad.

¿Cómo afecta la tecnología sin servidor a la pirámide de automatización de pruebas?

La respuesta depende del nivel. Pero la pirámide de prueba se parece menos a las pirámides egipcias y más a las pirámides mayas.

La capa de pruebas unitarias no se ve muy afectada. Las pruebas unitarias siguen siendo las más baratas de escribir y ejecutar, pero las unidades pueden ser más pequeñas.

La capa de pruebas de integración se vuelve más importante que nunca, porque las aplicaciones sin servidor dependen en gran medida de las integraciones. También es más económico, porque tener una base de datos sin servidor solo para pruebas es barato. Entonces, en una “pirámide de prueba” sin servidor, necesita tener más pruebas de integración.

La capa de pruebas de GUI también es más barata y rápida, debido a la paralelización más barata.

La capa de prueba manual permanece igual. Pero sin servidor puede ayudarte a mejorarlo ligeramente. Entraremos en detalles sobre eso más adelante.

Alex y su equipo finalmente tuvieron una idea de dónde concentrarse. El siguiente problema fue cómo escribir una función para probarlas más fácilmente.

Cómo escribir funciones sin servidor comprobables

Debe pensar en los siguientes riesgos mientras escribe una función sin servidor:

  • Riesgos de configuración ¿Son correctas la base de datos y la tabla? ¿O tiene derechos de acceso?
  • Riesgos técnicos del flujo de trabajo¿Está analizando y utilizando la solicitud entrante como debería? ¿O está manejando correctamente las respuestas correctas y los errores?
  • Riesgos de la lógica empresarial¿Seguiste todas las reglas de lógica empresarial que tiene tu aplicación?
  • Riesgos de integración ¿Está leyendo correctamente la estructura de solicitudes entrantes? ¿O está almacenando el pedido en la base de datos correctamente?

Para confirmar que su función sin servidor funciona correctamente, debe probar todos estos riesgos.

Puede probar cada uno de estos como lo hizo para las pruebas de integración. Pero configurar y configurar el servicio cada vez que desee probar uno de estos riesgos no es óptimo. Como le encanta decir a mi amigo Aleksandar Simovic:

Imagínese si las pruebas de automóviles se hicieran de esa manera. Eso significaría que cada vez que quisiera probar un solo tornillo o incluso un espejo en un automóvil, tendría que ensamblar y luego desmontar todo el automóvil.

Para que la aplicación sea más comprobable, la solución clara es dividir su función en varias más pequeñas.

Una de las mejores formas de hacerlo es aplicando Arquitectura Hexagonala sus funciones sin servidor.

La Arquitectura Hexagonal, o Puertos y Adaptadores , es una forma de arquitectura de aplicación que promueve la separación de preocupaciones a través de capas de responsabilidad. Como explica su creador, Alistair Cockburn:

Permita que una aplicación sea manejada igualmente por usuarios, programas, pruebas automatizadas o scripts por lotes, y que se desarrolle y pruebe de forma aislada de sus eventuales dispositivos y bases de datos en tiempo de ejecución.

Entonces, ¿cómo se aplica eso a las funciones sin servidor?

Mientras Alex y su equipo usan AWS, terminaron con una estructura como la siguiente:

  • La lógica empresarial de funciones expone pocos "puertos" (o espera pocos argumentos). Por ejemplo, uno para un evento entrante, uno para almacenamiento permanente y otro para notificaciones.
  • Tienen dos adaptadores para el evento que dispara una función, uno para el disparador AWS Lambda real y otro para las pruebas locales.
  • Disponen de varios adaptadores para almacenamiento permanente y notificaciones. Por ejemplo, adaptador de mesa DynamoDB y adaptador en memoria.

Alex y su equipo estaban felices de seguir adelante. Pero antes de continuar, veamos cómo afecta la Arquitectura Hexagonal a cada nivel de la pirámide de prueba.

Examen de la unidad

Las pruebas unitarias se mantuvieron igual. Pero es más fácil escribir pruebas unitarias gracias a la Arquitectura Hexagonal. Simplemente pueden usar un adaptador local o simularlo como un adaptador para probar la capa empresarial de función de forma aislada.

Pruebas de integración

Las pruebas de integración se beneficiaron mucho de la Arquitectura Hexagonal. Pudieron probar completamente las integraciones que poseen. Las integraciones de terceros se simulan con otros adaptadores.

¿Cómo funciona eso en la práctica?

Cada una de sus funciones sin servidor tiene archivos lambda.js y main.js. El archivo principal contiene la lógica empresarial de una función sin servidor. Y el archivo lambda.js se encarga de cablear los adaptadores e invocar el archivo main.js.

El archivo principal tiene su propia unidad y pruebas de integración. Pero sus pruebas de integración no prueban la integración completa con servicios finales, como AWS S3, porque eso los ralentizaría. En su lugar, utilizan un adaptador en memoria para probar la función con integración de almacenamiento de archivos.

La integración de AWS S3 se realiza a través de FileRepository , que tiene su propia unidad y pruebas de integración. Las comprobaciones de las pruebas de integración utilizan AWS S3 para asegurarse de que la integración final realmente funcione.

A diferencia de main.js , el archivo lambda.js no tiene pruebas, porque la mayoría de las veces solo tiene unas pocas líneas de código.

Este enfoque es como la técnica que utiliza el equipo de MindMup para probar funciones sin servidor. Con él, puede probar fácilmente integraciones de sus funciones y aún hacer que sus pruebas de integración sean más rápidas.

Prueba de GUI

Como Alex y su equipo estaban construyendo un backend para la aplicación, el nivel de pruebas de la GUI no era relevante. Pero a medida que aprendieron más sobre la tecnología sin servidor, se dieron cuenta de que podían usarlo para mejorar el nivel de pruebas de la GUI para las otras aplicaciones en las que estaban trabajando.

Las pruebas de IU son caras y lentas porque se ejecutan en el navegador. Sin embargo, la tecnología sin servidor es barata y se escala rápidamente.

Si pudieran ejecutar un navegador en AWS Lambda, obtendrían una paralelización barata. Eso haría que sus pruebas de interfaz de usuario fueran más baratas y rápidas.

Pero, ¿puede ejecutar un navegador, como Chrome, dentro de una función sin servidor?

¡Si! Y es fácil con la ayuda de herramientas como Serverless Chrome, Chromeless y Puppeteer.

Una combinación de navegadores sin servidor y sin cabeza puede brindarnos una nueva generación de herramientas de prueba de IU. Ya podemos ver y probar algunos de ellos, como Tasar.

CI / CD

Cuando Alex y su equipo probaron su primera función sin servidor, llegó el momento de implementar el código en el entorno de prueba. Eso planteó una nueva pregunta: ¿cómo pueden usar las herramientas de CI / CD para implementar su aplicación sin servidor?

La respuesta es simple: pueden usar una herramienta de CI para ejecutar las pruebas e implementar la aplicación. Para implementar la aplicación, use cualquier herramienta popular, como Claudia.js, AWS SAM y Serverless Framework.

Puede seguir utilizando su herramienta de CI favorita (como Jenkins, TravisCI o SemaphoreCI) o, si desea seguir con AWS, puede probar AWS CodeBuild.

Prueba manual

Incluso a través de las pruebas manuales no se ve afectado directamente por la tecnología sin servidor, el equipo encontró una manera de mejorar su proceso de control de calidad.

Las etapas y las implementaciones de aplicaciones sin servidor son baratas y, a menudo, rápidas de configurar. Además, con la tecnología sin servidor, no paga por la aplicación si nadie la está usando.

Esto significa que tener un entorno de prueba nunca ha sido más barato.

Además, con la tecnología sin servidor, a menudo puede promover la función de una etapa a otra. Esto significa que su equipo de control de calidad puede probar una función y, cuando confirman que funciona, puede promover la misma función a producción.

Más allá de las pruebas

Alex y su equipo enviaron su primera función sin servidor a la preproducción, y el equipo se alegró de haber aprendido a probar aplicaciones sin servidor.

Continuaron usando sin servidor en el proyecto y lo introdujeron en algunos otros proyectos. Alex se unió a sus amigos Anna y Jeff, como un tercer predicador sin servidor, a veces molesto. Y ellos vivieron felices para siempre.

Posdata

Pero a pesar de que su aplicación fue probada bien, algo sucedió de la noche a la mañana.

Después de una investigación, descubrieron que una de las integraciones cambió. Aprendieron que las pruebas son importantes para las aplicaciones sin servidor, pero no es suficiente.

Como las aplicaciones sin servidor dependen en gran medida de las integraciones, el riesgo se traslada de su código a las integraciones. Y, para poder detectar los cambios de integración y reaccionar rápidamente, su aplicación necesita un monitoreo adecuado.

Afortunadamente, cada día hay más herramientas de monitoreo sin servidor en el mercado. Algunas de las opciones buenas y populares son IOpipe, Thundra, Dashbird y Epsagon.

Pero, las aplicaciones sin servidor a menudo tienen un cliente pesado, lo que significa que el monitoreo de back-end no es suficiente. Necesita una herramienta similar para su interfaz. Este mercado también tiene muchas herramientas interesantes, como Sentry y Rollbar.

Pero con el espíritu de la tecnología sin servidor, creamos una aplicación de seguimiento de errores de código abierto llamada Desole. Es una aplicación sin servidor que puede instalar en su cuenta de AWS. Permite a las organizaciones realizar un seguimiento de las excepciones y los errores de las aplicaciones sin tener que elegir entre la comodidad del software como servicio y la seguridad de una solución autohospedada. Puedes comprobarlo aquí: //desole.io.

Todas las ilustraciones se crean utilizando la aplicación SimpleDiagrams4.

Si desea obtener más información sobre cómo probar y crear aplicaciones sin servidor con Node.js y AWS, consulte "Aplicaciones sin servidor con Node.js", el libro que escribí con Aleksandar Simovic para Manning Publications:

Aplicaciones sin servidor con Node.js

Una introducción convincente a las implementaciones sin servidor con Claudia.js. www.manning.com

El libro le enseñará más sobre las pruebas sin servidor, con ejemplos de código, pero también aprenderá cómo construir y depurar una API sin servidor del mundo real (con base de datos y autenticación) usando Node y Claudia.js. Y aprenderá a crear chatbots, para Facebook Messenger y SMS (usando Twilio) y habilidades de Alexa.