Radiografía de un equipo trabajando a lo Extreme Programming

Hay muchas descripciones teóricas en libros, artículos y conferencias sobre cómo trabajar con la metodología Extreme Programming, pero muy pocos dando detalles. En este sentido un recurso excelente es el libro de Henrik Kniberg, Scrum and XP from Trenches. Al margen de ello, quiero compartir aquí algunos detalles de implementación de la forma en la que trabaja el equipo del cual soy parte actualmente.

Equipo (la gente está en todas las dailies):

  • 5 Devs (skills de front, back, ci/cd, infra)
  • 1 Tester
  • 1 UX
  • 1 facilitador
  • 2 personas de negocio

Proceso:

  • Duración de iteración: 2 semanas calendario, time-boxed
  • Daily Stand-up: todos los días 9.15
  • Revisión de iteración & Demo: Jueves de 10:00 a 10:30 (cada 2 semanas)
  • Retrospectiva: Jueves de 10:30 a 11:30 (cada 2 semanas)
  • Planificación estratégica: Jueves de 11:45 a 13:00 (cada 2 semanas)
  • Planificación táctica: Jueves de 14:00 a 16:00 (cada 2 semanas)
  • Refinamiento: por el no tiene un horario ni cadencia fija, viene variando de iteración en iteración
  • Invision (el nombre aún no me cierra): martes de 11:00 a 12:00 tenemos esta reunión semanal donde coordinamos con otro equipo que desarrolla una API con la cual tenemos un importante dependencia

