Tener el mejor código para lograr el mejor producto

Una historia de #BestProduct — Parte I: #BestCode

Nota: esta es la parte I de esta historia. Ya puedes continuar leyendo la 2da parte.

Déjenme contarles la historia de Lionel, un desarrollador que se acaba de incorporar a la empresa.

Está en su segundo día, luego de haber pasado por la inducción de RRHH, una inducción técnica por parte de ciertos integrantes del equipo de liderazgo de desarrollo y una introducción al negocio por parte del Product Manager del equipo.

Andrés, el referente técnico del equipo le cuenta que la idea es que cada integrante se autogestione al máximo, que el no asigna tareas sino que entre todos discuten cuál es la mejor estrategia para alcanzar rápido los objetivos que el equipo tiene.

Hasta que él pueda entrar en ese ritmo, ira participando de las dailys y demás ceremonias para familiarizarse con el contexto.

“Pero cómo acá buscamos que seamos productivos desde el día 1, me voy a tomar el atrevimiento de darte una tarea. Ayer deployamos un nuevo filtro de precios, y si bien funciona correctamente, se detectó que no está actualizando las cantidades del resto de los filtros. Fijate si lo podés arreglar”

Lionel encantado con la idea de ser productivo en su primer día, se puso manos a la obra. Luego que le indicaran algunos nombres de las clases que se encargaban del manejo de filtros, se puso a mirar ficheros en busca del error.

Lo primero que le sorprendió fue lo fácil que era leer el código. Estilo claro, buena separación de responsabilidades entre clases, comentarios útiles.

Al cabo de un rato, pudo comparar el funcionamiento de otro filtro que si funcionaba con el que estaba arreglando, y vio lo que faltaba para que éste funcione tan bien cómo los otros. Se dispuso a llamar a alguno de sus compañeros para validar su hallazgo, pero por esas casualidades en ese momento no había nadie en sus escritorios, seguramente habría alguna junta o algo así.

/

Naturalmente el siguiente paso era arreglar el código, así que se puso manos a la obra, y en unos minutos lo tuvo listo. Cómo seguía sin haber nadie, decidió hacer su “Git push” para luego más tarde mostrarle fácilmente el cambio al líder del equipo.

Se sorprendió bastante cuando al intentarlo el commit fue rechazado, porque automáticamente corrió una herramienta de estilo de código diciéndole que había cometido una ofensa en espaciado y nomenclatura de variables. ¡Eso explicaba porque el código se mantenía tan fácil de leer! Sólo podía subirse aquel que respete “las reglas de la casa”.

Por suerte era muy simple corregirlo y volver a hacer el push un minuto más tarde.

Esta vez se fastidió un poco, porque fue nuevamente rechazado. El error decía:

-“Haz intentado subir código que no está cubierto por un caso de prueba”

A pesar de su enojo inicial, se dio cuenta que era una muy buena práctica, y si bien hubiese preferido hacer su push y luego hacer el test, se puso manos a la obra para identificar dónde estaban alojados los sets de pruebas y ver si podía hacer el suyo. No debería ser difícil considerando que ya debería haber casos para estos filtros.

Efectivamente luego de un rato lo encontró, se dio cuenta que era bastante simple replicar uno para su porción de código e incluso podía mejorarlo para probar exactamente la actualización de otros filtros que había sido el problema que tuvo que arreglar. Se aseguraba así que este problema no iba a ocurrir nuevamente ante futuros cambios.

Se alivió mucho al ver que su tercer intento de “Git push” pasaba satisfactoriamente. Pero lo que lo sorprendió esta vez, es que se disparó automáticamente un build de la aplicación.

“Que bueno!” -pensó- “voy a poder pasar el nuevo build al equipo de release management para que Victor -el QA del equipo- le eche un ojo mañana o pasado y ver si esta apto para ir a producción en algunas semanas”

No había tocado mucho el tema de ambientes y release management en la inducción, pero le interesaba aprender cómo lo manejaban.

Lo que no se esperaba era lo que vio a continuación. La siguiente linea del script automático luego del build, decía “Creando ambiente de QA”, y si sus ojos no le fallaban, la consola de ejecución parecía estar creando automáticamente todos los componentes de un ambiente en la nube de forma automática.

”Increíble!” -pensó- “Victor va a poder mirarlo mucho más rápido de lo que pensaba”

/

Siguió mirando maravillado la ejecución del script, y a continuación vio algo que a esta altura si esperaba: un robot de Selenium empezó a ejecutar prueba tras prueba los miles de casos que había visto en el repositorio cuando tuvo que agregar el suyo. ¡Tenía mucho sentido! Era una forma increíblemente efectiva de garantizar la calidad del build antes de que lo viese el responsable de QA y de migrarlo al ambiente de UAT.

