lunes, diciembre 29, 2008

Feliz 2009

Desde este modesto blog os deseo un Feliz 2009.

viernes, diciembre 26, 2008

Editor para Concordion

Papá Noel me ha traído esta Nochebuena un plugin Eclipse para facilitar el trabajo con Concordion. Si abro una especificación (un fichero html) con el editor Concordion, se abre una ventana de edición con dos pestañas: una con la especificación y otra con la fixture (el fichero java asociado). De la misma manera, si abro la fixture (un fichero java) con este editor, se abre una ventana de edición con las mismas dos pestañas y los mismos contenidos. Las fixtures se editan con el editor Java estándar y las especificaciones html con el editor web, que a su vez tiene dos pestañas: una con la vista de diseño y otra con la de previsualización. Además, la vista de diseño web está dividida y muestra arriba la página web para editar en formato WYSIWYG y abajo en puro HTML.

He basado el desarrollo en el ejemplo de editor multipágina que viene con Eclipse y en el WicketBench, un editor para Wicket que hace muchas más cosas y del que he tomado prestadas algunas ideas también para el futuro. Sin embargo, aún tengo que trabajar mucho este plugin porque es la primera vez que hago algo útil con Eclipse RCP y tengo mucho que aprender. De momento, los siguientes pasos serán:

  1. hacer pruebas unitarias (para poder refactorizar)

  2. refactorizar (es mejor no mirar al código ahora mismo)

  3. crear automáticamente el desplegable en forma de site (ahora es un jar que construyo manualmente)



Podéis descargar el jar y simplemente dejarlo en la carpeta "plugins" de vuestra instalación de Eclipse.

Felices Fiestas a todos, por cierto.

viernes, diciembre 12, 2008

Sustitución fácil de colaboradores con Mockito

Acabo de probar Mockito y creo que por fin he encontrado el framework de mocks que necesitaba. Crear "stubs" para sustituir a los colaboradores en las pruebas con EasyMock o jMock me resultaba muy laborioso, en cambio con Mockito es muy fácil.

El ejemplo:

@Test
public void testComprarUnProducto() {
TerminalPuntoDeVenta tpv = new TerminalPuntoDeVenta(100,logger);

CodigoProducto codigo = new CodigoProducto("FANTA 33CL","1234567890");
DispositivoEscaner mockEscaner = mock(DispositivoEscaner.class);
when(mockEscaner.scan()).thenReturn(codigo);
tpv.setEscaner(mockEscaner);

RepositorioProductos mockRepositorioProductos = mock(RepositorioProductos.class);
Producto producto = new Producto(codigo);
producto.setPrecio(10);
when(mockRepositorioProductos.buscarProducto(codigo)).thenReturn(producto);
tpv.setRepositorioProductos(mockRepositorioProductos);

tpv.setImpresora(mock(DispositivoTicket.class));

tpv.iniciarCompra();
tpv.scan();
tpv.finalizarCompra();
double resultado = tpv.cerrarCaja();
assertEquals(110,resultado,0);
}


Los métodos estáticos mock y when son la clave, especialmente when, porque en vez de liarnos a grabar expectations como con otros frameworks, con Mockito decimos cuando llamen al objeto sustituido a tal método y con tales parámetros, entonces devuelve tal resultado. Mucho más intuitivo.

Además, como estoy intentando "quitarme" de las pruebas que comprueban las colaboraciones, me viene genial; aunque si quisiera, no tengo más que hacer los verify que también haría con los otros.

Actualización:
He sacado un rato y he escrito el mismo ejemplo pero con EasyMock.


