Jun 22

Visita a Paradigma tecnológico

Hace ya casi un mes, me tocó una visita a Paradigma Tecnológico.

El tema es que un departamento de nuestra empresa, no el mío, tiene un proyecto en el que está como requisito el uso de algunas tecnologías modernas, entre otras, BigData. Puesto que en los departamentos de nuestros alrededores nadie tiene experiencia con estas tecnologías, se ha decidido subcontratar desarrollo y asesoría a alguien que sepa del tema, para sacar el proyecto adelante y para aprender nosotros sobre ello. La empresa elegida ha sido Paradigma Tecnológico.

Esta compañía ágil, como reza en su página web, hace nuestro proyecto con Scrum y finalizado el primer Sprint, llega el momento de hacer la "demo" al cliente, es decir, al departamento de mi empresa. Teniendo yo fama de friki, este departamento y  mi propia jefa, decidieron que yo debía acudir también a ese sprint, para enterarme lo más posible de este tipo de nuevas tecnologías y ver si son aplicables a otros proyectos. Así que allí fuí.

Lo que más me llamó la atención, en lo que se puede ver dando un paseo por las instalaciones de Paradigma, es que sí tiene toda la pinta de que usen Scrum realmente en todos los proyectos. Según se pasea, se ven tableros de Scrum y paquetes de postit de colores por todos lados. Según se podía ver y me contaba una de las personas que trabaja allí, los desarrolladores trabajan en una sala diáfana con mesas agrupadas de 6 en 6, creo recordar. Los programadores de un proyecto trabajan juntos en un grupo de mesas y en la pared al lado de su grupo de mesas tienen el tablero Scrum. Nos enseñaron también el product backlog de nuestro proyecto, un tablero enorme con miles de postit pegados con celo y nos enseañaron el gráfico "burn down" correspondiente a nuestro primer sprint.

En cuanto al Sprint que nos hicieron, era un poco extraño, posiblemente por ser el primer Sprint. Básicamente consistía en explicarnos la arquitectura decidida, una demo real sencilla viendo funcionar esa arquitectura y un "mono" de la interfaz de usuario para que nos hicieramos una idea de cómo iba a ser. Como es de rigor en un sprint, insistieron mucho en que hicieramos comentarios y diéramos nuestras opiniones, ahí creo que nos quedamos un poco "cojos", culpa nuestra.

Hay algunos detalles del Scrum que no me cuadran con lo que pensaba, por ejemplo, para el segundo Sprint se indicaron las tareas que se iban a hacer, imagino que previamente acordadas con el Product Manager que es una pesona de nuestra empresa. Lo que no me cuadra es que en ese segundo Sprint no se llegaba a una funcionalidad útil para el cliente, sino que las tareas eran pequeños (o grandes) trozos de código que evidentemente hay que hacer, pero que no constituyen en sí un producto, aunque sea muy básico, que se pueda entregar de alguna forma, salvo quizás, como un conjunto de liberías. Quizás yo soy demasiado teórico. Quizás un segundo sprint (de 3 semanas) sea también muy pronto para obtener ese primer producto básico. En cualquier caso, no le he dado demasiada importancia, ya que en mis intentos de hacer Scrum con mi grupo de trabajo, sé lo complejo que es entregar un pequeño producto en los primeros Sprint, donde hacer cualquier cosa completa que vaya desde un extremo del sistema (la interfaz de usuario) hasta el otro (el equipo hardware que se quiere controlar), pasando por todos los pasos intermedios (base de datos, lógica de negocio, …) requiere hacer mucho código de la arquitectura del sistema. Pero me deja ese mal regustillo de que quizás Scrum es demasiado teórico, excesivamente complejo, o no aplicable a cualquier proyecto …

Resumiendo, la impresión en general ha sido buena y me voy confirmando cada vez más en que hacer un Scrum que cumpla al 100% con la teoría de Scrum es muy complejo.

Mar 17

La parte olvidada de las metodologías ágiles

Cuando se habla de metodologías ágiles y quizás porque en el fondo somos programadores y no gestores, siempre se habla de cosas como la reunión diaria, las entregas frecuentes, los tableros Scrum, los test automáticos, etc, etc. Sin embargo, hay otro punto realmente importante y del que no se suele hablar, la intervención directa del cliente a lo largo de todo el proceso.

Afortunadamente, he tenido oportunidad de practicar con este último punto y ahí va la experiencia. Pongámonos primero en contexto

El proyecto es un proyecto pequeño para lo que estamos acostumbrados, un solo desarrollador, yo mismo, durante algo más de seis meses y con la suerte de poder dedicarme al 100% al proyecto (cosas de la crisis, no hay demasiado trabajo). Hay también un jefe de proyecto, pero su única gestión es básicamente el tema económico y alguna reunión o charla esporádica con los "jefes" del cliente. El proyecto es un proyecto Web, en el que sólo hay software implicado, el servidor está desde el principio en las instalaciones del cliente, con su dominio público en internet y al que tengo acceso de administración con una VPN (red privada virtual)

