Nueva aventura: proyecto de investigación

Luego de algunas discretas expediciones esporádicas al mundo de la investigación, este año voy a embarcarme formalmente en un proyecto de investigación junto a Diego Fontdevila y Alejandro Oliveros.

Si bien aún estamos en etapa de definiciones nuestro trabajo entra en la temática ingeniería de software y más específicamente en el área de prácticas y procesos.

Hemos decidido intentar gestionar este proyecto de investigación de forma similar a como gestionamos cotidianamente nuestros proyectos de desarrollo software. En ese sentido hemos bautizado el proyecto con un nombre clave: Paladine (nombre del líder de los hechiceros en el mundo DrangonLance).

Como parte de mi formación para llevar adelante este trabajo estoy cursando un seminario de Introducción a los métodos experimentales de investigación en Ingeniería de Software. Hasta el momento llevamos tan solo dos encuentros y ambos me han resultado extremadamente enriquecedores.

Continuará…

Anuncios

Un ejemplo de la fragilidad de los tests de UI

Ayer me enfrenté a un claro ejemplo de la fragilidad de los tests de UI. Resulta que hace un tiempo empecé a trabajar en una aplicación sin ningún tipo de tests y cuyo diseño hacía muy difícil generar tests unitarios y de componentes/api. Fue por ello que una de las primeras cosas que hice fue generar un set de pruebas de UI para tener algo de cobertura sobre los 3 flujos más críticos de la aplicación. Luego de un deploy a testing de una nueva versión, un test de regresión comenzó a fallar. Curiosamente el nuevo deploy no incluía ningún cambio que impactara directamente en la funcionalidad que el test cubría. Para sumar confusión a la situación, cuando corría tests en mi máquina, todo andaba perfecto, el fallo sólo se producía cuando el tests era ejecutado desde el build server.

Luego de un buen rato de troubleshooting, descubrí que habíamos tenido un cambio menor en un hoja de estilo, ese cambio hacía que cuando los tests se corrían en una máquina con una determinada resolución, dos elementos quedarán superpuestos haciendo que uno de ellos no fuera clickeable.

ui-fragil

Micro-servicios: ¿un nuevo buzzword?

Puede que si o puede que no. Algunas impresiones:

  • Hay gente que viene construyendo micro-servicios desde bastante tiempo antes de que el término se ponga de moda
  • Como suele ocurrir con toda moda en algún momento, hay gente que se está subiendo a esta iniciativa a pesar de que su contexto no lo requiere

Pero… ¿que es realmente esto de los micro-servicios? Es básicamente un nombre para identificar un conjunto de prácticas a nivel de diseño e implementación con foco en dos cuestiones:

  • Posibilidad de responder rápidamente a las necesidades del negocio
  • Soluciones robustas y escalables

El primer punto está íntimamente relacionado con la agilidad y la entrega continua y tiene un impacto directo en la forma de trabajo de los equipos/organizaciones a punto tal que resulta común que las organizaciones modifiquen sus estructuras de equipos al moverse hacía el mundo de los micro-servicios.

El segundo punto tiene una impronta mucho más técnica y a nivel implementación suele implicar cuestiones como: cloud computing, virtualización y dockerización.

¿Y a que se debe el nombre “micro-servicios”?

Hace unos 10 años hubo una fuerte “ola de servicios” en el contexto de SOA (Service Oriented Architecture). La implementación de iniciativas SOA implicó en la mayoría de los casos el uso de componentes de arquitectura “pesados” cuya administración/instalación solía tener un grado importante de complejidad. Al mismo tiempo muchas de las soluciones generadas en los contextos SOA no se caracterizaban por ser muy testeables (automatizamente).

Los micro-servicios deben su nombre en gran medida  a la intención de diferenciarse de lo que fueron las iniciativas SOA. Pues si bien hay puntos en común entre ambas iniciativas también hay importantes diferencias. Entre esas diferencias yo me inclino por los siguientes objetivos en el diseño de los micro-servicios:

  • Testeabilidad
  • Despliegue independiente y automatizado
  • Resiliencia
  • Escalabilidad horizontal

Continuará…

Automatización de test en proyecto “brown-field”

Hace poco más de un mes comencé a trabajar en un proyecto de desarrollo de una aplicación existente (brown-field project). La aplicación en cuestión era un monolito construido con una antigua versión de Grails y luego actualizado a Grails 2.5 y con no más de 30 pruebas unitarias. La visión del proyecto tenia 2 objetivos bien claros (sin ningún orden particular):

  • Realizar una rearquitectura de la aplicación para llevarla a un esquema de microservicios
  • Agregar un conjunto de funcionalidades relacionadas principalmente a cuestiones de integración con otras aplicaciones.

Una de mis primeras propuestas para el Product Owner fue comenzar generando un conjunto mínimo de pruebas end-2-end de regresión que nos dieran cierta seguridad para poder realizar modificaciones sobre la aplicación sin sonarla. El Product Owner siendo una persona de formación técnica estuvo de acuerdo con la propuesta y hacia allí fuimos. Comenzamos identificando las funcionalidades más críticas para el negocio y diseñando una arquitectura de pruebas para ellas.