@Test
public void testComprarUnProductoConEasymock() {
TerminalPuntoDeVenta tpv = new TerminalPuntoDeVenta(100,logger);

CodigoProducto codigo = new CodigoProducto("FANTA 33CL","1234567890");
DispositivoEscaner mockEscaner = createMock(DispositivoEscaner.class);
mockEscaner.scan();
expectLastCall().andReturn(codigo);
tpv.setEscaner(mockEscaner);

RepositorioProductos mockRepositorioProductos = createMock(RepositorioProductos.class);
Producto producto = new Producto(codigo);
producto.setPrecio(10);
mockRepositorioProductos.buscarProducto(codigo);
expectLastCall().andReturn(producto);
tpv.setRepositorioProductos(mockRepositorioProductos);

DispositivoTicket mockImpresora = createNiceMock(DispositivoTicket.class);
tpv.setImpresora(mockImpresora);

replay(mockEscaner);
replay(mockImpresora);
replay(mockRepositorioProductos);

tpv.iniciarCompra();
tpv.scan();
tpv.finalizarCompra();
double resultado = tpv.cerrarCaja();
assertEquals(110,resultado,0);
}


martes, diciembre 09, 2008

Muerte al if

Ahora que se puede pedir la muerte de los monarcas en impunidad, yo también me voy a unir a la moda y voy a pedir la muerte de otro rey: "¡Muerte al if!"

Nota: Que conste que no estoy entrando en el fondo (ni en la forma) sobre el asunto de Joan Tardà, que no se vaya a molestar nadie... :-)

Pues bien, a lo que iba, hace ya unas semanas hice una breve referencia a la campaña anti-if a la que me adherido tal y como reza un anuncio en el lateral de este blog. Os recomiendo encarecidamente la siguiente entrada del blog de Miško Hevery titulada "Inheritance, Polymorphism, & Testing" (sí, lo siento, en inglés) porque no tiene desperdicio. Tranquilos, si no os queréis "chupar" la media hora larga de presentación, también están las diapositivas. Por cierto, ahí está la respuesta a cómo se resuelve el segundo ejercicio del TestFirstChallenge que he usado en algunas ocasiones para enseñar TDD e incluso para seleccionar candidatos en una empresa donde trabajaba antes (no diré cuál para no dar pistas). :-)

Por cierto, antes de que se me olvide, ¿alguno de vosotros usa Guice? Estaría bien que contárais la experiencia, sobre todo si la podéis comparar con Spring. ¡Sería genial!

lunes, diciembre 08, 2008

Estado del proyecto : métricas ágiles

Acabo de leer el artículo que Xavi Albaladejo ha publicado en Proyectos Ágiles titulado "Métricas ágiles y cuadro de mandos balanceado para Scrum".