En este contexto, tengo contacto diario y directo, por teléfono y email, con los usuarios finales del proyecto, los que van a estar usando esa web día a día, así que pensé que es una situación ideal para metodologías ágiles. Al ser yo el único desarrollador y estar el cliente en otra ciudad a más de 400 km de distancia, todo eso de las "demos" y reuniones al estilo Scrum no me parecía adecuado, así que  opté por una opción más al estilo Kanban. Me di de alta en https://kanbanflow.com , hice un tablero con cuatro columnas : to-do, in-progress, verification y done, copié los requisitos iniciales en la columna to-do y le mostré el tablero a los clientes, así como una explicación del funcionamiento general de Kanban y metodologías ágiles, en lo que a ellos les afecta. Les pareció una idea estupenda y es lo que estamos usando.

Ellos ordenaron y matienen ordenada la columna de "to-do", además de añadir más tareas cuando les viene en gana, en el orden en que quieren que se desarrolle. Yo siempre saco la primera tarea de arriba del todo y la muevo a la columna "in-progress", teniendo como máximo 3 tareas simultáneas en desarrollo. Cuando termino de probarla en mi entorno de pruebas y la subo al servidor, la muevo a "en verficacion" y ellos, tras probarla, la mueven a "done" o la devuelven a la primera columna con más cosas que quieren o bugs que han encontrado. En fin, nada que no sepamos ya del funcionamiento de un tablero Kanban.

¿Y cuales son las consecuencias de todo esto?. Pues bien, como nada es blanco ni negro, hay cosas buenas y otras no tan buenas. Empecemos con las primeras.

Lo mejor de todo es que el cliente está encantado. No es solo que me lo digan cuando les pregunto, es también el "feedback" que me da nuestro jefe de proyecto cuando habla con ellos o lo que yo mismo oigo a los clientes hablar entre ellos cuando nos hemos reunido cara a cara.

Lo primero que les gusta, por supuesto, es que el producto, aparte de no tener grandes fallos, cumple exactamente lo que necesitan, como no puede ser de otra forma, puesto que los mismos usuarios finales lo ven evolucionar día a día y deciden sobre lo que se debe hacer y cómo. Y lo segundo que les encanta es la excelente gestión de sus peticiones (mérito de un mecanismo como Kanban), ellos tienen total control sobre lo que piden y cuándo se aborda, así como total visibilidad de lo que se está haciendo y lo que tarda en hacerse. Ninguna de sus tareas lleva un tiempo estimado de más de 3 ó 4 días, pero la mayoría son de 1 ó 2 días, por lo que ven progresos de forma continua. Si alguna tarea lleva mucho más, hablo con ellos y tratamos de partirla, creando una tarea más pequeña con lo que realmente es importante para ellos y otras con lo menos importante y que puedan poner más abajo en la lista.

Y ahora viene la parte no tan buena. Aunque se deja claro al principio que pueden añadir, modificar y ordenar tareas a su gusto, también se deja claro que el proyecto tiene una fecha de terminación y que toda modificación que hagan o tarea que añadan, no debería afectar a esa fecha, sino simplemente hacer más probable, si no seguro, que las tareas al final de la columna to-do se queden sin hacer. Esto, por supuesto es algo que no les gusta oir. Pero eso no es lo peor, porque la ventaja de controlar el desarrollo día a día les convence frente a la posibilidad de que alguna tarea poco importante para ellos se quede sin hacer y de alguna forma, lo aceptan. Lo peor es que en el día a día se "emocionan" con las tareas que se van realizando y tienden a no acabarse nunca. Cuando terminas una tarea y ellos la prueban, se les ocurren mejoras que inmediamente hacen que la tarea vuelva a la columna "to-do", con añadidos para hacer y, normalmente, al principio para que se aborde inmediatamente. Hay que estar continuamente pidiéndoles verificación, como sutil indirecta de que nos estamos eternizando en los detalles, de si están seguros que ese nuevo añadido es más prioritario que las siguientes tareas en la lista.

Hay otro detalle, no sé si bueno o malo, y es el "pequeño estrés" que causa este método al desarrollador (yo). Al ver ellos el progreso día a día y ser tareas de tan poco tiempo estimado (1, 2, 3 días), "canta" mucho si un día me distraigo con cualquier cosa. Si tengo alguna reunión ajena al proyecto, si acabo de volver de vacaciones y tengo el típico día perezoso que te pasas "güeveando" en internet o con el email … Se ve agravado por el hecho de que para tener mejor visibilidad de cómo va el proyecto, llevamos un pequeño excel compartido que se actualiza todos los Viernes, en él aparecen las tareas, el tiempo que yo estimo para cada una de ellas en días y sumando esos días, la fecha prevista de terminación de cada una de ellas … y por tanto la fecha prevista de terminación del proyecto si se hacen todas las tareas. Si una tarea se complica más de lo previsto, ya me causa un pequeño "estrés" actualizar el excel y ver cómo la fecha de finalización se va alargando a la vista de todos. Pero me causa mucho más "estrés" si encima ese retraso va causado por la típica pereza que todos tenemos algún día que otro.

