¿Cómo administrar el código heredado frágil?

¿Cómo administrar el código heredado frágil?

¡Bienvenido al mundo real! Después de hacer todos los ejemplos de aprendizaje simplificados, ha comenzado su primer trabajo de TI. Es muy probable que después de realizar algunas tareas de preparación, te des cuenta de que hay un código antiguo desagradable en el proyecto en el que estás trabajando. Si tienes suerte, hay alguien en tu equipo que intenta protegerte para que no te aventures demasiado en esa zona oscura, pero puedes estar seguro de que no durará para siempre. Deberá enfrentarse a la realidad en algún momento—gran parte de su trabajo diario consistirá en mantener una base de código heredada. Veamos cómo puedes hacer que esta experiencia sea lo más manejable posible.

Hojear el código

Obtén el código y sumérgete un poco en él. Es probable que el código existente sea confuso, que los archivos sean demasiado grandes y que todo parezca un desastre. Al principio, podría concentrarse en la estructura del archivo para encontrar patrones. En un proyecto con una larga historia y poco enfoque en la consistencia, es probable que encuentre diseños de la competencia utilizados de manera aparentemente aleatoria. En este caso, solo trate de averiguar qué tan malo fue y deje la sistematización para más adelante.

README actualización

Después de revisar el código, evaluemos el estado de la documentación. Debería haber algún tipo de archivo README. Tal vez esté criminalmente desactualizado, pero al menos menciona las ideas utilizadas en la creación del código base. Puede intentar actualizar la información a medida que encuentre algunas piezas obsoletas. Un buen lugar para comenzar es integrar lo que recibió en los correos electrónicos y otras comunicaciones sobre el proyecto y asegurarse de que esté reflejado y vinculado desde el README. Además, asegúrese de actualizarlo regularmente para que la próxima persona en el proyecto tenga un comienzo más fácil.

Descubre el proceso de construcción

Recientemente trabajé en un curso de actualización de Angular que recibió su última actualización hace tres años. Los primeros videos estaban en Angular 4—una versión tan antigua que tiene problemas de compatibilidad con las Node.js y procesadores mas actuales. Pasé por una cascada de actualizaciones forzadas antes de poder construirlo en mis máquinas—y eso fue solo en un pequeño proyecto de ejemplo. Un proyecto que heredes en el mundo real probablemente estará en un estado mucho peor.

Con suerte, todo lo que necesita para construir el proyecto con éxito será

  1. cubierto por LÉEME u otra documentación,
  2. todavía al día, y
  3. trabajando como se esperaba.

Lo más probable es que su proyecto no cumpla con esos puntos en el camino, lo que le permitirá resolverlo por su cuenta. Si está fallando, puede buscar el error y ver qué lo está causando.

Si no hay nada útil en la documentación, el siguiente lugar para verificar es package.json. Puede haber algún comando similar a una compilación entre ”scripts”. En el peor de los casos, puede buscar rastros de herramientas de compilación que fueron populares en el pasado y participar en una especie de arqueología de JavaScript:

  • grunt
  • gulp
  • webpack
  • browserify
  • require.js

Image description

Y el despliegue

Eso también puede ser divertido. No saber dónde se ejecutan sus sistemas es bastante frustrante: hace que se preocupe por lo que podría pasar si se estropean. Teníamos un chatbot interno y no pudimos averiguar dónde vivía durante unos meses. Esta información debería estar disponible más fácilmente para más sistemas de misión crítica, pero esas cosas a menudo toman más tiempo de lo esperado.

Descubrir todos los detalles sobre su implementación de producción puede llevar mucho tiempo. Podría detenerse por no tener el usuario correcto, perder credenciales para algunas áreas y tener que verificar todo dos veces para evitar romper cosas. ¡Felicidades! Puede hacer un cambio de código en su máquina que llegue a producción. Tu trabajo puede tener un impacto.

Investigue las medidas de garantía de calidad (QA) existentes:

De manera similar a lo que hizo para la compilación, intente encontrar lo que sea que esté disponible para

  • Pruebas de integración,
  • Pruebas unitarias, y
  • Lint.

Si no está documentado y no está definido en los scripts de package.json, puede buscar algunas herramientas que eran comunes en el pasado.

  • Pruebas de integración:
    • protractor
    • selenium
  • Pruebas unitarias:
    • jasmine
    • mocha
    • sinon
  • Lint:
    • jslint
    • jshint
    • tlint

Si hay rastros de medidas de control de calidad automatizadas configuradas en el pasado, intente reutilizarlas tanto como sea posible. Puede haber un valor real en todas las cosas que configuraron los desarrolladores anteriores, y sería una pena tirarlo todo.

Establecer una prueba de humo

Si está restaurando un motor antiguo, en el primer intento, lo encenderá sin carga para ver si funciona sin quemarse. Esto se llama prueba de humo—todo está bien, siempre y cuando no veamos humo. Lo mismo ocurre con el código heredado: cuando no tiene nada con lo que probar la aplicación a fondo, al menos puede compilarla y ver si la aplicación se inicia correctamente. Hasta que pueda ejecutar pruebas más sofisticadas automáticamente, es mejor que se limite a cambios directos y utilice este mismo procedimiento básico para asegurarse de que todo funcione como se espera.

Image description

Comience con pequeños cambios

El proceso de reactivación del proyecto va bastante bien; ahora está listo para comenzar a realizar cambios en el código. Comience con algo pequeño, con cosas que nadie notará. Usted puede

  • actualizar la versión del parche de alguna biblioteca,
  • cambiar el nombre de algunas variables locales, o
  • refactorizar algunos antipatrones molestos en un solo lugar.

Recuerde que su meta es hacer un cambio que casi seguro no tendrá efectos secundarios.

Implementar en producción

Cree el código con sus cambios triviales e impleméntelo en todos los entornos hasta la producción. Su objetivo es hacer un ejemplo de este proceso restaurado—hacer que los cambios de código pasen de su cabeza a las máquinas de los clientes. Es lo suficientemente desafiante por sí solo; es por eso por lo que mantuvimos el alcance de nuestros cambios al mínimo. Su objetivo es brindarle a usted y a las partes interesadas confianza en el proceso.

Agregar pruebas de integración

Lo más probable es que tenga que crear pruebas de integración desde cero. Me refiero a esas pruebas que comprueban que todo está integrado y funciona en conjunto. Otro nombre es extremo a extremo (e2e) porque a menudo se prueban tanto el frontend como el backend juntos. Debes comenzar aquí porque no importa si calculas el IVA correctamente si la aplicación falla cuando inicias una nueva transacción. Al principio, puede tener más sentido desarrollar pruebas simples para muchas páginas en lugar de pruebas precisas solo para unas pocas. Una prueba tan simple como visitar una ruta y verificar si los elementos clave de la interfaz aún están presentes puede proporcionar mucho valor—esto detecta instancias en las que alguna página se rompe por completo.

Image description

Configure y comience a agregar pruebas unitarias

Una vez que sepa que la aplicación se está iniciando como se esperaba, puede entrar en los detalles y ver si todas las unidades—clases, funciones, etc.—funcionan como se esperaba. Puede probarlos desde el nivel de la interfaz de usuario, pero las pruebas de extremo a extremo son:

  • lento para escribir—obtener los datos correctos en el lugar correcto lleva mucho tiempo
  • lento para ejecutar—tener una base de datos, un backend y un navegador en ejecución consume muchos recursos

En lugar de incluir todos los casos extremos imaginables en su configuración de integración, desea tener una configuración de prueba separada para obtener más detalles esenciales. Quiere pruebas unitarias. Ellos:

  • son órdenes de magnitud más rápidos de ejecutar que e2e
  • están desconectados del backend y la base de datos
  • permite probar partes atómicas de su aplicación, independientemente del código y los flujos de trabajo circundantes