Dado que la aplicación no había sido desarrollada con la “testeabilidad” en mente, resultaba muy dificil realizar pruebas que no unitarias y de API, asi que decidimos ir por un enfoque de caja negra realizando pruebas end-2-end que interactuaran con la aplicación via UI tal cual un usuario real.

Luego de un de par de pruebas de concepto llegamos a la siguiente arquitectura de tests:

test_arq

  • Gherkin: la idea de usar este DSL user-friendly no tiene un fundamento en que nos permite espeficar flujos funcionales desde una perspectiva de negocio.
  • Cucumber-JVM: como la aplicación está hecha en Grails el cual ya corre sobre JVM y los nuevos servicios se construirán en Java, nos pareio que Cucumber-JVM era la opción obvia. si es cierto que también podríamos haber usar JBehave, la realidad es que Cucumber-JVM está más difundido y por ello hay más documentación de soporte.
  • DB-Unit: lo utilizamos para cargar distintos set de datos para cada contexto de tests. Asimismo DBUnit se encarga de borrar los datos existentes antes de cargar cada dataset.
  • Selenium: era la opción default para interactuar con aplicaciones web. Para generar cierto nivel de abstracción sobre el webdriver utilizamos PageObjects.
  • JUnit: finalmente tenemos JUnit como librería de aserciones y motor de ejecución.

Continuará…

Prácticas DevOps: unificación de ambientes

Una de las primeras recomendaciones que suelo hacer a quienes me contratan para ayudarlos con cuestiones de Continuous Delivery/Automazación de ambientes es la unificación/normalización de infraestructura. Lamentablemente suelo encontrarme con proyectos donde cada servidor/ambiente es una historia distinta: el servidor de producción corre una versión de sistema operativo distinta a la del servidor del producción, tomcat y apache instalados de distinta forma en distintas ubicaciones en cada uno de los ambientes. Situaciones de este tipo tienen dos problemas:

1. Existe cierto riesgo de que algo probado en testing luego no se comporte de la misma forma en producción debido a que los ambientes son distintos (y no me refiero a cuestiones de escala)

2. No es posible utilizar los mismo scripts de deployment/administración/monitoreo ya que muchas veces la ubicación de las aplicaciones/utilitarios es distinta en cada ambiente.

Ante situaciones así mi propuesta suele ser unificar ambientes/servidores siguiendo la heurística:

  1. Elegir un sistema operativo (y versión particular) en los posible que cuente con soporte de largo plazo. Ejemplo Ubuntu 14.04
  2. Automatizar el provisioning de base que tendran todos los servidores: configuración de usuarios, networking, etc. (es lo que seria automatización capa 1)
  3. Para cada componente (web server, base de datos, etc, etc) determinar la forma de instalarlo y generar los scripts correspondientes. (es lo que seria automatización capa 2)

De esta forma, cuando uno pretende avanzar sobre la automatización de despliegues, todo resulta mucho más simple ya que está claro el sistema operativo de base y la forma en que fue instalado cada componente. Al mismo tiempo, si todos los servers/ambientes se generan con los scripts de los pasos (2 y 3) entonces es muy factible poder reutilizar scripts de deploy entre distintos proyectos bajando de manera importante el esfuerzo de automatización.

Preparando Análisis y Diseño Orientado a Objetos en UNTreF

Por estos días me encuentro preparándome para dictar esta materia el primer cuatrimestre de este año. Si bien ya he dictado este materia en otras ocasiones esta vez tengo el desafío de dictarla solo, las veces anteriores la dicté en conjunto con @dfontde. En base al feedback obtenido de las dictadas anteriores y de algunas ideas que probando en otras materias, he decido hacer algunos ajustes a la dinámica de dictado de la materia.

El avance de internet, las redes sociales y la sobrecarga de información requieren que la dinámica de las materias se adapte, por ello más allá de la clase presencial semanal tendremos un modelo de aula extendida basado en un plataforma web. En base a esto se espera que los alumnos tengan una interacción constante con todo el grupo de estudio. Por cada hora de clase presencial se espera una dedicación de al menos una hora de trabajo fuera del aula. Dicho esto y pasando en limpio: los alumnos que cursen la materia deberán dedicar al menos 8 horas semanales todas las semanas. Dependiendo de cuanta maña pueda darse cada alumno, puede que la materia le insuma unas 6 horas semanales o puede que le insuma unas 10. El punto clave aquí es que a diferencia de otras materias no es posible llevar esta materia “haciendo la plancha” y estudiando a 30 horas seguidas los días previos a la evaluación. Se quiere una dedicación constante.

Respecto del mecanismo de evaluación no me gusta tomar examen escrito (aunque no lo descarto) y por ello estoy diseñando un mecanismo de evaluación basado en tareas semanales. La mayoría de estas tareas será de índole individual. Las tareas consistirán principalmente en lecturas con cuestionarios asociados y resolución de problemas de modelado y programación.