Puedo asegurar que nunca he trabajado tanto y tan seguido como en este proyecto, en parte por el "estrés" que me causa perder el tiempo, en parte por tener en todo momento perfectamente claro qué es lo que tengo que hacer y cómo. Ojo, no he echado ni una sola hora de más, es simplemente que apenas pierdo el tiempo a lo largo del horario laboral tratando de que el flujo de tareas de "to-do" a "done" sea lo más fluído posible.

Ahora nos estamos acercando a la fecha prevista de finalización, por supuesto, con requisitos iniciales que el cliente no ha considerado importantes al final de la lista to-do y totalmente fuera de plazo, pero con otros requisitos que han añadido sobre la marcha y que han considerado más importantes hechos a su gusto, con el cliente bastante contento en general. Veremos qué tal va el cierre final ….

Dec 20

KanbanFlow

 Hace unos días descubrí una herramienta online que me ha encantado, KanbanFlow.

Te registras gratuitamente y tienes la posibilidad de crear tableros Kanban. Lo que me ha gustado es la sencillez de uso, pero con bastantes posibilidades de configuración. Puedes crear varios tableros, indicar qué columnas tiene cada tablero, crear etiquetas de colores y simplemente arrastrarlas de una columna a otra, en fin, todo lo que se espera de un tablero. Puedes añadir subtareas, que no serían más que una lista de "checks" dentro de una etiqueta. Lleva además un cronómetro de pomodoro con el que podemos guardar tiempos de trabajo en las tareas.

La versión gratuita en principio permite crear cualquier número de tableros y compartirlos con cualquier número de usuarios. La versión de pago principalmente permite asignar roles a los usuarios, exportar a ficheros pdf, csv, etc, llevar histórico de las tareas y tiempos, …

Otro detalle es que la gente que está trabajando en esto parece estar pendiente del asunto. Puse una pequeña petición en su página de ayuda y soporte y aunque me la negaron, tardaron en contestar una o dos horas.

Sep 29

Metodologías ágiles y entregas frecuentes.

En la metodologías ágiles, Scrum por ejemplo, es típico que se hable de entregas al cliente frecuentes, con algo que les sea útil y donde puedan ir viendo los progresos. Últimamente, estoy pensando si eso es o no posible en todos los proyectos. ¿Por qué? Porque en el proyecto que estoy ahora es claramente posible y así lo estoy haciendo, pero eso me ha hecho darme cuenta que en los proyectos anteriores no solo no es tan fácil, sino que posiblemente es poco menos que imposible.

Los proyectos en los que ando actualmente, ya casi desde hace dos años, son proyectos web. Y cada proyecto lleva dos o como mucho tres desarrolladores y se hacen en unos meses, menos de un año, cada uno de ellos. En estas condiciones es fácil hacer entregas frecuentes. Tu proyecto solo lleva software y está público en internet. Así que haces un pequeño desarrollo de un par de semanas, aunque sólo sea el login, o la página principal con un poco de funcionalidad, la subes al servidor, se lo dices al cliente y ellos prueban y dan su opinión. Y repites el proceso cada 15 días o así añadiendo cada vez un poco más de funcionalidad, siguiendo las indicaciones de tu cliente.

¿Y cómo eran los proyectos de antes?. Pues bien, el proyecto más gordo en el que estaba metido era un proyecto en el que había varios departamentos implicados, de software, de hardware, de montaje (hierros, tornillos y cables), etc, etc. En unos camiones suministrados por el ciiente (unos 10 camiones), se montan varios equipos hardware, unos comprados como GPSs, estaciones solaris, PCs con Windows, receptores de radio, .. otros diseñados y fabricados específicamente para el proyecto, bien a otras empresas, bien a otro departamento, como radiogoniómetros o exploradores de frecuencia, … y se hace mucho, pero que mucho software, para controlar todo eso y presentar datos decentes a los usuarios en cada camión. Desgraciadamente, en semejante entorno, el software es lo que menos se nota. Por mucho software en varios lenguajes (Ada, Java y C++ sobre Windows y Solaris) que lleve el sistema, siempre llama más la atención 10 camiones, repletitos de equipos en su interior y con varias antenas gigantes en su exterior.

¿Cómo hacer entregas frecuentes y funcionales al cliente en este entorno?. Teniendo en cuenta que el hardware tarda lo que tarda en llegar, que los camiones no se nos entregan hasta que hay suficiente hardware como para empezar el montaje físico y que la mayor parte importante del software no se puede integrar hasta que están los equipos físicos…. la única opción es hacer simuladores de todo y hacer "demos" más o menos frecuentemente, que el cliente vea la interfaz de usuario, la pinta que tiene, qué datos va a presentar y cómo, como se va a manejar, …. pero todo con datos simulados. Y cuando llega el tiempo de integrar realmente con los equipos hardware verdaderos y ver cómo los ejecutables que corren en los diferentes camiones se comunican entre ellos, os aseguro que es un verdadero infierno, cualquier bug puede ser debido a cualquier cosa, desde un cable mal conectado, pasando por un equipo que no funciona correctamente hasta, por supuesto, un bug en el software.