¿Quieres aprender más? Aquí puede encontrar mi razón para escribir pruebas unitarias.

Verficar el código con lint

Los linters son análisis estáticos del código destinados a señalar las fuentes de problemas comunes. Es bueno tener un control regular que revise su código y le diga que todo está bien aquí. eslint, un linter popular para JavaScript y TypeScript, permite una gran cantidad de configuraciones. Puede configurar la configuración para detectar solo los problemas más problemáticos, arreglar todo el código base e integrarlo con su editor de código. Para seguir obteniendo más valor de la configuración, puede continuar iterando sobre la configuración, activando o desactivando diferentes reglas y agregando complementos específicos del marco. De esta manera, podrá hacer que su código mejore con el tiempo; y al mismo tiempo, cada paso será pequeño y no te llevará demasiado tiempo a la vez.

Hacer cumplir el estilo de codificación

Cumplir con el mismo formato facilita la lectura del código: de esta manera, no hay lugares con formatos extraños que atraigan su atención por la razón equivocada. La coherencia en el código base aporta una sensación de orden y facilita la confianza en el estado actual del proyecto. El estilo de codificación puede generar muchas discusiones acaloradas. No me importa mucho el formato en particular; Solo quiero hacer lo mismo, sin importar quién y cuándo escribió el código, y me gusta que el estilo se aplique automáticamente. Afortunadamente, en este momento contamos con herramientas obstinadas, como prettier, que pueden formatear proyectos completos en un momento y dejar solo unas pocas opciones para discutir dentro de su equipo. ¡Así que puede subcontratar tanto el formato en sí como las interminables discusiones al respecto a una herramienta externa!

Ir a través de actualizaciones fáciles de librerías

Ahora, hagamos algunas tareas finales de calentamiento. Puede intentar actualizar alguna dependencia de una versión de parche a una más nueva—por ejemplo, de la versión 1.2.3 a la 1.2.4. Su código probablemente esté usando versiones antiguas de todas las bibliotecas de terceros que usa. Actualizarlos requerirá mucho trabajo y es una buena inversión hacerlo: las nuevas versiones generalmente tienen algunas características nuevas, correcciones de seguridad y más materiales disponibles en línea. Incluso una actualización de parche no es un cambio trivial, y con todo el trabajo que hemos hecho aquí, deberíamos esperar uno de dos resultados:

  • las cosas fallan después de la actualización, pero son detectadas por una de nuestras capas de verificación, o
  • todo funciona bien—tanto en las pruebas como en la producción después de la implementación.

¡Asegúrate de no intentar apresurar esas actualizaciones! Haga uno a la vez, suelte y espere comentarios. Recuerde, le está enseñando a la gente a confiar en sus cambios, y lo último que necesita es una regresión.

Realice la mejora más pequeña y sencilla de cara al usuario

Hasta ahora, su trabajo ha sido casi invisible para los usuarios—a menos que haya logrado interrumpir la producción en algún momento. Con toda la infraestructura en su lugar, ¡está listo para entregar algo de valor! Elija el problema más pequeño y simple que pueda encontrar—un error tipográfico en alguna página o un margen faltante en un botón. Su objetivo es demostrarse a sí mismo y a los demás que puede solucionar problemas y realizar cambios en el código sin romper nada más. No lo arruines tratando de hacer algo impresionante.

Configurar la integración continua (CI)

Vendrán más solicitudes de cambio si el proyecto realmente está volviendo a la vida. En ese caso, tendrá sentido establecer una integración continua. Si está interesado en obtener más información, déjame saber en la encuesta:

¿Qué sigue?

¡Felicidades! Usted es la nueva persona de referencia para el código heredado. Disfrute de la seguridad laboral recién adquirida—el trabajo debe hacerse y no hay cola de personas dispuestas a hacerlo. Puede ser un excelente momento para verificar dos veces si su compensación está a la altura del mercado y cubre el valor que brinda a la empresa——lea más aquí.