Consideraciones para habilitar el homeworking

El homeworking es una de las prácticas que a mi parecer está ganando gran popularidad en los ambientes informáticos. En particular en Buenos Aires existe hoy en día una gran demanda de profesionales informáticos y varias empresas “ofrecen como beneficio” la posibilidad de hacer homeworking 1 o 2 días por semana. Personalmente me gusta mucho el homeworking, yo soy bastante organizado y realmente logro ser muy productivo trabajando desde casa, sumado al hecho que me ahorro tiempo de viaje y caos de tránsito. Pero al mismo tiempo creo que es un cuestión que no debe tomase a la ligera.

Para empezar considero que el homeworking no es para todos. Ni para todos los proyectos, ni para todas las personas, ni para todas las organizaciones.

Hay proyectos en los que se requiere que la gente esté físicamente junta, tal vez no todo el tiempo, pero si en determinados momentos/temporadas (típicamente al comienzo del proyecto).

Al mismo tiempo, si una organización pretende habilitar el trabajo homeworking debe proveer cierta infraestructura para hacerlo posible, me refiero a cuestiones como algún sistema para conferencias online (skype, hangout, etc), acceso remoto a los servicios/servidores de la organización (ambiente de test, servidor de integración, sistema de tickets, etc, etc).

Finalmente respecto de las personas, es necesario saber organizarse y tener cierto nivel de autonomía en el trabajo. Este último punto no es trivial, pues la autonomía requiere ciertos conocimientos, tanto del contexto/organización como también de las tecnologías a utilizar.

Por otro lado hay un “anti-patrón” que he visto en varias ocasiones: tomar el homeworking como “obligación”: “yo los miércoles trabajo desde casa” cuando en realidad me parece que debería ser algo más del estilo “yo los miércoles intento trabajar desde casa, pero si el proyecto/contexto lo requiere vemos como manejarlo (obviamente procurando no perder el beneficio ;-) )“.

Chat no mata mail

En el último año he visto muchos equipo comenzar a utilizar herramientas de chat comunitario. Slack, Campfire, HipChat y Gitter son algunas con las que tuve la oportunidad de trabajar. Algunos equipos suelen utilizar este tipo de herramientas como medio de reemplazo del mail, integrando con las mismas todas la notificaciones y reemplazando así aquellas notificaciones que tradicionalmente se recibían por  mail.

Si bien me parece que estas herramientas pueden resultar útiles para determinadas situaciones creo que de ninguna manera reemplazan al mail. En mis proyecto me gusta siempre contar con lista de correo independientemente que se cuente o no con una herramienta de chat comunitario.

Personalmente me resulta mucho más cómodo el uso del mail para mantener discusiones asíncronas las cuales a mi parecer no resulta cómodo manejarlas vía chat. El chat me parece genial para mantener discusiones en vivo cuando uno requiere interacción inmediata pero no para estos casos de respuestas no urgentes y tardías. Al mismo tiempo tengo la sensación que entrar a un chat y ponerse a revisar mensaje viejos es extremadamente incómodo.

Voy a ejemplificar con algunos casos para los que considero que una lista de mail resulta mucho más apropiada que el chat.

  • Discusiones de refactoring: estoy codeando y veo a la pasada algo que no me cierra y que me parece merecería un refactor pero que no es trivial de realizar. Entonces planteo la discusión por mail pues no es algo urgente. De esa forma cada uno puede responderlo cuando lo considere apropiado y una vez lograda una decisión vemos de agendarlo para trabajar en una iteración futura (posiblemente con una charla presencial de por medio)
  • Diseño de producto: similar al caso anterior pero desde la perspetiva de producto, se me ocurre que se podría agregar/modificar una funcionalidad, entonces inicio una discusión por mail con el Product Owner y el equipo para ir hablando el tema antes de llegar a la próxima planning.
  • Intercambio de información con miembros externos al equipo: tengo que avisar a mi comunidad de usuarios que se realizará una tarea de mantenimiento de la aplicación, entonces mando un mail con este aviso y pongo en copia oculta la lista de correo del equipo desarrollo. De esta forma el equipo tiene presente la tarea de mantenimiento y está al tanto que los usuario ya fueron notificados.