¿Y cómo haces test automáticos de todo esto? Sí, se pueden hacer test automáticos de las "chorradas", como que si un usuario introduce mal su password no se le deja entrar en el sistema, típico ejemplo de cualquier manual ágil, pero no se puede probar de forma automática y fácilmente que si dos radiogoniómetros en camiones distintos detectan un emisor de radio y se triangula su posición, aparece dibujado en el mapa de  un tercer camión (de hecho, tiene que aparecer dibujado en el mapa de todos los demás camiones). Un test automático de todo esto, eliminado el hardware y sustituyéndolo por simuladores, implica arrancar al menos tres ejecutables (uno por camión), más los simuladores si son ejecutables sueltos ya que simulan un equipo hardware, y verficar que en un mapa (o en la base de datos que hay detrás del mapa) aparece el emisor de radio detectado en la posición correcta.

Estoy mucho más de acuerdo con la filosofía ágil que con la tradicional, pero no existe la llave inglesa universal que vale para todo tipo de tuercas y  tornillos simultáneamente. Si es posible aplicarla, adelante, y si no es posible, hay que hacer lo que se pueda intentando conseguir lo mejor de ella.

Aug 13

Configurando Hibernate para test unitarios.

Cuando hacemos test de JUnit o la herramienta que sea, una de las cosas difíciles de probar son las transacciones con base de datos. En nuestro entorno de desarrollo necesitaríamos una base de datos igual que la de producción y deberíamos borrar todos los datos, meter los datos previos al test para tener la base de datos en un estado conocido, hacer el test y luego revisar el contenido de la base de datos. Esto, aparte de complejo, puede ser muy lento con una conexión a una base de datos real.

Una de las soluciones es utilizar una base de datos en memoria (como HSQLDB, H2, etc). Estas bases de datos suelen ser un jar que no necesita instalación, así que basta con añadirlo a nuestro classpath en los test. Al ser en memoria, los test serán también muy rápidos. Sin embargo, sigue habiendo dos problemas:

  • En cada test habría que crear todas las tablas desde cero.
  • Las SQL de estas bases de datos pueden no ser las mismas que la de nuestra base de datos de producción (MySQL, Oracle, etc).

Para ayudarnos a solucionar estos problemas podemos usar Hibernate (u otra herramienta similar). Si en el fichero de configuración de Hibernate, los de mapeo de clases (o anotaciones) y nuestro código no usamos nada específico de una base de datos (debería ser lo normal salvo casos excepcionales), Hibernate nos hará independientes de la base de datos que usemos (de hecho, ese es uno de sus objetivos). Por otro lado, hibernate tiene un parámetro de configuración hibernate.hbm2ddl.auto en el que le podemos indicar que cree desde cero todas las tablas de la base de datos. Así que Hibernate nos resuelve, en principio, los dos problemas mencionados.

La primera idea que se nos ocurre es tener dos ficheros de configuración de Hibernate (hibernate.cfg.xml), uno para producción con la base de datos real y otro para test. Pero somos buenos programadores y no nos gusta tener cosas repetidas (principio DRY), posiblemente esos ficheros sean prácticamente iguales salvo los parámetros de conexión a la base de datos y el mencionado parámetro hibernate.hbm2ddl.auto, que en nuestro base de datos de test valdrá "create" y en la de producción puede valer algo como "verify".

La solución es simple, basta tener un único fichero de configuración para la base de datos de producción, con toda la parámetrica real. Para los test cargamos ese fichero … y modificamos en código sólo lo que nos interese. Se puede hacer de esta forma

Configuration configuration = new Configuration().configure();
configuration.setProperty("hibernate.connection.url", "jdbc:h2:mem:databaseName");

configuration.setProperty("hibernate.hbm2ddl.auto","create");
SessionFactory sessionFactory = configuration.buildSessionFactory();
 

El método configure() de Configuration leerá el fichero por defecto de configuración (suponemos que es el de producción) y luego, con el método setProperty() podemos "machacar" todas las propiedades que queramos de ese fichero. En el ejemplo sólo hemos cambiado la url de la base de datos y hibernate.hbm2dll.auto, aunque posiblemente deberíamos cambiar también el nombre de la clase del Driver de base de datos, usuario, password, etc.

Ahora sólo nos quedaría poner este código en algún sitio al que nuestras clases de test puedan acceder. Nuestras clases de test obtendrían el sessionFactory usando este código, mientras que el código de producción lo obtendría de la forma habitual, posiblemente a través de un UtilHibernate.java.

Por supuesto, no nos libra nadie de llenar la base de datos en cada test con unos datos conocidos y analizar luego los resultados.

Nos queda un detalle, que es borrar los datos después de cada test. Utilizando la base de datos en memoria como hemos hecho en el código anterior, quedará "viva" y con datos mientras esté arrancada la máquina virtual java. Al ejecutar una batería de test (con mvn test, por ejemplo), la máquina virtual no muere hasta que acaban todos los test, por lo que los datos que unos test van dejando en base de datos quedan para los siguientes test, aunque estén en memoria. Debemos vaciar esos datos después de cada test.

Una opción "pesada" es ir borrando los datos o hacer un "drop" de las tablas, en el orden adecuado para evitar problemas de "contraints". Pero otro método rápido y sencillo consiste en simplemente cerrar el SessionFactory. El siguiente test tendrá que crear un SessionFactory nuevo (con el código de arriba) y así se volverán a crear todas las tablas desde cero. Es decir, nuestras clases de test tendrán los métodos setUp() y tearDown() (o @Before y @After en JUnit 4) de la siguiente forma