En mi modesta opinión, me parece una buena recopilación de métricas (algunas difíciles de automatizar, como la del resultado de las retrospectivas, pero no por ello de menor valor. Me atrevo a preguntaros, ¿qué 5, 6 ó 7 métricas usarías para que el cliente tuviera una visión resumida del estado del proyecto? Vamos, ¿cómo construiríais el "cuadro de mandos" para vuestros clientes?

Vale, como está feo tirar la piedra y esconder la mano, ahí van las mías:
  • Velocidad del equipo (para cada sprint)
  • ROI. Cada historia de usuario debe tener un valor de negocio asignada por el Dueño del Producto y, por tanto, podemos saber cuánto valor de negocio se ha convertido en cada sprint.
  • Las tres métricas de calidad que Xavi resalta: Satisfacción del cliente o usuario, Incidencias o defectos detectados por los usuarios, Defectos detectados por el equipo de desarrollo.
  • Tiempo de puesta en producción después de cada sprint. (Esta métrica no la incluye Xavi, pero a mi entender serviría para, de alguna manera medir parte de las "Lecciones aprendidas")
Me gustaría también ser capaz de ofrecer al cliente alguna medida del riesgo que se está asumiendo y cómo va afectando éste durante la vida del proyecto, pero sinceramente no sabría bien cómo hacerlo. Quizás una buena referencia para esto (en inglés) sería este artículo que enseña a estimar el riesgo con una hoja de cálculo.

No estaría mal mostrar el "panel de control" como una "radar chart" para poder comparar de un vistazo varias métricas de un sprint a otro, p.ej.



¿Sería diferente el cuadro de mandos del cliente y el del ScrumMaster o jefe de proyecto? Hombre, el corazón me dice que deberían ser iguales por eso de que "somos un equipo", "la transparencia con el cliente", y todo eso..., pero la razón me dice que a cada uno le interesa una perspectiva diferente del proyecto:
  • al cliente es algo más económico, de valor de negocio, de rentabilidad de la inversión en marcha,
  • mientras que al ScrumMaster le interesa más bien los impedimentos que se pueden estar acercando para poderse adelantar a su aparición.
Por eso creo que deben ser diferentes. ¿Cuáles serían vuestras métricas para el ScrumMaster?

Las mías, creo que serían:
  • Velocidad del equipo. Sí, también, de hecho, con más razón incluso que para el cliente. De esta métrica se pueden sacar muchas conclusiones que contrastar en las retrospectivas con el equipo. Es muy importante averiguar a qué pueden ser debidas las variaciones en la velocidad: estimamos mejor, hemos eliminado un impedimento que puede volver a surgir, ha surgido un impedimento que nos retrasa...
  • Las líneas de código. Sí, sé que es un poco llamativo y
    "anticuado", pero me parapeto detrás de un excelente artículo de James
    Shore (autor de "The Art of Agile Development") sobre cómo medir la deuda técnica.
  • Felicidad del equipo. Bfff, esto es dificil de explicar, pero la actitud que tiene el equipo después de cada retrospectiva es importantísimo en el desarrollo del siguiente sprint. Recomiendo leer sobre el "Niko-niko calendar", y si alguien lo pone en práctica, estaría encantado de conocer sus impresiones.
  • Desviación en las estimaciones. Me parece importante ofrecer este feedback al equipo (porque el "cuadro de mandos" creo que debe ser para todo el equipo), y por ello creo que el ScrumMaster debe ser capaz de recopilar esta información y manejarla con cuidado porque puede afectar mucho a la credibilidad del equipo (incluso para ellos mismos).
  • Calidad del código: cobertura, complejidad ciclomática y las reglas de calidad acordadas que podamos automatizar con herramientas como Checkstyle, PMD, JDepend... Para esto último aconsejo encarecidamente que probéis Sonar.
Algunas métricas (como el "nikocal") no son exactamente cuantificables, pero no es importante porque de lo que se trata es de ver las tendencias. En todos los casos, lo que importa no es la "instantánea" sino la tendencia puesto que sólo de las tendencias podemos sacar conclusiones o al menos elaborar hipótesis que nos ayuden en nuestro camino.


Doy por supuesto que tenemos en las paredes o en una herramienta (como radiadores de información) nuestros paneles constantemente actualizados con las historias de usuario del sprint en curso, las iniciadas y las terminadas, así como el gráfico de "burndown" y cualquier otro que vuestro(s) equipo(s) haya(n) considerado a bien tener siempre a la vista.

Y también doy por supuesto que nuestro equipo y nuestra organización están ya lo suficientemente maduros como para no tener que medir cosas como:
  • Número de veces que se rompe el build (en Integración Continua)
  • Calidad de los commits en el SCM. Por ejemplo, si pasan días sin que nadie haga commit es que algo muy malo está pasando. O si los commits no llevan un comentario que permita identificarlo y trazarlo con la tarea correspondiente.

viernes, diciembre 05, 2008

La Gran Brecha de la Fatalidad

Acabo de verme enterita una presentación de Dan North y Martin Fowler en la QCon 2007 de Londres titulada "The Yawning Crevasse of Doom" (La Gran Brecha de la Fatalidad) donde hablan (durante 1 hora) sobre la necesidad de construir puentes de comunicación entre el negocio y la técnica. Llegué a ella a partir del blog de Gojko Adzic (que está preparando un libro sobre pruebas de aceptación ágiles) y de ella es posible obtener muy buenos argumentos y técnicas agilistas. Insisto: muy recomendable.

Durante 1 hora da para decir muchas cosas, pero yo me quedaría con lo siguiente:

Construir puentes
En vez de tener a los analistas yendo y viniendo entre los usuarios y los técnicos (la brecha), es mejor conseguir que la organización permita establecer puentes entre ambos mundos. Aquí insisten en la importancia vital de las conversaciones entre usuarios y técnicos porque ayudan a evitar trabajar en funcionalidades que no aportan valor de negocio y además permiten encontrar mejores soluciones que trabajando a través de intermediarios.

Fatalidad
Si creemos que no es posible construir esos puentes, estaremos de alguna manera influyendo en nuestro entorno para que la brecha se siga manteniendo e incluso se amplíe. Así se defienden unas partes de otras mediante contratos, documentos de requisitos, diagramas de arquitectura... En cambio, si la actitud es positiva, es posible colaborar en un entorno de confianza en la que incluso se pueda trabajar en construir un sistema sin conocer cómo será el "desplegable" final.

Lenguaje ubicuo
Para que todos dentro del equipo (gente de negocio y gente técnica) puedan entenderse es conveniente usar un lenguaje ubicuo (tal y como recomienda Eric Evans en su estupendo libro "Domain-Driven Design").
Sin embargo, el uso de un lenguaje común entre usuarios y técnicos que permita y/o facilite la comunicación entre ambas orillas no debe obligarnos a que este lenguaje sea "universal" para toda la empresa. Fowler dice explícitamente que es mejor un conjunto de "modelos locales" (más manejables y comprensibles y menos abstractos) y un mecanismo de mapeo entre ellos.

Construir juntos
Técnicas como construir juntos "Prototipos de baja fidelidad" (ya sabéis, "paper prototyping" con Post-Its, etc), "Storyboards" (como los que se usan para las películas de cine),... ayudan a construir esos puentes.

Hecho
Para especificar qué entienden los usuarios y los técnicos por "tarea completada" es conveniente utilizar ejemplos, idealmente que se puedan comprobar automáticamente. (Es lo que se conoce como pruebas de aceptación ejecutables).

Suficiente
Otro término muy relacionado con "hecho" es "suficiente". Se trata de conocer lo suficiente para avanzar hasta el siguiente paso. Para ello es necesario asumir que las prioridades están en constante cambio durante la construcción del proyecto.

Productividad
Un detalle, ¿sabíais que sólo el 15% aprox del coste total del software corresponde a la programación?
Es muy importante trabajar continuamente en encontrar todas las oportunidades posibles que nos permitan recoger reacciones (feedback) de todos los miembros del equipo y conocer aquellos factores puedan afectar al estado de ánimo del equipo puesto que éste es un aspecto psicológico que afecta significativamente a la comunicación y, por tanto, a la productividad.

jueves, diciembre 04, 2008

Introducción a m2eclipse

Por fin he conseguido terminar la traducción del artículo "Introduction to m2eclipse" que comenté hace unas semanas. Espero que os sea de ayuda. Me gustaría también complementarlo con otro material en español que he encontrado en la red:

Para los que queráis ahondar en el tema (en inglés) os recomiendo el wiki del proyecto m2eclipse.

miércoles, diciembre 03, 2008

Seminario gratuito sobre Lean Software Development

Han extendido la fecha para registrarse en un seminario online titulado "Free Online Lean Training", organizado por Alan Shalloway (NetObjectives) y que se celebrará en seis sesiones virtuales de dos horas hasta mediados de Abril. Requiere un buen nivel de inglés y un cierto trabajo previo antes de cada sesión pero creo que merece la pena porque pretende aportar a los que ya practicamos (o creemos que practicamos) el agilismo, una base teórica-científica para que dejemos de guiarnos por creencias y pasemos a aplicar y poner a prueba principios que residen en una teoría: Lean (que me atrevo a traducir como "ajustada", en el sentido de "desarrollo o producción ajustado").

El proceso para registrarse es un poco laborioso (hay que registrarse en varios grupos de Yahoo! y además en el wiki que NetObjectives está preparando para dar soporte al curso) y además añadirse a alguno de los grupos de "asistentes" al curso (en España ya hay al menos dos grupos en el momento de escribir esto).

Gracias a Jorge Uriarte por ponernos en Agile Spain sobre la pista.