De hecho se quedó muy tranquilo por que efectivamente la ejecución se interrumpió por un fallo en uno de los casos. Inmediatamente reconoció su error: no había contemplado el caso de aplicar el filtro cuándo había un sólo resultado de búsqueda. Lo que no le gustó tanto fue ver que ¡su commit era nuevamente rechazado! A esta altura pensó que simplemente era un proceso de aceleración de QA. Pero pensándolo más profundamente entendió que estaba muy bien mantener el código base siempre listo para ir a producción y rechazar cualquier commit que no cumpliese ese criterio para no perjudicar a otros compañeros o equipos.

El error era muy simple, el caso de falla super claro, y era un fichero que había modificado hace minutos. Por lo que repararlo le costo prácticamente segundos. Y por supuesto, volvió a hacer el commit.

Para no perderse de nada, se quedó viendo nuevamente todo el script automático y ahora si vio cómo los casos finalizaban exitosamente. Pero mientras esperaba se iba preguntando que seguiría…

Y la realidad lo sorprendió.

Lo primero que ocurrió fue que se creo un nuevo ambiente de forma automática, se inició un robot de Jmeter que disparó 5000 request por minuto durante 10 minutos y envío un mensaje de “Test de carga finalizado satisfactoriamente” al terminar. Respiró aliviado, porque si hubiese perjudicado la performance en su primer día si que no sabría cómo mejorarlo. Y nuevamente se alegró de estar en un lugar que la performance fue tomada tan en serio que cada commit se evaluaba para evitar llevar degradación del servicio a producción.

Luego el script anunció “Integrando build en Staging”.

Esto tampoco lo esperaba… quizás mantenerlo unos días o semanas para liberarlo a Staging con otros commits del equipo hubiese sido más razonable.

Y nuevamente se corrió la batería de test automáticos pero ahora de forma integral con la última versión de todos los sistemas en un entorno y set de datos que suponía sería más cercano al de producción.

En paralelo el script le informó “Realizando pruebas de seguridad” y un nuevo set de pruebas automáticas especiales intentó infringir varias potenciales brechas de seguridad. Pasaron satisfactoriamente, seguramente gracias a lo insignificante de su cambio en este aspecto. Le agradó ver que la seguridad del sistema estaba garantizada desde el build y no sólo por auditorías semestrales que se podían perder mucho de lo que cambiaba diariamente en el sistema.

El script siguió…

/

Su mandibula casi se cae al piso con lo que paso a continuación. El script anunció en su monotono tono de ejecución que ese inocente fix que había commiteado hacía menos de una hora ¡estaba siendo desplegado de forma automática a producción!

Ya no había forma de pararlo…

Desesperado llamó al lider del equipo.

Andrés: “Lionel! ¿Todo bien? ¿Paso algo?”

Lio: “Auxilio! Hice un git push del fix. Y se ejecutó un script que lo está poniendo en producción. Mil disculpas, no sabía que iba a pasar eso! ¿Cómo puedo frenarlo?”

Lider: “¿Pero corrió las pruebas?”

Lionel le contó toda la historia, los commits rechazados, su sorpresa a medida que veía los pasos y cómo este último lo había tomado por sorpresa.

Andrés: “Ya sé, no te preocupes”

Lio: “¿Cómo que ya sabés?”

Andrés: “Claro, revisa el chat del equipo”

Lionel vió rápidamente cómo cada una de sus acciones había sido reportada, desde sus commits fallidos hasta el nuevo deploy a producción con su descripción informando automáticamente al equipo y otros stakeholders exactamente que requerimiento estaba subiendo y que archivos se habían modificado.

Andrés: “¡Tranquilo! Lo vengo siguiendo desde nuestra app de comunicación del equipo. Esa es la idea. Nuestro trabajo fundamental es hacer todo lo posible para que tengamos la mayor productividad. Justamente para que puedas ser productivo desde el día 0. Para que cualquier valor que nuestro código haya generado pueda llegar al cliente lo antes posible. Hiciste bien. Nuestro trabajo es dar las herramientas para que ir a producción con cualquier commit sea rápido y seguro”.

Luego de un suspiro de alivio, Lionel vió que mientras tenía la conversación telefónica el deploy había terminado. Entró a producción y vió que efectivamente el filtro ahora funcionaba 🙂

Andrés le informó que su cambio, como todos, fue habilitado para los usuarios de la red interna y 10% de los usuarios reales. Y que luego de 24hs si no se notaba ningún impacto negativo en las métricas pasaría al 100%.