public class TestUno extends TestCase {
   private SessionFactory = sessionFactory;

   @Override
   public void setUp() {
      sessionFactory = // Obtener session factory con el codigo anterior
   }

   @Override
   public void tearDown() {
      sessionFactory.close();
   }
   …
}

 

Simplemente un detalle. De esta manera realmente no se borran los datos al terminar en test. En realidad se borran al empezar el siguiente test, ya que el "create" de hibernate.hbm2dll.auto hace exactamente eso, borrar para crear desde cero.

 

Jul 07

Triangulación con TDD

Test Driven Practical TDD and Acceptance TDD for Java DevelopersEstoy leyendo ahora en mis ratos perdidos de tren al trabajo el libro Test Driven: TDD and Acceptance TDD for Java Developers. Los dos primeros capítulos me han resultado muy pesados porque no paran de repetir una y otra vez las ventajas de TDD de mil formas distintas, ventajas por otra parte ya bastante conocidas. Pero acabo de entrar en la parte donde se va desarrollando código con TDD y me está pareciendo interesante.

Una de las cosas que me ha llamado la atención es lo de la "triangulación" con TDD. Ya había leído de ella sin llegar a entenderla realmente, simplemente porque los ejemplos que había leído de triangulación eran muy tontos. Por ejemplo, si tienes que hacer un test de una clase que suma, el primer test podría ser el típico

assertEquals(4, sumador.suma(2,2));

Explicando la triangulación te dicen que pongas directamente que ese método suma(2,2) devuelve a piñón fijo 4 y luego, triangulando, haces otro ejempo de suma, por ejemplo, suma (2,5) y así llegas a la implementación correcta return sum1+sum2. Como se puede ver, algo un poco "estúpido".

Este libro menciona la triangulación varias veces, pero en un párrafo deja muy claro qué es exactamente o, al menos, así me lo ha parecido a mí. El ejemplo que comenta es que queremos tratar varias tipos de tarjetas de crédito (visa, master card, dinners club, etc, etc). El problema es que cada tarjeta tiene sus particularidades y que podemos no tener muy claro cómo hacer el código para tratar todas esas particularidades, qué partes van a ser comunes y ponernos a pensar a priori todo ese código puede ser tedioso.

Así que la solución es la famosa triangulación. Cogemos una de las tarjetas y empezamos el TDD con ella, los test, el código, específico para esa tarjeta, sin preocuparnos de las otras y finalmente el refactoring. Luego cogemos la segunda, hacemos nuevos test para esa y modificamos el código para que funcione para las dos. En la parte importante de refactoring es donde realmente arreglamos ese código para que las partes comunes y no comunes queden bien diseñadas para esas dos tarjetas. Luego tercera tarjeta, más test, más tocar código y lo más importante, nuevamente refactoring para que el diseño sea lo más claro y mejor posible para tres tarjetas.

De esta forma, deberíamos llegar a una de los mejores diseños posibles para tratar los tipos de tarjeta que debemos tratar.

Así que cuando hacemos TDD, más que triangular siempre a piñón fijo, incluso para suma(2,2) haciendo que devuelva 4 a piñón fijo y obligarnos a hacer otro test suma(2,5), debemos aplicar triangulación cuando tenemos varios casos similares pero con peculiaridades cada uno de ellos y no tenemos muy claro cómo hacer un código elegante o el mejor diseño para tratar esas particularidades a priori.

 

Apr 11

He leído “Scrum y XP desde las trincheras”

Aprovechando el eBook que me han traído los reyes estoy leyendo mucho últimamente, en el tren y en las cafeterías (sí, soy el friky ese que se sienta solo en una esquina y esconde las narices en el libro, aunque no tengo muy claro si esa expresión aplica a un eBook). Ahora le ha tocado el turno a "Scrum y XP desde las trincheras", de Henrik Kniber.

El libro no cuenta Scrum, por lo que no es el adecuado si quieres aprender qué es Scrum. De XP habla más bien poco o nada (creo que menciona la programación en parejas en un par de ocasiones, poco más). Entonces, ¿de qué va el libro?

El autor trabaja con grupos de desarrolladores que aplican Scrum y como la teoría nunca es tan bonita como la pintan, aplicar Scrum tiene un montón de problemas o cosas que no están muy claras cómo resolver. El autor nos va contando los problemas que ellos han encontrado, soluciones que han probado, soluciones que han adoptado y qué problemas todavía no saben resolver. Es un libro adecuado para aquellos equipos que saben qué es Scrum y lo están aplicando desde hace poco y se van encontrando con los problemas típicos de aplicar Scrum. Este libro le ofrece un abanico de soluciones posibles y cuáles le han funcionado al autor y cuales no.

Algunos problemas típicos:

¿Qué hacer cuando alguien del equipo se queda sin tarea dentro del Sprint?. Entre las soluciones del autor está el dejarle que él mismo elija cualquier cosa que pueda hacer para ayudar al equipo (test, pruebas, documentación, scripts que automaticen tareas, lo que sea). Y si sigue sin encontrar nada para hacer, entonces convertirlo en "recadero" de los miembros del equipo, una forma de ayudar es traerles café, por ejemplo.

¿Qué hacer cuando el código o lo que sea necesita tiempo para ser arreglado y no para producir historias válidas de  un Sprint?. El autor propone varias cosas, pero parece que opta por bajar el factor de rendimiento del equipo lo suficiente como para que puedan abordar estas tareas de mejora, es decir, aceptan menos historias en el Sprint.

¿Qué hacer si el proyecto es grande y necesita muchos desarrolladores?. El autor dice haber probado con un equipo de Scrum grande y con varios más pequeños. Al final la solución buena según él es hacer equipos pequeños (de entre 3 y 10 desarrolladores).

Y si hay varios equipos Scrum en el mismo proyecto, ¿cada uno a su bola? ¿Sprint sincronizados? ¿Un sólo dueño de producto o uno por equipo?. Entre las soluciones del autor, parece que opta por un sólo dueño de producto, Sprint sincronizados de forma que la demos sean el mismo día, la planificación también pero solo par repartir las historias entre los equipos, luego cada equipo hace su planning poker. Las reuniones diarias deben hacerse a diferentes horas, de forma que el jefe de producto pueda acudir a todas reuniones de todos los equipos si quiere, etc, etc. Otra ventaja de esto es que al terminar cada Sprint se pueden intercambiar miembros entre los equipos, partir un equipo más grande en otros más pequeños o juntar dos equipos en uno.

¿Y qué hacemos con los que llegan tarde a la reunión diaria?. Elegir una hora buena para todos y si los tardones son habituales, lo típico de echar una moneda a un fondo común o traer "bollitos" para todos.

¿Y si el equipo está distribuido geográficamente?. Messenger abierto todo el día, web cams, etc, etc y todo lo posible para facilitar la comunicación. Habla incluso de poner web cams permanentes, de forma que todos puedan verse a todos en cualquier momento.

En fin, lo dicho, todo un abanico de problemas y posibles soluciones. El libro es ameno de leer y no se hace en absoluto pesado.

 

Jan 14

¿Se deteriora Scrum?

scrumVeo que Scrum está dando fuerte. En nuestra empresa, aparte de nuestros intentos de hacer Scrum, hay otros departamentos que también lo están intentando. También conozco gente en otras empresas con las que colaboramos que están empezando a usarlo. Pero no solo es eso lo que me llama la atención ("frikis" los habemos en todos lados)

Por un lado, en la portada de nuestra intranet, que la empresa aprovecha para poner lo maravillosa que es, los proyectos que tiene y lo bien que va, apareció hace unos días un artículo en el que nuestra empresa y otra habían colaborado para la implantación de Scrum en los procesos de no sé qué.

Por otro, ha caído en mis manos (de forma completamente legal) una oferta técnica de otra empresa para el desarrollo de un sistema … y en él ponen que usarán redmine … y Scrum como metodología de desarrollo.

Todo esto tiene su parte buena … y su parte mala.

La parte buena es que Scrum está ganando la suficiente fama de ser una buena metodología de desarrollo como para que las empresas empiecen a considerarlo como algo bueno, que merece la pena intentar. Lo ponen en su propaganda, en sus ofertas, …

Lo malo es lo de siempre, que se acaba desvirtuando el fondo real que hay detrás de la metodología. Al convertirse en algo "bonito" para poner en papel, se pondrá "usamos Scrum" por sistema, se use bien, se use mal o no se use en absoluto. El cliente no conseguirá siempre los resultados esperados de esta metodología y acabará perdiendo su fama.

La verdad es que estoy un poco hasta las narices de las mentiras empresariales, "vende-motos" y palabras rimbombantes. Conseguir un premio a "la excelencia empresarial" es muy fácil, sea lo que sea eso, pero todos los curritos sabemos que lo que hay detrás es cualquier cosa menos "excelencia". La "garantía de calidad", sea lo que sea eso, tres cuartos de lo mismo. Tener la "certificación ISO no sé qué", sea lo que sea eso, igual. Y dentro de nada, ser "Scrum certified" será algo (sea lo que sea) que no sabremos que es, pero que pagando se consigue.

Jul 03

Ventajas de la reunión diaria

Daily ScrumComo no todo es blanco o negro, las metodologías ágiles tienen también muchas cosas buenas. Una de las más sencillas de implementar y con la que conseguir mejoras son las reuniones diarias. Intentamos ya en varias ocasiones hacer Scrum y Kanban, incluso TDD y varias más de las metodologías/prácticas ágiles. Aunque seguimos en el intento, la reunión diaria es la más fácil de seguir y de la que obtener ventajas rápidamente.

La hora teórica de entrada es las 8:00. Habitualmente la gente suele ir llegando sobre las 8:30 y lo primero que hago es ir a tomar café con mi amiguete y luego revisar el correo, el Hudson y el Taskfreak. Imprimo este último y con él, sobre las 9:00 hacemos nuestra reunión de 10/15 minutos. Antes éramos cuatro en la reunión, ahora sólo somos tres.