En forma resumida mi opinión es: Chat no mata mail.

Iniciativa de Software Craftsmanship en Buenos Aires

El movimiento de Software Craftsmanship (SC) surgió hace un par de años y al igual que ocurre con el movimiento ágil cuesta poner una fecha “de fundación”. Si bien el manifiesto de Software Craftsmanship data de 2009, algunas publicaciones al respecto son bastante anteriores: Software Craftsmanship: The new Imperative (2001) y The Pragmatic Programmer (1999).

El movimiento de SC ha tenido un gran crecimiento en los últimos años y varias conferencias han potenciado su difusión. Entre estas conferencias destaca sin duda SoCraTes (Software Craftsmanship and Testing Conference) la cual desde 2010 se ha replicado en distintos países (Alemania, UK, Bélgica, Francia, España)

En paralelo con el crecimiento de este movimiento han surgido también algunas críticas/debates que han sido muy resumidos por Martin Fowler en su artículo Craftsmanship and the Crevasse.

Hasta donde tengo conocimiento no existe hoy por hoy en Buenos Aires un espacio comunitario que trate sobre este movimiento. Al mismo tiempo dada la cercanía de este tema con agile, creo que podría ser interesante reflotar los encuentros mensuales de Agiles@BuenosAires para hacer algunas actividades de Software Craftsmanship. Manos a la obra.

Continuará…

 

Las dos cuestiones más desafiantes del desarrollo de software

Desarrollamos software para aportar valor a un negocio/organización. En ese sentido el desarrollo de software tiene dos cuestiones centrales que son la fuente de sus mayores complejidades: determinar lo que hay que construir y manejar de forma eficiente las necesidades de cambio. Si bien yo he enumerado estos dos temas como cuestiones disjuntas la realidad es que tienen una íntima relación. Determinar lo que hay que construir debe gran parte de su complejidad al hecho de que una vez determinado lo que se debe construir, lo mismo suele cambiar. De todas todas vayamos por parte.

Determinar lo que hay que construir

Este es un tema que se ha tratado bastante, a punto tal que se ha generado un disciplina alrededor del tema: Ingeniería de requerimientos. Hoy por hoy, luego de haber leido, reflexionado y experimentado creo que el tema puede simplificarse a dos escenarios:

1) requerimientos conocidos y estables
2) requerimientos no-conocidos y/o no estables

Nunca en 15 años de trabajo en la industria me encontré con el caso (1), pero curiosamente creo que gran parte de la bibliografía, técnicas y conocimientos de la ingeniería de requerimientos está enfocada en este tipo de escenarios. Se me ocurre que en estos escenarios puede ameritarse hacer un trabajo intenso sobre los requerimientos antes de comenzar con el desarrollo (digo esto sin estar muy convencido).

Todos mis proyectos se enmarcan en escenarios del tipo (2), en algunos casos me ha tocado desarrollar software sin tener requerimientos conocidos, simplemente teniendo una visión y un objetivo de negocio y debiendo “experimentar sobre los requerimientos”. En la gran mayoría de los proyectos en los que he participado me he encontrado con un conjunto de requerimientos cambiantes a satisfacer y ha sido precisamente esa propiedad “cambiante” la fuente de las principales fricciones del proyecto.
Para estos escenarios del tipo 2, no considero que sea útil, ni conveniente realizar un trabajo intenso sobre los requerimientos antes de comenzar el desarrollo. Al contrario, creo que la cuestión pasa por “probar” de una forma sistemática siguiendo 4 premisas:

  • Trabajo iterativo
  • Involucramiento del usuario
  • Entrega frecuente
  • Feedback continuo

Manejar de forma eficiente las necesidades de cambio

