Pero... ¡en mi máquina funciona!

"Pero... en mi máquina funciona" puede deberse a diferencias en configuración, dependencias de librerías o sistemas operativos. Importante probar en entornos similares y trabajar en equipo para garantizar un rendimiento consistente. Descubre qué soluciones puedes tomar para resolverlo.

Pero... ¡en mi máquina funciona!

Este artículo iba a ser un conjunto de frases que los desarrolladores en la mayoría de los proyectos repiten...  expresando en pocas palabras situaciones importantes en las que cualquier líder de equipo tiene que actuar... pero la primera ya merece un post ;)

— Pero...¡En mi máquina funciona!

Los que la conocéis tenéis 2 opciones o empezar a reíros para liberar la tensión o a llorar porque sabéis lo que viene... Esta expresión suele venir acompañada con problemas de conexión... cuando se produce el silencio esperando que explique el motivo por el que "alguien ha subido algo" que no funciona en producción o en el mejor de los casos en el staging o entorno de preproducción y, lamentablemente, coincidió con pruebas del cliente...

Las causas de este tipo de problemas son muchas.. aquí vamos a daros algunas ideas por donde empezar:

💡
Advertencia: Usaré la palabra programador o desarrollador pues caracterizan al profesional según el tipo de problema... También abusaré de frameworks de python ;)

Problemas de configuración del entorno:

Muchas veces, un programador puede haber configurado su entorno local de manera diferente al entorno de producción o de otro desarrollador. Sobre todo cuando trabajamos con equipo remoto y no controlamos el entorno de desarrollo. Como resultado, una función o característica puede funcionar correctamente en su máquina, pero no en otro lugar.

💡
Para estos casos lo ideal es tener scripts de virtualenvironment o ansible que configuren el entorno de forma homogénea a todos los desarrolladores.
💡
Un virtual environment es un directorio que contiene una versión específica de python y todos sus paquetes asociados. Los virtual environment están perfectamente aislados, por lo que puedes tener tantos entornos virtuales como quieras en tu Mac o linux, y tener siempre muy claro con cuál estás trabajando.
💡
Ansible® es una herramienta de automatización de TI de código abierto que automatiza el aprovisionamiento, la gestión de la configuración, el despliegue de aplicaciones, la orquestación y muchos otros procesos manuales de TI. A diferencia de otras herramientas de gestión más simplistas, los usuarios de Ansible (como administradores de sistemas, desarrolladores y devops) pueden utilizar la automatización de Ansible para instalar software, automatizar tareas cotidianas, aprovisionar infraestructuras, mejorar la seguridad y el cumplimiento normativo, parchear sistemas y compartir la automatización en toda la organización.

Dependencias faltantes o versiones diferentes:

Un Programador podría tener todas las dependencias necesarias instaladas en su máquina, pero al compartir el código con otros, podrían encontrarse con que algunas dependencias faltan o están en versiones diferentes, lo que puede afectar el funcionamiento del software.

Recomendación: uso de poetry en vez de requirements.txt

💡
Herramientas como PIP, Conda o los sencillos archivos requirements.txt no pueden resolver este problema de gestión de dependencias en proyectos grandes. Todo lo contrario, esta pesadilla es causado en gran parte por ellas. Así que, para poner fin a su sufrimiento, la comunidad de código abierto de Python desarrolló esta fantástica herramienta conocida como Poetry. Este framework de gestión de dependencias posee casi 26.000 estrellas en GitHub y actualizaciones cada pocos días.
💡
Poetry es una herramienta de gestión de dependencias y empaquetado en Python. Te permite declarar las bibliotecas de las que depende tu proyecto y las gestionará (instalará/actualizará) por ti. Poetry ofrece un archivo de bloqueo para garantizar instalaciones repetibles, y puede construir el proyecto para su distribución.

Datos de prueba:

Si un desarrollador está probando con datos específicos en su máquina y no se tienen en cuenta otros escenarios posibles, fácilmente se puede obtener un comportamiento diferente al esperado cuando se realicen pruebas en un entorno más amplio o con datos reales.

💡
En esta etapa de desarrollo las pruebas unitarias son responsabilidad del desarrollador, que debe haber creado siguiendo la metodología TDD (Test Driven Development). Comprobar el funcionamiento de pequeñas funciones es sencillo y no requiere de datos complejos para chequear su funcionamiento. En cambio, las pruebas de regresión, integración, funcionales y de aceptación son ya parte de la actividad normal del QA y requerirán de una metodología de uso de datos bien diseñada. 

Sistemas operativos distintos:

Cada sistema operativo puede tener particularidades que afecten el comportamiento de una aplicación. Lo que funciona en una máquina con un sistema operativo determinado podría no funcionar en otra con un sistema operativo diferente.

Esto se convierte en un problema por ejemplo cuando hay que compilar apps en distintos S.O. (iOS, Android..)

💡
Como ya hemos visto, cualquier variación en el entorno de desarrollo en el equipo es un problema por lo que recomendamos unificar criterios. Nuestra recomendación es que todos trabajen en linux, en la misma versión. Si esto no es posible el uso de todas las herramientas anteriores serán necesarias, pero triplicando los esfuerzos, lo que implica la dedicación de un devop experto para configurar correctamente los entornos de desarrollo en cada máquina... coste que de verdad... no compensa. Al final, mantener un entorno de desarrollo heterogéneo lleva al caos. Existen alternativas para evitar que el desarrollador tenga que instalarse un S.O. en su máquina, como son los entornos de escritorio en CLOUD. Tienen un coste importante aunque en proyectos donde la seguridad es clave, deberíamos tenerlos en cuenta.

Entorno de red:

En aplicaciones que requieren acceso a la red o servicios externos, las diferencias en la conectividad y la infraestructura pueden causar problemas. Una aplicación podría funcionar bien en una red local, pero fallar en una red externa.

💡
Repeticion de situaciones anteriores añadiéndose la complejidad de la infraestructura, de nuevo, cualquier buena aplicación debe saber detectar estas situaciones, y una buena metodología de pruebas es necesaria. El QA debe existir y revisar todas las pruebas unitarias para evaluar si el desarrollador debería añadir nuevas.

Configuración de bases de datos:

Si la configuración de la base de datos difiere entre máquinas, puede conducir a comportamientos inesperados y errores.

💡
Los esquemas de las bases de datos de pruebas deben ser idénticos a los de producción, aunque los datos pueden estar modificados para impedir problemas de privacidad de la información o fugas de información. Ansible y docker dos herramientas fundamentales para evitar problemas de configuración en los sistemas.

En resumen, si queremos evitar sorpresas es importante que los desarrolladores prueben sus aplicaciones en entornos similares a los de producción, y utilicen herramientas para gestionar dependencias y configuraciones de manera sencilla y consistente. Además, aunque no lo hayamos nombrado, la colaboración y el trabajo en equipo son fundamentales para asegurar que las aplicaciones funcionen de manera coherente en diferentes máquinas y entornos.