La reunión la hacemos sentados. Las buenas costumbres aconsejan hacerla de pie para que la gente esté incómoda y la reunión no se prolongue más de la cuenta, pero con el tiempo hemos conseguido no tener ese problema, rara vez dura más de 10 minutos y nos permitimos hacerla sentados.

¿Qué mejoras hemos conseguido con la reunión diaria?

Sensación de grupo

La primera y más importante es la sensación real de la gente de formar parte de un grupo. En nuestro caso concreto, si lo de contar "qué hicimos", "qué vamos a hacer" y "qué problemas tenemos" nos lleva realmente cinco minutos (sólo somos tres), solemos permitirnos unos cinco minutos más de reunión para "cotilleos": comentar como van las pruebas de un proyecto, qué tal le va a uno que está desplazado en la India, los planes del jefe de mover a cierta persona a otro proyecto, etc, etc. Todo esto, además de reforzar la sensación de equipo de trabajo, también refuerza algo los lazos de compañerismo.

Dije que antes eramos cuatro y ahora somos tres. ¿Qué pasó con el cuarto?. Simplemente que le propusieron pasarse a algo más adecuado a su perfil (administrador en vez de programador) y depender de otra persona que no era yo. Pero cuando se lo propusieron, dijo que no quería cambiar del todo, se sentía muy integrado en nuestro grupo y no quería perder eso.

Fue realmente una sorpresa esta objeción. Cuando estaba en nuestro grupo tendía a distraerse de las tareas de programación para dedicarse más a instalar tarjetas de red, configurar routers, instalar software, etc, se le veía claramente que le iba más eso que programar. Le propuse el cambio a mi jefa y ella me dio la razón, pensó que esta persona podía disfrutar más de su trabajo en el grupo de administradores y le propuso el cambio. Y la objeción fue imprevista, efectivamente, dijo que le gustaba más instalar cosas que hacer software, pero que no quería cambiar por sentirse muy integrado en nuestro grupo. Así que el cambio fue gradual, pasó a realizar tareas de administrador poco a poco y siguió acudiendo a nuestras reuniones para hacer su parte de trabajo de programador. Al final la realidad se impuso y realizar dos papeles distintos es imposible, así que dejó cogiendo cada vez más trabajo de administrador y menos de programador y dejó de acudir a las reuniones de forma natural.

De hecho, los tres que quedamos estamos a punto de trabajar en cosas totalmente distintas (tres proyectos distintos, con tres jefes de proyecto distintos y temáticas totalmente distintas). Pero de común acuerdo hemos decidido seguir haciendo las reuniones porque a fin de cuentas el software es software, los problemas son similares y si alguien tiene un problema y lo cuenta a los que ya considera sus compañeros, enseguida se prestan a ayudarle a resolverlo.

Enfocarse en las tareas concretas del día a día

El tener nuestra lista de tareas y decir a primera hora de la mañana "hoy voy a hacer esto" hace que el resto del día tengas claro qué vas a hacer. Supongo que hay algunos que no necesitan este tipo de cosas, pero yo soy de los que tiende a saltar de una cosa a otra. "Comprometerme" con el grupo a que ese día voy a hacer determinada cosa (aunque ninguno de ellos dependa de que yo lo haga), me pone una pequeña traba a distraerme. Me daría vergüenza al día siguiente decir "no he hecho esta tarea porque he estado mirando el correo, navegando por internet, mirando otra vez el correo, un café, probando una herramienta que me he encontrado …."

Así que lo dicho, decir en público "hoy voy a hacer esto", de alguna forma te obliga a centrarte en hacer exactamente eso.

Saber dónde se va el tiempo e incentivo a la mejora

A pesar de todo, en muchas ocasiones, al día siguiente acabas diciendo "No he terminado la tarea que dije ayer" y cuando llegas a la parte de los problemas que has tenido para acabarla dices "me han llamado a una reunión de tres horas", "Se han llevado un ordenador del laboratorio que hacía puerta de enlace de la red del laboratorio y me he quedado sin conexión con los equipos", "me han pedido hacer esto de otro proyecto", etc, etc, etc.

Algunas cosas son inevitables, pero al menos eres consciente de dónde se pierde el tiempo, ya que tienes que decirlo claramente a tus compañeros. Pero cuando esas pérdidas de tiempo tienen arreglo, enseguida "canta" que perdemos el tiempo por algo que hacemos mal y que se puede arreglar/mejorar. Justo lo que pregona Scrum. Aunque en nuestro caso ha quedado un poco fuera la figura de Scrum Master, siempre alguno del grupo coge como tarea mejorar eso que dificulta el trabajo.

Aprovechar la capacidad de los mejores

Y aunque los mejores del grupo o con más capacidad posiblemente no necesiten estas reuniones para centrarse en lo que tienen que hacer o para mejorar su propio proceso de trabajo, no todos tienen esa capacidad.

En estas reuniones las personas de más capacidad se hacen también conscientes de los problemas de los demás, no sólo de los suyos propios. Son capaces incluso de ver posibles mejoras en donde la otra persona ni siquiera ha detectado un problema. De esta forma, todos se benefician de los mejores aunque no vayan específicamente a preguntarle por un problema concreto.