A mi parecer este solo punto justifica la gran mayoría de las prácticas técnicas de la ingeniería de software (arquitectura, diseño OO, automatización, integración continua, etc). Si uno tuviera la certeza de poder escribir una pieza de código y nunca más modificarla podría no preocuparse por escribir código claro, mantenible y testeable. Curiosamente creo que en la formación académica se hace foco en la enseñanza de las prácticas técnicas pero sin hacer suficiente foco en el por qué de su importancia. Al construir software buscamos cumplir ciertas propiedades para facilitar la evolución/cambios que el software deberá soportar. El no cumplir con dichas propiedades suele generar diversos tipos de perjuicios para el negocio.

Obviamente más allá de estas dos cuestiones hay otras miles que también son relevantes (trabajo en equipo, planificación, etc), pero a mi parecer estas dos son las que están en los primeros puestos de complejidad.

Reflexiones sobre la Enseñanza de la Ingeniería de software

En mi actividad profesional cotidiana me desempeño como ingeniero de software ocupando distintos roles y realizando distintas tareas dependiendo de las particularidades del proyecto de turno. Por ello cuando en 2011 tomé a mi cargo la materia Elementos de Ingeniería de Software en la Universidad Nacional de Quilmes busqué una dinámica de dictado de la materia que efectivamente pudiera preparar a los alumnos para desempeñarse profesionalmente en esta disciplina.

Personalmente considero que la ingeniería de software es una actividad naturalmente industrial, y en este sentido me parece fundamental que su enseñanza tenga un enfoque práctico puesto que la ingeniería de software teórica resulta insuficiente para el ejercicio profesional de la disciplina.

Curiosamente mi formación  en Fiuba no tuvo este enfoque. Como alumno tuve un conjunto de materias de índole más bien teórica y  tiempo después otras materias de tipo taller donde se suponía ponía en práctica la teoría aprendida tiempo atrás. Esto me parece perjudicial para el alumno, pues a la hora de estudiar la teoría, la misma se aprende “en el aire” sin ponerla en práctica. Luego, tiempo más tarde se cursa un taller, pero al llegar al taller uno ya se olvidó de la teoría “supuestamente aprendida”. Exactamente esto me pasó con el tema de estimación: en una materia me enseñaron los diversos métodos de estimación pero nunca me pidieron estimar, simplemente me pidieron describirlos en un examen escrito. Tiempo después cuando cursé el taller y tuve que estimar, tuve que volver a estudiar los métodos y fue ahí, a la hora de aplicarlos, que me surgieron mil dudas. Algo similar me ocurrió con las cuestiones de testing y calidad.

Otra curiosidad de mi carrera (y que también se repite en otras casas de estudio) es que cursé en primera instancia una materia de análisis y luego una de diseño, como si fueran dos actividades disjuntas (un punto sin duda debatible). Hasta ese momento carecía de una visión general del proceso de desarrollo de software, cosa que aprendí tiempo más tarde en la materia de gestión. Creo que resulta muy dificil (y poco conveniente) enseñar técnicas de análisis y diseño sin contar con el marco general de un proceso de desarrollo. En este sentido me parece interesante el enfoque de la Universidad Nacional de Quilmes, donde primero se ofrece una materia introductoria a la Ingeniería de Software que brinda al alumno una visión general de la disciplina, con un enfoque muy práctico y luego en siguientes cuatrimestres se ofrecen materias específicas para cada actividad: Ingeniería de requerimientos, Gestión de proyectos, Arquitectura de software, etc, etc.

Respecto del enfoque práctico, en concreto creo que es necesario hacer el ejercicio de construir/extender un pieza de software de cara a poner en práctica toda la teoría y técnicas enseñadas, tengo la sensación que enseñar ingeniería de software a partir de lecturas, cuestionarios y ejercicios conceptuales es insuficiente para formar profesionales de la informática y como dije antes el hacer estas actividades en materias separadas no me parece apropiado.