Prácticas de desarrollo:

  • Trunk-based Development, todo el equipo, todo el tiempo trabajando en la misma rama
  • Pair-Programming, todo el tiempo
  • TDD todo el tiempo en el código server-side (C#)
  • Test-Last en el código de client-side (angular)
  • Despliegue automatizado a todos los ambiente
  • Feature Toggling

Stack tecnológico:

  • Net Core 3.1
  • Angular 9
  • Gitlab (versionado de fuentes & pipeline)
  • Artifactory (versionado de binarios)
  • RunDeck (deploy automation)
  • Specflow, NUnit, Postman/Newman y Jess (test automation)
  • Sonar (quality check)
  • Docker, Docker Compose & Kubernetes (packaging & runtime)
  • Visual Studio Code, Visual Studio, WebStorm & Rider (IDEs para todos los gustos pues tenemos gustos muy distintos)

Herramientas de gestión / colaboración

  • Microsoft Teams (chat & calls)
  • Miro & Zeplin (diseño & mockups)
  • Jira (backlog)
  • Confluence (wiki)

Algunas de estas cuestiones de esta forma de trabajo no me terminan de convencer (por ejemplo yo preferiría hacer iteraciones de 1 semana) pero por el momento nos viene funcionando bien, el negocio está contento y ningún miembro del equipo ha planteado desconformidades relevantes.

Charla: Trunk-based Development, principios y recomendaciones desde la trinchera

Me invitaron a dar una charla en un conferencia y elegí este tema principalmente por dos cuestiones. Por un lado tengo la sensación que es una práctica muy sana pero al mismo tiempo bastante rechazada, por otro lado es la charla que a mi me hubiera gustado escuchar hace 10 años .

Título: Trunk-based Development: principios y recomendaciones desde la trinchera

Resumen: Trunk-Based Development es una práctica central para implementar CI/CD, pero curiosamente muchos la perciben como una práctica muy difícil o poco aplicable. En esta sesión repasaremos los fundamentos de esta práctica, los prerrequisitos para poder aplicarla efectivamente sin morir en el intento y una serie de recomendaciones para sacarle el mayor provecho. Hablaremos también de las prácticas relacionadas como Pair-Programming, Feature Toggling y Branch by Abstraction. Durante la sesión alternaremos espacios para consultas, debate y “el testimonio algunos creyentes”

Audiencia: es una charla para gente que ya tiene experiencia en desarrollo de software profesional independientemente del modelo de branching y la herramienta de versionado que utilicen. Definitivamente no es una charla para principiantes en desarrollo de software.
Formato: exposición dialogada
Duración: 60 minutos
Palabras clave: ci/cd, control-de-versiones, (no) branching,

En cuanto esté definido día y hora de la charla, lo anunciaré por este medio y en las redes.

Reflexiones de un cuatrimestre online

La cuarentena obligó a las instituciones educativas que operaban en una modalidad presencial a pasar a una modalidad no presencial. Esto tuvo impacto obviamente en las clases pero también en otras cuestiones operativas de las instituciones. Pero dado mi rol docente solo voy a referirme a cómo afecto este cambio a la materia que yo dicto.

El cambio nos impacto, pero a diferencia de otros casos, nosotros consideramos que el impacto fue positivo. En primer lugar dado que ya veníamos dictando la materia con un enfoque de aula invertida, ya teníamos mucho material de estudio generado (lecturas y videos). Por otro ya veníamos trabajando en un esquema de evaluación continua basada en tareas semanales y evitando así la necesidad de tomar examen (los exámenes fueron un todo una complicación para muchas docentes). Al mismo tiempo parte de nuestra materia tiene una fuerte carga de programación y es justamente ahí donde la situación nos generó un impacto positivo: todos los alumnos estaban en su casa, con su computadora, pudiendo así programar en clase. Sin embargo, este cuatrimestre no hicimos mucho uso de esta posibilidad, pero es algo que definitivamente aprovecharemos mucho más de aquí en más.

Un tema central que no logramos resolver es el uso de la cámara: nuestro deseo como docentes es que los alumnos enciendan la cámara durante la clase, sobre todo cuando hacemos actividades interactivas. Creemos que esto ayuda a “achicar la distancia” y a generar otro tipo de vínculo. Pero lamentablemente, no lo logramos. O sea, algunos alumnos (menos de un tercio), usaban la cámara, pero el resto no. En algunos casos esto se debe a conexiones poco estables en las que el uso de la cámara genera aún más inestabilidad. En otros casos, hay gente utilizando computadoras de escritorio que directamente no tiene cámara. Y obviamente también hay cuestiones de gusto, en fin. El tema es sensible, porque por un lado están las cuestiones técnicas pero por otro están las cuestiones de privacidad, de alguna forma cuando uno enciende la cámara está “dejando entrar a la audiencia a su casa”. Hemos sabido de algunas materias que imponen el uso de la cámara como una precondición para cursar la materia. A nosotros por el momento no nos parece un opción válida, pero sin duda es algo que revisaremos en caso de continuar con esta modalidad.

No tenemos ni idea de cuánto tiempo persistirá la pandemia y las condiciones de aislamiento/distanciamiento, pero hay una cuestión que tenemos muy clara: cuando vuelvan las clases presenciales, nosotros no volveremos completamente a la presencialidad. Creemos que para muchas de nuestras clases resulta más beneficioso que los alumnos puedan estar conectados trabajando con sus computadoras. Por esto es que, aún cuando vuelva la presencialidad, nosotros mantendremos un porcentaje de clases online.

Comparto a continuación algunas sugerencias que nos funcionaron bien:

  • Si la clase es con dinámica de clase magistral (docente hablando sin pasando diapositivas y poca intervención de los alumnos), considerar hacer un video y que los alumnos lo vean fuera del horario de clase.
  • Hacer un intervalo si la clase dura más de 90 minutos
  • Para las clases en las que se hagan ejercicios de programación, usar Visual Studio Code con Live Share.
  • Utilizar herramientas como Miro, Mentimeter y Kahoot para hacer más interactivas las clases
  • Considerar grabar las clases pero disponibilizarlas solo a pedido en caso que algún alumno tenga dificultades de conexión

Cierre de un cuatrimestre atípico en MeMo2@fiuba

Cerramos el cuatrimestre de MeMo2@fiuba en una modalidad 100% online y en términos resumidos creemos que estuvo muy bien.

Como herramientas de soporte utilizamos Jitsi para las clases online, Canvas LMS como aula virtual y GitLab como plataforma de desarrollo. En términos descriptivos este cuatrimestre tuvimos:

  • 22 inscriptos, 1 abandono, 21 aprobados
  • 46 tareas individuales que incluyeron 7 ejercicios de programación y 12 cuestionarios con sus correspondientes lecturas y videos
  • 2 trabajos grupales, uno de alcance variable y esfuerzo fijo y otro de alcance fijo y esfuerzo variable
  • 2 visitas de profesionales: Pablo Najt y Matias Gorostegui, gracias a ambos

Más allá de los números hay dos cuestiones interesantes que los alumnos destacaron. Por un lado la predisposición de los docentes para mejorar clase a clase lo cual quedó evidenciado en el hecho de que al final de cada clase les pedimos a los alumnos completar una breve encuesta para tener feedback específico de la clase. Por otro lado la buena adaptación de la materia a la modalidad online, de hecho algunos alumnos nos destacaron como la materia que mejor se adaptó. Siendo sinceros, creemos que no hicimos demasiados cambios para la modalidad online básicamente porque ya teníamos la materia planteada en un modalidad híbrida e invertida, basada fuertemente en el uso del aula virtual y mucho material en video.

De acuerdo a nuestra encuesta interna del curso tuvimos casi los mismos números que el cuatrimestre anterior:

  • Evaluación general del curso: 8.5 / 10
  • Claridad de los docentes: 4.3 / 5
  • Conocimiento de los docentes: 4.8 / 5
  • Dinámica de clases: 4.3 / 5
  • Materiales de estudio: 4.2 / 5
  • Dedicación promedio extra clase: 8.5 hs. semanales
  • Conformidad con la nota de aprobación: 4.4 / 5
  • Nota promedio de aprobación de la materia: 7.8

Por otro, en términos de feedback más general surgido de las encuestas y de la actividad de cierre, nos encontramos con algunos temas recurrentes (como usar python en lugar ruby y tener más cuidado al dar feedback de los ejercicios) y algunos otros temas nuevos (como agregar material sobre object-relation mapping y ver las cuestiones de configuration management antes del TP1).

Finalmente, puertas adentro del equipo docente creo que el trabajo fluyó que en cuatrimestre anteriores y en parte me parece que se debe a implementamos una reunión de de sincronización semanal (la weekly).

Shu-Ha-Ri, grado y posgrado

Escribo este post a partir de varias consultas que he recibido en relación al experimento de la materia Ingeniería de Software y el Seminario de Posgrado en Software Delivery.

Primero un poco de contexto. Como docente de UNTreF, todos los segundos cuatrimestre de cada año dicto junto a Diego Marcet la materia Ingeniería de Software perteneciente a la carrera de grado de Ingeniería de Computación. Por otro lado, el primer cuatrimestre dicto el Seminario de Postgrado en Software Delivery.

La materia Ingeniería de Software está pensada para alumnos del último año de la carrera que tienen poca o nula experiencia laboral. Cubrimos los temas clásicos de ingeniería de software, pero en su mayoría lo hacemos desde una perspectiva de Extreme Programming, en contraposición a la visión tradicional. En este sentido los libros de referencia en nuestra materia son los de Beck, Shore y Freeman en lugar de los clásicos de Pressman y Sommerville. Al mismo tiempo el foco de la materia está en el trabajo de un equipo. También utilizamos bastante el libro que escribimos con Fontela, Fontdevila y otros colegas hace un par de años.

Por otro lado el seminario de Software Delivery está pensado para gente que ya curso una materia de ingeniería de software y que ya tiene al menos algunos años de experiencia laboral. Tratamos temas más avanzados que incluyen cuestiones organizacionales que implican trabajo con varios equipos. Aquí la bibliografía de referencia es el libro Accelerate y luego para cada uno de los temas que menciona este libro tenemos material complementario.

Desde la perspectiva del modelo de aprendizaje Shu-Ha-Ri, la materia de grado es claramente nivel Shu, enseñamos una forma de hacer las cosas. Me gusta explicar esto con la película Karate Kid: pulir y encerar, pulir y encerar. “Estimados alumnos, tiene que resolver esto y tiene que hacerlo con este proceso”. Buscamos que los alumnos logren un pleno dominio de una técnica, de una forma de desarrollo software. Por su parte el seminario de postgrado es más nivel Ha, vemos varias formas de aproximar un problema y reflexionamos al respecto. Los participantes ya vienen con nivel Ha y buscamos que los participantes puedan dar el salto de Ha a Ri.

No estoy seguro si esta relación Shu => grado, Ha-Ri => postgrado, pero claramente aplica en este caso particular.

Cierre del Seminario de Software Delivery, primera edición

Recientemente completamos la primera edición del Seminario de Postgrado en Software Delivery que organizamos en UNTreF.

El seminario constó de 6 encuentros (virtuales, obviamente) de 2 horas cada uno. Participaron del seminario unos 14 profesionales pero menos de la mitad completaron el trabajo final. A algunos directamente no les interesó hacerlo, algunos otros lo intentaron pero por una u otra razón lo llegaron a completarlo. Sin embargo creemos que los trabajos completados fueron muy buenos.

Inicialmente, en una época pre-pandemia, el curso estaba planteado en una modalidad mixta de encuentros presenciales y virtuales, con lo cual el cambio a modalidad 100% virtual no fue tan difícil.

Como herramientas de soporte para el dictado de curso utilizamos Jitsi para los encuentros virtuales y Canvas como campus virtual. Esta última herramienta yo ya la venía utilizando para el dictado de mis materias de grado con muy buen resultado.

Todo el contenido del seminario estuvo regido por las temática descriptas en el libro Accelerate de Forsgren, Humble y Kim.

Una de las cuestiones que varios de los participantes destacaron como muy positiva fue la frecuencia de los encuentros. Dado que el curso tenía una carga importante de trabajo fuera de las clases, decidimos espaciar los 6 encuentros a los largo de 14 semanas se la siguiente forma:

  • Semana 1
  • Semana 5
  • Semana 6
  • Semana 10
  • Semana 11
  • Semana 14

Viendolo en retrospectiva creo que fue una buena decisión aunque para una próxima edición posiblemente ajustemos la distancia entre los encuentros.

Quedamos muy conformes con el seminario y ya tenemos decidido repetirlo, en principio el primer cuatrimestre del 2021. Aquellos interesado en particular en futuras ediciones puede contactarme por este medio.

Experimento: universidad para todos y todas

Resumen: ¿te interesaría cursar la materia Ingeniería de Software de UNTreF que dictamos con @diemarcet aún sin ser alumno de UNTreF? Entonces completá este formulario indicando porque te intersaría cursar la materia.


La historia completa

La dinámica de cursada con la que está armada la materia implica que en los alumnos trabajen equipo para hacer un desarrollo porque el trabajo en equipo es uno de los temas de la materia. Creemos que lo optimo es que sean equipos de 3 alumnos. Obviamente la cantidad de alumnos que se anotan en la materia no siempre es múltiplo de 3. De hecho, en base a la información que tenemos, este segundo cuatrimestre de 2020 no lo será.

Entonces se nos ocurrió que dado que la materia se dictará en forma completamente online podríamos aceptar como alumnos a gente externa a la carrera o incluso externa a la universidad. Algunos puntos importantes a considerar para aquellos que estén interesados:

  • La materia se dictará los miércoles de 18 a 22 en forma online
  • Adicionalmente al tiempo de clase, la materia requiere una dedicación de unas 6 horas semanales para estudiar y hacer tareas
  • Respecto de los temas, vemos los temas del SWEBook con un enfoque adaptativo y muy “hands-ons”. En términos concretos podríamos decir que estudiamos y practicamos lo que podría denominarse como “Extreme Programming Moderno”
  • Aquí, aquí y aquí comparto algunos links para que tengan una mejor idea de la materia

De Subversion a Git, el problema no es la herramienta

Luego de varios años volví a encontrarme en un cliente con Subversion y la decisión de migrar a Git.

La principal dificultad que he encontrado en este tipo de migraciones viene dado por un uso incorrecto de Subversion. Este uso incorrecto creo que es consecuencia de varias cuestiones:

  1. Desconocimiento de prácticas básicas de configuración management
  2. La flexibilidad (o permisividad) de Subversion en lo referente a la estructura de directorios
  3. La “tentación” de usar el Subversion como si fuera simplemente un file-system compartido

Es a partir de estas cuestiones que es factible encontrarse con repositorios Subversion sin una linea base y/o con una cantidad de sin sentido de branches. A esto se suma el hecho de utilizar un único repositorio Subversion para todos los proyectos de la organización.

Como suele ocurrir, el problema no radica en la herramienta sino en la forma en la que utilizamos. Un martillo no parece ser una herramienta apropiada cuando lo queremos utilizar para revolver el té.

Por otro lado Git ya tiene incluido en su diseño algunas cuestiones que “obligan” a tener ciertas prácticas básicas de configuration management o que al menos limitan ciertas barbaridades que el usuario pueda tentarse de hacer.

En mi experiencia cuando se utiliza Subversion de acuerdo a las recomendaciones del SvnBook la migración a Git resulta bastante simple. Al mismo tiempo, si bien existen herramientas para migrar de Subversion a Git la estrategia que más he utilizado es “congelar el Subversion”, mantenerlo como almacenamiento de versiones históricas y arrancar con un repositorio Git con tan solo la versión de la línea base.

Finalmente un detalle importante al empezar con Git es hacer el esfuerzo de entender mínimamente como funciona. Si lo usamos integrado con un IDE, corremos el riesgo de utilizar Git como si fuera Subversion y comprarnos así varios problemas o simplemente desperdiciar ciertas capacidades de Git. Luego de trabajar en varios proyecto de migración, en 2015 grabé una serie de videos sobre Git para explicar algunos principios básicos de su funcionamiento, los pueden encontrar aquí.

Implementando Feature Toggles en C# con Microsoft.FeatureManagement

Se conoce como Feature Toggles (o feature flags) a la capacidad/funcionalidad de disponibilizar (prender/apagar) una funcionalidad en base a un determinado criterio. En mi proyecto veníamos usando esta técnica casi desde que empezamos y en particular la usamos para habilitar funcionalidades gradualmente a distintos grupos de usuarios. De entrada hicimos nuestra propia implementación de feature toggles, la cual ofrecía ciertas capacidades acotadas pero que para nuestro escenario resultaban suficientes.

Nuestro Product Owner se entusiamó con esta capacidad de “togglear” funcionalidades y entonces decidimos analizar una solución de toggles más robusta y flexible. Es así que comenzamos a analizar las opciones listadas en el sitio FeatureFlags.io. Por otro lado nos encontramos con el componente Microsoft.FeatureManagement. A simple vista este componente nos resultó el más atractivo de los que habíamos visto y por ello decidimos probarlo.

El resultado fue contundente, nos llevó aproximadamente 1 hora reemplazar nuestro componente casero por el componente de Microsoft y lo que pensábamos que sería una prueba de concepto terminó completamente integrado en nuestra aplicación.

En forma resumida el uso de este componente requiere de los siguientes pasos.

1. Agregar el paquete

Agregar la referencia al paquete Microsoft.FeatureManagement.AspNetCore

2. Agregar la configuración

La configuración se puede poner en un archivo json o directamente se puede incluir en el archivo de configuración de la aplicación (appsettings.json).

"FeatureManagement": {
   "funcionalidad1":true,
   "funcionalidad2": false,
   "funcionalidad3": {
      "EnabledFor": [
         {
            "Name": "Targeting",
            "Parameters": {
            "Audience": {
              "Users": [
                "juan",
                "maria"
               ]
            }
          }
        }
  }

Este fragmento de configuración indica que la “funcionalidad1” está encendida, que la funcionalidad2 está apagada y que la funcionalidad3 está encendida solo para los usuarios juan y maria.

3. Agregar los toggle points

Los toggle points son los lugares en nuestro código donde se consultan los toggles para verificar si una funcionalidad está activa o no. Esto es: en el punto de entrada a la funcionalidad1 tengo que ver si la misma está disponible o no. Para esto utilizamos la clase featureManager

if(featureManager.IsEnabledAsync("funcionalidad1"))
{
   ....
}

Dependiendo de cómo esté definido el toogle puede que tengamos que adicionalmente darle al FeatureManager información contextual para que pueda consultarse la funcionalidad.
El componente de Microsoft ofrece también featureGates que pueden ser utilizados en los controllers/actions de una aplicación web y así evitar la ejecución en caso que la funcionalidad indicada no esté habilitada.

[FeatureGate("funcionalidad1)]
public class MyController : Controller
{
    …
}

Este componente ofrece out-the-box la capacidad para definir evaluación de toggles dependindo de rangos horarios, usuarios y grupos de usuarios. En caso que esto no sea suficiente también es posible crear extensiones para definir criterios propios de evaluación.

Generación de reportes de cobertura con ReportGenerator

Hace un tiempo escribí sobre medición de cobertura en Net Core utilizando Coverlet. Como indiqué en ese artículo Coverlet tiene la capacidad de medir la cobertura y generar reportes al respecto en distintos formatos. Pero hay una limitación: cuando nuestra cobertura no es del 100% querremos saber puntualmente que métodos/líneas no están cubiertos y si bien Coverlet genera reportes con esta información, los mismos no son en formatos “amistoso para humanos” sino que son en formatos particulares para ser procesados por otras herramientas. Es aquí donde entra en juego ReportGenerator.

ReportGenerator es una herramienta que a partir de un reporte de cobertura en formato “no amistoso para humano” (opencover, cobertura, jacoco, etc) genera reportes en formatos “amistoso para humanos” (csv, html, etc). Esta herramienta está construida en .Net y puede instalarse de varias formas diferentes dependiendo de la plataforma en la que uno pretenda utilizarla. Más aún, la propia herramienta provee una página donde a partir de completar un conjunto de opciones se generan las instrucción de instalación y ejecución correspondientes.

Ahora bien, para poder generar un reporte con ReportGenerator a partir de una medición de cobertura generada con Coverlet hay que indicarle a Coverlet que genere el resultado en un formato que sea compatible con ReportGenerator, por ejemplo formato OpenCover. A continuación comparto un ejemplo.

dotnet test Domain.Tests/Domain.Tests.csproj /p:CollectCoverage=true /p:CoverletOutput=../coverage.info /p:CoverletOutputFormat=opencover

reportgenerator -reports:coverage.info -targetdir:"coverage"