Y los mejores tampoco son infalibles, muchas veces alguien no tan bueno es capaz da una idea o propone algo que se le había escapado

Resumiendo

Resumiendo, que estamos encantados con nuestra reunión diaria y que aunque tiene pinta que el grupo se disgrega (cada uno a su proyecto), por unanimidad queremos seguir haciéndola. Quizás el tiempo nos diga que carece totalmente de sentido… o quizás no.

Y aunque se puede ver claramente que no hacemos una reunión diaria al puro estilo Scrum (no la hacemos de pie, no hay tablero aunque sí lista de tareas, no ha scrum master propiamente dicho), la mejora es apreciable por todos.

Jul 02

¿Qué habría pasado de usar TDD?

hommer pensando en un programa softwareSiguiendo un poco con el post anterior, hace tiempo en Verlo para creerlo comenté un código real de una empresa con el que me había tropezado. En ese código había una clase (llamémosla Datos) con 16 atributos estáticos iguales (digamos, atributo1, atributo2, … atributo16). Pulsando un botón (uno por atributo) debía mostrarse en una ventana nueva algunas cosas relativa a uno de esos atributos. En el código había 16 clases Ventana, una por atributo, llamadas Ventana1, Ventana2…. Ventana16. La única diferencia en el código de esas clases, aparte del nombre, era que accedía a Datos.atributo1, Datos.atributo2 … Datos.atributo16

¿Qué habría pasado si hubieran usado TDD?

Supongamos que este mismo programador hubiera hecho este código usando TDD. ¿Qué habría pasado?. Pues lo evidente, habría 16 clases de test llamadas TestVentana1, TestVentana2, … TestVentana16.

Pero TDD no es sólo hacer test, es hacerlos antes. Bueno, supongamos que los ha hecho antes.

Y TDD tiene otro tercer paso, refactorizar para quitar todas las repeticiones posibles de código, incluso las menos evidentes. Bueno, no sé vosotros, pero yo, independientemente de usar o no TDD, me repatearía hacer copy-paste 16 veces de una misma clase y como ser vago a veces es una virtud, habría dado las vueltas necesarias para no hacer esto. Sin TDD se me ocurre simplemente meter los atributos en un array de 16 posiciones y en un método set() de la única clase VentanaUnica pasarle el índice de la posición que debe tratar. Es lo primero que se me ocurre, nada complejo, seguramente hay más y mejores soluciones.

Sin embargo, este desarrollador no lo ha hecho. ¿Por qué?. Se me ocurren cuatro posibles motivos:

  1. Totalmente inexperto en java, un array es algo complejo de usar y lo del set() ni lo cree posible. Muchos programadores novatos tiene problemas para hacer que los atributos de una clase se vean en otra y por eso tienden a hacerlos estáticos (justo como ha hecho este señor).
  2. No tiene cabeza para programar, por más vuelta que le ha dado, no se le ha ocurrido cómo evitar hacer las 16 clases.
  3. Le importa tres pepinos. Para qué se va a complicar la vida si con 16 clicks de ratón (un copy y 15 pastes) lo arregla.
  4. Todas las anteriores.

Bueno, pues con este panorama, ¿qué habría hecho al intentar refactorizar con TDD?

  1. Ya tengo mi TestVentana1, así que hago mi Ventana1. Ahora mi TestVentana2 y hago mi Ventana2. ¡¡ Código repetido !!. ¡¡ Vamos a refactorizar !!: Imposible, java no permite hacerlo, si java no permite pasar el atributo de la clase Datos a la clase Ventana, Ventana1 y Ventana2 deben ser clases distintas. Y no te digo juntar los dos test en uno solo.
  2. Buff, qué dolor de cabeza, no se me ocurre como puedo convertir dos clases distintas que manejan atributos distintos en una sola.
  3. Jó, que rollo refactorizar ahora que me está funcionando, voy con los siguientes 14 pastes, que el copy ya lo tengo hecho.
  4. Java no deja, no se me ocurre como hacerlo y voy a correr un montón si reaprovecho el copy para el resto de pastes.

Algo como Srcum tampoco evitaría estas cosas. En el sprint diario este señor diría "Ya tengo las ventanas de  los atributos" y todos felices. Bueno, con un poco de suerte, un día diría "tengo la Ventana1 del atributo1", al día siguiente "tengo la Ventana2 del atributo2" y alrededor del quinto día, quizás a alguien se le ponga la mosca detrás de la oreja y quiera ver qué está haciendo. De todas formas, no se tardan 16 días en hacer 15 pastes.

Una herramienta de análisis estático de código integrada en una herramienta de integración continua cantaría esto por la noche, suponiendo que cante cuando encuentra código repetido y, como hacemos nosotros, el compilado falla si no se cumple alguna métrica importante. Desgraciadamente, existe el @SuppressWarnings que la gente se acostumbra a poner por sistema, incluso antes de que cante la métrica (conozco al menos dos personas que lo hacen).

La programación en parejas también habría ayudado, salvo que la pareja de nuestro programador fuera el recién entrado al que le han asignado para que le enseñe.