Creo que algunas de estas cuestiones han sido consideradas en el nuevo plan de la Licenciatura en Sistemas de la FIUBA (aunque no estoy seguro de hasta que punto). Espero también que estas cuestiones sean consideradas en el próximo plan de estudios de la carrera de Ingeniería Informática de FIUBA.

 

 

 

Ansible vs Puppet: mi opinión

Hace unos días escribí sobre el camino que recorrí con las herramientas de automatización de infraestructura y mencioné que luego de haber usado Puppet y Ansible, he decidido quedarme con este último. Esta decisión se debe principalmente a las cuestiones:

  • El DSL de Ansible me resultó mucho más amistoso que el de Puppet
  • Para trabajar en modo “standalone” Ansible incluye en su core un conjunto de utilidades/tareas que a mi me resultan muy útiles y que no están en el core de Puppet (a menos que uno instale módulos adicionales).
  • El modo de funcionamiento “push” de Ansible me gusta más que el modo pull de Puppet.

Resalté algunas partes de la frases anteriores para dejar bien en claro el nivel de subjetividad de las mismas.

Reflexiones sobre la automatización de pruebas

La semana pasada dicté junto a @dfontde un taller de automatización de pruebas. Entre la audiencia tuvimos principalmente desarrolladores.

Obviamente uno de los temas que tratamos fue la automatización de pruebas a nivel de Interface Gráfica de Usuario (GUI). De hecho cada vez que dicto este taller la gente suele venir con la expectativa de encontrar la bala de plata para poder automatizar pruebas exclusivamente a nivel GUI. Mi posición al respecto es siempre la misma: ¿en verdad que quieres automatizar pruebas a ese nivel?.  A lo largo del taller trabajamos fuertemente sobre la cuestión de a qué nivel automatizar las pruebas y muchos suelen convencerse que puede resultarles más conveniente trabajar la automatización a nivel del API/Servicios.

Las pruebas a nivel GUI suelen ser frágiles (cambios mínimos en la GUI pueden romper las pruebas) y costosas de ejecutar (ya que requieren instanciar la aplicación completa). Pero al mismo tiempo pueden ser la única opción de automatización, ya que prueban la aplicación en modo caja negra, no importa como esté construida la aplicación pues simplemente se interactúa con ella desde afuera. Este es un punto muy relevante para el caso de aplicaciones legacy, que muchas veces han sido construidas sin características de testeabilidad. Más allá de estos argumentos que son clásicos y pueden encontrarse en la bibliografía hay algunas cuestiones adicionales que se han puesto de manifiesto en los últimos años.

  • Por un lado cada vez son más comunes las famosas SPAs (Single Page Application), muchas veces basadas en frameworks “client-side”como AngularJS. Esto implica una creciente cantidad de código JavaScript. Este tipo de aplicaciones no suele ser tan simple de automatizar a nivel GUI pues no todas las herramientas no se lo bancan bien. Pero al mismo tiempo aparece un nuevo nivel de automatización posible: pruebas unitarias de los componentes JavaScript.
  • Por otro lado, los frameworks de desarrollo / generadores de código “server-side” como Spring-Boot ya incluyen como parte de sus funcionalidades una propuesta para la codificación de pruebas automatizadas a nivel de API e incluso en algunos casos se encargan de generar el código de algunas de estas pruebas.

En mi opinión estas dos cuestiones refuerzan necesidad de repensar cualquier intento de automatización de pruebas a nivel GUI. Y quiero ser muy claro en cuanto a esto: no estoy diciendo que no se automaticen pruebas a nivel GUI, sino simplemente que no me parece una buena estrategia que el grueso de las pruebas automatizadas sea a nivel GUI. Creo que hay que pensar en una estrategia de automatización más integral que incluya pruebas a distintos niveles. Esto nos permitirá tener una mejor cobertura con un esfuerzo mucho menor y repartido entre los distintos perfiles del equipo (tengamos presente que el testing no es sólo responsabilidad de los testers).