jueves, 31 de diciembre de 2009

Resumen del 2009

El último día del año siempre es un buen punto para echar un vistazo atrás y ver cómo nos ha ido en general. Este post pretende hacer eso, un pequeño resumen de cómo me ha ido el año profesionalmente.

En mi empresa hemos madurado mucho como equipo. Siempre intentando mejorar, por un lado hemos hecho uso de nuevas herramientas o intentado usar las antiguas de forma más eficiente. Por otro, en cuanto a las metodologías que seguimos en la forma de trabajar, hemos aplicado algunas nuevas, que han ido dando sus frutos. Y de una forma u otra, me gusta pensar que, aunque de forma muy humilde, en algo he podido contribuir a esta mejora. Y espero poder seguir aportando algo para que en el 2.010 sigamos esta línea.

En cuanto a la formación, además de intentar aprender siguiendo varios blogs, listas de correo, foros, etc… he realizado algunos cursos, de los que destacaría:
  • El de Core Spring (si vemos la foto, mirando desde donde está el profesor como referencia, a su izquierda estoy yo… el segundo de la fila, al ladito de Ben Corrie a ver si se me pegaba algo ;-) y acompañado a mi izquierda por dos compañeros de trabajo, José e Isabel).
  • Los tres cursos que ofrece actualmente la plataforma ScrumManager
  • El curso de TDD impartido por Carlos Ble
Este último curso probablemente marque un punto de inflexión en mi carrera. Hasta ahí, me había limitado a aprender de lo que otros ofrecen, pero me propuse cambiar mi filosofía. Por un lado, mi objetivo era contribuir, modestamente, en todo lo que pudiera. Si no nos limitamos a seguir el trabajo de otros, por muy poco que seamos capaces de aportar, con pequeños granitos de arena entre todos podríamos formar una gran montaña. Por otro lado, intenté ver la formación de una forma proactiva, sin limitarme a esperar a los cursos que me pudieran interesar, sino esforzarme para hacerlos realidad.

En ese sentido, he estado implicado en varios proyectos. El primero fue organizar el curso de TDD. Era un curso que me interesaba hacer y que en mi opinión valía la pena, así que me puse manos a la obra para que Carlos lo volviera a realizar.

Esta colaboración fue bastante productiva, primero porque en mi opinión el curso tuvo bastante éxito, y después porque hemos seguido trabajando juntos en otros proyectos. Por ejemplo, Carlos me brindó la oportunidad de participar como revisor de su libro, y luego la de participar en uno de los capítulos, donde me encargué de ordenar y añadir pinceladas propias a lo que ya había escrito Carlos. También participaré en la próxima edición del curso, ampliando un poco el temario.

En cuanto a ScrumManager, desde el principio estaba convencido de que era un marco de trabajo que tendría éxito. Así, no sólo realicé los cursos que ofrecían, accediendo a su directorio de profesionales certificados, sino que aprovechando la oportunidad que me han brindado, intentaré participar de forma activa en todo lo que pueda, como colaborador.

También gracias a Juan Palacio, uno de los fundadores de ScrumManager, se ha hecho realidad lo que empezó como una idea, una simple propuesta. En marzo se celebrará en Tenerife la primera edición en Canarias del curso Flexibilidad con Scrum. Cuando le hice la propuesta a Juan, deposité muchas ilusiones en este proyecto, y me alegra ver que gracias a él, y al esfuerzo que hemos hecho desde iExpertos, al final será posible poder ofrecer un curso de tal calidad en Canarias.

Me he dado cuenta de que el post ya es demasiado largo y no es mi intención aburrir. Creo que he repasado los logros más importantes, y podría concluir que ha sido un buen año para mí, espero poder continuar en esta línea. Aunque para finalizar, me gustaría mencionar otro proyecto en el que colaboro, intentando mostrar las ventajas de hacer actividades como esta. Ángel Medinilla está coordinado un proyecto para traducir el libro Kanban and Scrum - making the most of both. Esto hará que muchos puedan leer este libro en español, lo que produce una grata sensación, a los que participamos, de haber colaborado en algo que será beneficioso para muchos. Por otro lado, estamos teniendo la oportunidad de participar con varias personas de diferentes partes del mundo en un proyecto común, con la gestión ágil que está guiando Ángel. Desde luego, para los que quieran empezar a ver lo que es Scrum, por ejemplo, proyectos como este son una gran oportunidad, de aprender y a la vez aportar algo a otros.

Quiero agradecerte el que hayas pasado por aquí a leerme. Las seis visitas diarias que recibe actualmente este blog de media, no son suficientes como para ganarme la vida con él, pero me basta con que tú pases de vez en cuando para seguir animado a continuarlo ;-) Feliz año nuevo!!

miércoles, 16 de diciembre de 2009

La sorprendente ciencia de la motivación

Aprovechando que el curso que estaba haciendo en Open Knowledge Scrum estaba relacionado en cierto modo con mi entrada anterior, abrí un tema de discusión en el foro.

Lo bueno, a parte de poder aprender de los puntos de vista de otros profesionales, es que Raúl Uribe en su respuesta compartió con todos el enlace a un vídeo realmente interesante. Ya comentaba, en la entrada anterior, que creo que la clave del éxito, tanto personal como del equipo, es la motivación… y sobre esto trata la conferencia magistralmente expuesta por Dan Pink. Curiosamente, poniendo al día el Google Reader descubrí que en DosIdeas habían hecho una trascripción del vídeo.

Igualmente interesante son los artículos a los que Juan Palacio hace referencia en este hilo:
Personalmente creo que sí es importante crear un caldo de cultivo para la motivación en un equipo. Por ejemplo, en mi empresa se intenta asignar a cada miembro del equipo aquellas tareas con las que más a gusto se siente… hacer lo que te gusta, es una forma de mantener la motivación. Puede que esto no se vea como intentar motivar, sino como intentar no desmotivar… llamémoslo X, pero creo que acciones de este tipo sí que son fundamentales.

domingo, 13 de diciembre de 2009

Efecto Hawthorne

Hace algún tiempo leí un artículo que hablaba de un estudio realizado para evaluar el efecto que tiene sobre la productividad una serie de factores como el sueldo, los niveles de luz, el descanso, etc. Se comprobó que aumentando el nivel de intensidad luminosa en el entorno de los trabajadores, se aumentaba la productividad. Sorprendentemente, cuando se disminuyó la intensidad luminosa la productividad también aumentaba. Y lo mismo pasaba con prácticamente todos los aspectos que se fueron cambiando.

Al final del estudio, se concluyó que la auténtica causa de la mejoría en el desempeño es la sensación de los trabajadores de estar siendo atendidos por el propio estudio. A este efecto se le conoce como efecto Hawthorne, por haber sido realizado, entre 1927 y 1932, en la Hawthorne Plant de la Western Electric Company en Cicero, Illinois.

Seguí buscando información, porque me había parecido algo muy interesante, y me encontré con un análisis también llamativo: el estudio suponía un cambio en el día a día de los trabajadores. En general, la gente llega a aburrirse con un trabajo monótono. De hecho, hay empresas, como Fujitsu, que tienen como normal introducir algún aspecto experimental en todos sus proyectos, para romper así con la rutina de sus trabajadores.

Personalmente, creo que al final todo se puede resumir en un solo concepto: motivación. Muchas veces escuchamos: “se me ha pasado el día volando”. En mi caso, eso siempre pasa ante tareas que realmente me gustan, al afrontar nuevos retos, ante cambios en el equipo a favor de la mejora continua, etc. Estoy convencido de que, siguiendo la línea de una entrada anterior, convenientemente motivados un equipo puede conseguir grandes logros. Por tanto, debe ser un tema a tener en cuenta cómo motivar el equipo.

I can accept failure, everyone fails at something. But I can't accept not trying.
Michael Jordan

jueves, 10 de diciembre de 2009

JUnit 4.7: TemporaryFolder

Como comenté en una entrada anterior, he estado haciendo pruebas con la versión 4.7 de JUnit (aunque ya está disponible la 4.8, pero esta entrada lleva su tiempo en el tintero).

Otra funcionalidad que he "descubierto" y me parece muy interesante, la ofrece la clase TemporaryFolder. Con ella, podremos crear archivos y carpetas, con la ventaja de que estos se eliminarán automáticamente al finalizar el test.

Para muestra un botón:

package es.gmr.junit;

import java.io.File;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class TemporaryFolderTest {

@Rule
public TemporaryFolder temporaryFolder =
new TemporaryFolder();

@Test
public void deberiaPasar() throws Exception {
File newFile =
temporaryFolder.newFile("gangamuza.txt");

Assert.assertTrue("El fichero no existe",
newFile.exists());
}
}


En este caso, el test pasará sin problemas, ya que el fichero gangamuza.txt se habrá creado en un directorio temporal. (En mi caso, en C:\Documents and Settings\gregoriomr\Configuración local\Temp). Y al finalizar el test, tanto el directorio que se crea temporalmente para almacenar los ficheros, como el fichero gangamuza.txt se han eliminado.

Aunque durante la ejecución del test se produjera una excepción, los directorios y ficheros se eliminarán igualmente, con lo que nos evita tener que controlar muchas situaciones. También tiene un método similar, para crear directoiros: newFolder.

Por poner un pero, si cancelamos la ejecución del test antes de que finalice, evidentemente no se eliminarán los ficheros y directorios. El "problema" es que cada vez que se ejecuta crea un directorio temporal cuyo nombre sigue el patrón "junit" + 19 dígitos, que va cambiando en cada ejecución. Por lo que un directorio que se quede sin borrar, ya no será recuperado y no ha implementado forma de eliminarlo en la siguiente iteración.

sábado, 5 de diciembre de 2009

Eventos: Curso de ATDD+TDD en Tenerife (Enero 2010)

Ha pasado bastante tiempo desde que anuncié el último evento que consideré interesante. Pero la verdad es que ha faltado algo de tiempo, y también ha influido el hecho de que esté organizando yo mismo los próximos eventos que anunciaré. Pero antes de hacerlo, tengo el placer de anunciar el próximo curso de ATDD + TDD que impartirá Carlos Ble, la quinta edición ya. Curso para el que me ha brindado la oportunidad de colaborar ;)

Personalmente me alegro de haber contribuido a que se realizara la anterior edición en Tenerife, porque creo que es un curso recomendable y del que la gente a la que animé salió contenta (o por lo menos no me han dicho lo contrario Smile ). Espero que nos veamos por allí.

miércoles, 11 de noviembre de 2009

JUnit 4.7: @Rule

En mi empresa nos estamos tomando bastante enserio el tema de los tests, así que he dedicado algunos ratos libres a buscar herramientas que nos ayuden en esta tarea. Entre otras cosas, he leído sobre la versión 4.7 de JUnit, y descubrí una característica bastante interesante. Para presentarla, voy a seguir un ejemplo que probablemente haga que se les ponga los pelos de punta a muchos, pero creo que es un ejemplo bastante sencillo y claro.

Supongamos que tenemos una batería de test, y de alguna forma queremos hacer que ciertos tests se ejecuten los días pares y el resto los impares. Lo primero es definir una nueva anotación para poder anotar en los test si se deben ejecutar los días pares o los impares.

package es.gmr.junit;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DateAnnotation {
  boolean ejecutarDiasPares() default true;
}


Esta nueva funcionalidad de JUnit, requiere que creemos una clase que implemente la interfaz MethodRule. Esta clase interceptará las llamadas a los métodos del test y realizará las acciones convenientes, que en nuestro caso es ejecutar el método si se cumple la condición adecuada (día par o impar).

package es.gmr.junit;

import java.util.Calendar;

import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;

public class ManejadorEjecucion implements MethodRule {
  @Override
  public Statement apply(Statement stament, final FrameworkMethod frameworkMethod, final Object obj) {
    return new Statement() {
        @Override
public void evaluate() throws Throwable {
DateAnnotation dateAnnotation = frameworkMethod.getAnnotation(DateAnnotation.class);
if (dateAnnotation == null) {
frameworkMethod.invokeExplosively(obj);
else {
Calendar calendar = Calendar.getInstance();
boolean hoyEsPar = calendar.get(Calendar.DAY_OF_MONTH== 0;
boolean ejecutarDiasPares = dateAnnotation.ejecutarDiasPares();

if hoyEsPar && ejecutarDiasPares || !hoyEsPar && !ejecutarDiasPares){
frameworkMethod.invokeExplosively(obj);
}
}
            }
        };
}
}



Por último, en la clase donde se implementan los test, debe haber declarada una variable pública del tipo de la clase que hemos implementado en el punto anterior (ManejadorEjecucion) y anotada con @Rule.

package es.gmr.junit;

import org.junit.Rule;
import org.junit.Test;

public class TestPruebas {

  @Rule
  public ManejadorEjecucion manejadorEjecucion = 
    new ManejadorEjecucion();

  @Test
  @DateAnnotation(ejecutarDiasPares = true)
  public void diasParesTest(){
    System.out.println("Hoy es par");
    // ...
  }

  @Test
  @DateAnnotation(ejecutarDiasPares = false)
  public void diasImparesTest(){
    System.out.println("Hoy es impar");
    //...
  }
}



Al ejecutar, veremos que hoy sólo se lanzará el test diasImparesTest.

Como comentaba al principio, esto es sólo un ejemplo para "jugar" con esta anotación. He estado haciendo pruebas para crear mocks, o probar concurrencia, pero son ejemplos que seguro que se llevarían muchas más líneas.

martes, 3 de noviembre de 2009

¿Cómo hacerlo posible?

Desde que empecé a interesarme por las metodologías ágiles, he leído varias veces que la gente habla de un problema recurrente: el rechazo al cambio.

Para poder entrar en estas metodologías se requiere un cambio importante, ya que debemos modificar la forma de pensar, organizarnos, realizar las tareas, enfocar los objetivos, etc. Todo esto sumado a un considerable esfuerzo orienado a la formación, ya que se hacen imprescindibles ciertas herramientas y se deben aplicar nuevas metodologías de programación.

Personalmente creo que el primer error en este camino es preguntarnos si es posible el cambio en nuestro equipo. Puede que lleve poco tiempo en el negocio como para que mi forma de pensar se haya amoldado a la realidad, y por eso yo creo que la respuesta a esta pregunta es SÍ, por lo que sobra.

Nos solemos encontrar con el típico problema del tiempo, pero debemos ser realistas, y pensar que nuestros días tienen las mismas horas que los del resto de las empresas, sobre todo aquellas situadas en países en los que, con bastante ventaja sobre nosotros, estas metodologías se han impuesto con excelentes resultados. No se trata de experimentar, estamos hablando de algo que ha demostrado su valor. Por todo esto, cada vez que debamos plantear un cambio que nos haga mejorar, creo que se debería cambiar la pregunta ¿es posible? por esta otra: ¿cómo lo hago posible?.

Si crees que esto que he dicho no tiene mucho sentido, piensa por un momento si como usuario de un metro, podrías cambiar la forma de pensar del resto de usuarios para que en vez de saturar las escaleras mecánicas prefirieran subir y bajar caminando. O hacer cambiar la mentalidad de los usuarios de un parque, para que hagan uso de las papeleras... ¿Parece imposible verdad? La gente de "The fun Theory", una iniciativa que recomiendo seguir, probablemente no se preguntaron si era posible, simplemente pensaron en cómo hacerlo.




De vuelta...

Tras varias semanas moviditas, ya casi puedo dar por finalizado uno de los proyectos más importantes a los que me he enfrentado: comprar mi propio piso y mudarme. Mi novia y yo no pensábamos que conllevara tanto trabajo. Nos decidimos por un piso que estaba completamente vacío, así que tuvimos que invertir bastante tiempo en comprar los electrodomésticos, luces, muebles, camas, etc., etc., etc.

En un equipo de dos personas, ambos pasamos por todos los roles: electricistas, albañiles, pintores, carpinteros, ... ;) Y sumando, al final nos damos cuenta de que hemos invertido muchas horas.

En cuanto al papeleo, es otro tema que se llevó su tiempo. Probablemente haya un arbolito menos por nuestra culpa :S

Pero ya CASI todo está en su sitio, y por fin las cosas volverán a la normalidad. Actualizar el blog es una de tantas tareas que he tenido que dejar de lado, pero espero volver a retomarla. Intentaré que el contenido vaya mejorando, y ser constante. De momento, he cambiado la imagen (etapa nueva, look nuevo) y por lo menos ya hay una referencia a quién escribe "About", que ya han sido varias las personas que me han comentado que debería estar. Aunque me queda como tarea pendiente actualizar mi CV, ya que según lo que consta en él, todavía trabajo en la empresa que dejé hace más de un año :S

jueves, 15 de octubre de 2009

Eventos: Integración Continua - Buenas Prácticas

Ya he publicado algunos eventos, pero hay lo hago con especial ilusión, ya que soy uno de las personas que están implicadas en su organización. Justo ahora acabo de publicarlo en iExpertos.com, se trata de una charla sobre buenas prácticas en la integración continua impartida por José Manuel Beas aquí, en Tenerife, el 7 de Noviembre de 10:30 a 14:30.

Sigo creyendo que con convicción podemos conseguir una formación de calidad entre todos, sin tener que ir a por ella a otros lugares. Espero que se animen y aprevechen la que considero una gran oportunidad, ya que José Manuel Beas sin duda tiene mucho que aportar.

jueves, 24 de septiembre de 2009

Eventos: Metodologías ágiles && Scrum && ISTQB

En la entrada anterior comenté que una de las opciones para realizar un curso de Scrum era el portal ScrumManager. Ya he terminado el curso, y debo decir, ahora sí con criterio, que merece la pena realizarlo. El formato me ha parecido muy cómodo (lecciones en el portal, documentación, una presentación, enlaces a material extra, ...) y el contenido era muy claro y resultaba fácil asimilar los conceptos. Además, las dudas que pudieran surgir eran rápidamente resueltas en el foro. Del chat no puedo opinar porque no tuve la suerte de poder asistir a ninguna de las dos tutorías.

Para pasar el examen basta con seguir las lecciones (al menos desde mi punto de vista, aunque hay gente que no lo superó). Yo no tuve mucho tiempo para dedicarle al curso, y no tuve problema en superarlo con un 89% teniendo pendiente aún revisar el pdf y la presentación del curso (me queda el resquemor de no haber sacado un par de horas para mirar con más calma lo que me faltaba y haber acertado las preguntas que me faltaron :S ).

Además, personalmente apuesto por esta plataforma: la formación es gratuita (y de calidad), por lo que las certificaciones no son sólo un negocio. Además, cada curso te otorga un número determinado de puntos de acreditación, que pueden indicar la cantidad de conocimiento que has ido adquiriendo (no basta con hacer el curso, debes superar una prueba), así como tu interés por aprender constantemente. Ofrecen un directorio de profesionales certificados. Y es un punto de encuentro para compartir conocimientos y seguir aprendiendo.

Actualmente está abierta la matrícula para el Curso de Introducción Scrum Manager, que empezará el 1 de Octubre. Y el 28 de Septiembre se volverá a abrir el plazo para matricularse en el curso Scrum.

Del 6 al 8 de Octubre se impartirá el curso: Certificación Ingeniero de Pruebas ISTQB en Madrid, pudiendo realizar el examen para obtener la certificación el día 8. Creo que es una opción muy interesante (de hecho me han avisado porque ya me interesé por él hace tiempo), ya que se imparte en español y es un tema que me interesa mucho, pero el precio (1400 euros el curso más 200 el examen) hacen que de momento lo tenga que dejar pasar... igual alguno de ustedes tiene más suerte ;). Yo por ahora, tengo en mi pila de tareas pendiente el mirar la documentación que te prepara para el examen (en inglés).

Otro evento en el que me encantaría estar (aunque no va a poder ser) es el Agile Open Spain, que se celebrará en Madrid los días 23 y 24 de octubre. En este enlace se puede ver los temas que se han ido proponiendo, o proponer algún tema nuevo. Los nombres de las personas que ya han hecho propuestas ya son familiares a los que intentamos aprender algo de este mundillo, y sin duda será un gran evento.

P.D.: Para que los conceptos estén siempre presentes un fondo de pantalla ... algo friki ;)

miércoles, 9 de septiembre de 2009

Eventos: Scrum

Supongo que a muchos les habrá pasado como a mí: enterarse de un curso cuando ya ha acabado, o no quedan plazas. Mi idea es aportar mi humilde granito de arena, indicando los eventos que me puedan parecer interesantes, para compartirlos con todos ustedes, por si fuera de su interés. Igualmente, cualquier noticia saben que será bien recibida ;)

En esta entrada pondré tres alternativas para los que quieran aprender un poco más de Scrum (a través de cursos claro):

  1. La primera opción es gratuita y online. El curso lo imparte Claudia Ruata, y aunque empezó hace poco, lo que he visto ya es suficiente para decir que está muy bien y el contenido es realmente bueno, igual que la plataforma usada. Ya no es posible matricularse para esta edición, pero irán saliendo nuevas convocatorias.
  2. Si se prefiere un curso presencial, se tiene esta otra opción. Está organizado por EBTecnos y se impartirá el 5 y 6 de noviembre en Málaga (de 9:30 a 18:30 con una hora para almorzar), y el coste es de sólo 290 euros (260 para los socios). En este caso el profesor es Ángel Medinilla, del que soy un fiel seguidor y creo que asistir a un curso impartido por él sería una gran oportunidad.
  3. La tercera opción sería en Madrid el 12 y 13 de noviembre. En este caso el coste es de 464 euros (incluidos los dos almuerzos). El horario y el profesor son los mismos que en el caso anterior.
Los que estén interesados en las opciones presenciales, si quieren pueden ponerse en contacto conmigo, ya que para el curso de Madrid podrían conseguir un descuento de hasta 60 euros (teniendo en cuenta que hay que pagar el curso, los billetes y la estancia, no está nada mal), y para el curso de Málaga, igualmente si hay gente interesada se podría buscar la forma de ahorrar gastos.

P.D.: Para los que no lean a Ángel, dejo un enlace a una de las entradas de su blog que me ha parecido muy buena ;)

lunes, 24 de agosto de 2009

Hibernate: Usando un constructor en las sentencias HQL

De vuelta a la "rutina" y con las pilas cargadas tras las vacaciones, voy a escribir una nota que tenía pendiente hace tiempo.

Se trata de la posibilidad de usar un constructor dentro de una sentencia HQL. Por ejemplo (y me vuelvo a mojar con los ejemplos aunque no suelo elegir los más adecuados) puede que en nuestra arquitectura tengamos beans para gestionar las vistas, y que uno de estos beans maneje datos de varias clases del modelo. Podría ser interesante en determinadas ocasiones, que en las consultas podamos obtener directamente instancias de este bean, para no tener que obtener una instancia del modelo con cierto número de campos y relaciones, cuando sólo nos interesa unos pocos datos.

La forma de hacerlo es realmente simple, basta con añadir el new a la sentencia, e indicar los parámetros que le pasamos al constructor. Un ejemplo simple sería (no describo la clase Usuario ya que es sencillo imaginarla):

select new DatosUsuario(usr.id, usr.nombre, usr.direccion.codigoPostal)
from Usuario usr ...

martes, 4 de agosto de 2009

Ágil: eventos

Esta entrada en realidad es sólo una cuña publicitaria, intentando aportar mi humilde granito de arena para promover el desarrollo ágil.

Hace poco se dieron en la Tenerife Lan Party 2K9 dos charlas relacionadas con estos temas, una dada por José Manuel Beas ("Cómo dar los primeros pasos en el agilismo") y otra por Carlos Ble ("Los principios ágiles"). El caso es que tras las charlas, algunos fuimos a tomar algo y seguir hablando, y ahí se sacaron unas fotos. José Manuel me ha pasado el enlace a la foto (en la que él precisamente no sale), que es este. La idea de publicar esta foto, es demostrar que por estos lares (Tenerife) hay bastante gente interesada en estos temas, y creo que la idea del grupo Agil Canarias puede ser una realidad. Ahora muchos estamos de vacaciones (esta entrada se cocina en La Gomera ;) ) pero en septiembre espero animar a Carlos para que se organice otro encuentro. Personalmente, la forma de funcionar del grupo de Barcelona me parece muy buena, y a ellos le está funcionando muy bien, así que podríamos emularlos. De todas formas, el primer paso es apuntarse en la lista de Agil Spain, si todavía no lo has hecho y te interesa el tema.

Aprovechando la entrada "publicitaria", decirles que a finales de agosto habrá un curso de Scrum en Valencia. En este enlace está toda la información. El curso lo dará Juan Palacio, y la verdad es que el precio me parece bastante interesante (incluye la certificación). Si te animas, probablemente nos veamos por allí ;)

jueves, 30 de julio de 2009

Parametrizar un test JUnit

Supongamos que queremos ejecutar un test varias veces con distintos valores. Una opción podría ser algo como lo siguiente:

package es.gmr.test;

import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import junit.framework.Assert;

public class TestParametrizar {

private List<Integer> datos;

@Before
public void setUp() throws Exception {
this.datos = Arrays.asList(2, 4, 5, 6);
}

@Test
public void test() {
for (final Integer num : this.datos) {
testEsPar(num);
}
}

public void testEsPar(final Integer x){
Assert.assertEquals(x + " no es un número par", 0, (x % 2));
}
}

Lo malo de esta opción, es que si la ejecutamos (desde Eclipse por ejemplo) veremos lo siguiente:

Es decir, si uno de los valores del listado no supera el test, no se continuará con los siguientes. Para evitar esto, JUnit 4 nos permite generar parámetros para lanzar varias veces un test con dichos parámetros. Para ello, primero deberemos anotar nuestra clase con @RunWith(Parameterized.class). También tendremos que tener un método anotado con @Parameters, que será el encargado de generar la lista de parámetros. Por último, la clase debe tener un constructor con un argumento del tipo de los parámetros, ya que cada vez que se lance un test, se llamará a este constructor para inicializar el parámetro. Con todo esto, obtenemos el siguiente test:

package es.gmr.test;

import java.util.ArrayList;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import junit.framework.Assert;

@RunWith(Parameterized.class)
public class TestParametrizar {

private final Integer num;

public TestParametrizar(final Integer x) {
this.num = x;
}

@Parameters
public static Collection<Integer[]> init() throws Exception {
final Collection<Integer[]> datos = new ArrayList<Integer[]>();
datos.add(new Integer[] {2});
datos.add(new Integer[] {4});
datos.add(new Integer[] {5});
datos.add(new Integer[] {6});
return datos;
}

@Test
public void test() {
Assert.assertEquals(this.num + " no es un número par", 0, (this.num % 2));
}
}

Ahora, se lanzarán tantos tests como parámetros hayamos definido, y el resultado sería algo así:

Vemos que cada parámetro hace que se ejecute un test, y aunque con uno de ellos el test falle, se sigue tratando lo siguientes.

domingo, 26 de julio de 2009

Ser lider (I)

Ya hace bastante que no dedico un rato a escribir algo por aquí, y con varios temas en mente a la espera de tiempo, hoy me voy a poner a ello.

En esta entrada simplemente voy a hacer referencia a dos artículos que a mí personalmente me han hecho reflexionar bastante. El primero es de José Manuel Beas, punto de referencia obligado para todos los que intentamos saber algo sobre metodologías ágiles. Al final del artículo "Liderar mediante el ejemplo" (que recomiendo leer) deja la siguiente reflexión:

Si en tu día a día crees que los demás deberían hacer las cosas de otra manera y estás convencido de que las cosas no se pueden cambiar, quizás podrías intentar seguir el ejemplo de Martin Fowler y liderar mediante el ejemplo

Hay que ser realmente bueno para poder cambiar la filosofía de un equipo con un simple gesto. A mí me hizo pensar como personas como Fowler, pueden hacer cosas grandes con gestos pequeños. Aunque luego José Manuel me contaba (cuando le comenté que iba a hacer referencia a su artículo, hace ya bastante tiempo :S ) que la historia no era realmente así (luego lo explicaba aquí y aquí) yo me sigo quedando con la idea principal, con el hecho de que si creemos realmente en algo y recorremos con paso firme ese camino puede que al final nos acaben siguiendo.

Y si se leen el artículo, decir que la lectura "Reluctant Leader, Reluctant Follower" que recomienda José Manuel es realmente interesante. Yo ya me he dejado una frase anotada en mi lista de citas:

"... like a river—adapting to the rocks but always flowing down hill"

El otro artículo puede ser algo más polémico. Hace más o menos una semana, Leonardo De Seta escribió un artículo titulado "Necesitamos matar a las vacas sagradas". No quiero ni imaginar lo difícil que debe ser para alguien, cuestionar la utilidad de un miembro de su equipo dentro del mismo. Imagina que te toca a ti, y le debes decir a un compañero al que conoces hace años que no está aportando gran cosa al equipo y debes prescindir de él; o se lo debes decir a alguien que te saca años de experiencia, o que lleva más tiempo que tú en la empresa/organización, ... Como dice el autor:

"Pero no es fácil sacar a la luz a nuestras propias vacas sagradas. Suelen ser sagradas por algún motivo (aunque no suele ser muy bueno), y quienes se atrevan a señalar a esta vaca seguramente se encontrarán con rechazo de quienes intentan proteger el pasado de la institución."

En el artículo, hay una frase que me ha gustado bastante, y creo que esta filosofía nos ayudaría/empujaría a todos a mejorar cada día:

"Las organizaciones tiene que creer que si cualquier valor, creencia, proceso, política o mantra corporativo es lo suficientemente valioso para tenerlo, también debería ser lo suficientemente fuerte como para ser desafiado"

martes, 2 de junio de 2009

Java: lambdaj

Hace unos días, hablando con un amigo, digamos ... Federico, me decía que hace tiempo que no pongo nada en el blog. Y tiene razón, así que aprovechando que he estado jungando con la librería lambdaj, voy a poner las pruebitas que he hecho.

Lambaj emula los lenguajes funcionales, permitiendo tratar colecciones de una forma más sencilla, intentando reducir el número de líneas de código necesarias para operar sobre ellas.

Antes de empezar, comentar que si miramos el código mostrado en los ejemplos que acompañan a la documentación de la librería, vemos que se llaman directamente funciones como asList, forEach, ... Evidentemente, si simplemente copiamos y pegamos este código en nuestro proyecto (tras haber incluido la librería), no compilará. Lo que se ha hecho en el ejemplo es importar de forma estática los métodos estáticos de ciertas clases. Es decir, si lo hacemos de la forma más habitual, tendría que hacer algo como:


import java.util.Arrays;

...

Arrays.asList(...)



Pero si hacemos uso de los static imports, que permiten acceso a los miembros estáticos extendiendo el tipo. Es decir, todos los campos estáticos, métodos, etc. estarán disponibles para nuestra Clase. Por ejemplo, podríamos hacer algo como:


import static java.util.Arrays.asList;

...

asList(...)



Bien, aclarado esto, vamos a ver algunos ejemplos. Para realizar las pruebas, usé la siguiente clase:


package es.gmr.modelo;

public class Coche {

private Integer cilindrada = null;
private Integer anyo = null;
private boolean disponible = false;

// --- Constructor

public Coche(){}

public Coche(Integer cilindrada, Integer anyo) {
this.cilindrada = cilindrada;
this.anyo = anyo;
}

// --- getters && setters

public Integer getCilindrada() {
return cilindrada;
}

public void setCilindrada(Integer cilindrada) {
this.cilindrada = cilindrada;
}

public Integer getAnyo() {
return anyo;
}

public void setAnyo(Integer anyo) {
this.anyo = anyo;
}

public boolean isDisponible() {
return disponible;
}

public void setDisponible(boolean disponible) {
this.disponible = disponible;
}
}


Y ahí va el primer ejemplo: invocar un método sobre todos los objetos de una lista


package es.gmr.pruebas;

import static ch.lambdaj.Lambda.forEach;
import static java.util.Arrays.asList;

import java.util.List;

import es.gmr.modelo.Coche;

public class PruebaLambdaj {

public static void main(String[] args) {
final List listaCoches = asList(new Coche(1600, 2000),
new Coche(1400, 2002), new Coche(2000, 2005));

forEach(listaCoches).setDisponible(true);

for (final Coche coche : listaCoches){
System.out.println("¿Está disponible? " + (coche.isDisponible() ? "SI" : "NO"));
}
}
}


Algo importante a tener en cuenta, que en la documentación no he visto, es que si la clase Coche no tuviera el constructor sin parámetros, tendríamos un error en tiempo de ejecución.

En el segundo ejemplo se filtrará la lista, obteniendo sólo los coches matriculados después del año 2000. La librería trae algunos filtros, pero lo interesante es que podemos implementar nuestros propios filtros, con la librería Hamcrest


package es.gmr.pruebas;

import static ch.lambdaj.Lambda.filter;
import static java.util.Arrays.asList;

import java.util.List;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.matchers.TypeSafeMatcher;

import es.gmr.modelo.Coche;

public class PruebaLambdaj {

public static void main(String[] args) {
final List listaCoches = asList(new Coche(1600, 2000),
new Coche(1400, 2002), new Coche(2000, 2005));

final Matcher nuevo = new TypeSafeMatcher() {
@Override
public boolean matchesSafely(Coche item) {
return item.getAnyo() > 2000;
}

public void describeTo(Description description) {
description.appendText("nuevo()");
}
};

final List listaFiltrada = filter(nuevo, listaCoches);

for (final Coche coche : listaFiltrada){
System.out.println("Año matriculación: " + coche.getAnyo());
}
}
}


Por último, vemos dos formas de ordenar la lista, con un Comparator y sin él:


package es.gmr.pruebas;

import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.Lambda.sort;

import static java.util.Arrays.asList;

import java.util.Comparator;

import java.util.List;

import es.gmr.modelo.Coche;

public class PruebaLambdaj {

public static void main(String[] args) {
final List listaCoches = asList(new Coche(1600, 2000),
new Coche(1400, 2002), new Coche(2000, 2005));

final Comparator comparator = new Comparator(){
public int compare(Coche c1, Coche c2) {
return -1 * c1.getCilindrada().compareTo(c2.getCilindrada());
}
};

final List listaOrdenadaA = sort(listaCoches, on(Coche.class).getCilindrada());
final List listaOrdenadaB = sort(listaCoches, on(Coche.class), comparator);

for (final Coche coche : listaOrdenadaA){
System.out.println("Cilindrada: " + coche.getCilindrada());
}

System.out.println("---");

for (final Coche coche : listaOrdenadaB){
System.out.println("Cilindrada: " + coche.getCilindrada());
}
}
}


Hay muchas más opciones... pero para muestra un botón ;)

martes, 19 de mayo de 2009

Eclipse: Detail formatters

Todos los que nos hemos peleado con el depurador de Eclipse (sin el que no sería nadie) nos habremos fijado en la poca información que se muestra en la vista Variables a primera instancia. Por ejemplo, si tenemos una clase Usuario como esta:

Y estamos depurando el siguiente "programa":

La información que nos muestra la vista (si no entramos a desglosar la variable que nos interesa, y no se ha implementado el método toString) nos dice bastante poco.


Para evitar esto, Eclipse nos permite usar una expresión alternativa al toString. Para ello, en tiempo de depuración, pulsamos con el botón derecho sobre la variable que nos interese y seleccionamos New Detail Formater


El editor nos permitirá escribir expresiones, haciendo uso de los métodos y atributos de la clase seleccionada (Usuario), y ofreciendo la posibilidad de autocompletar el texto al escribir. Si escribimos algo como lo siguiente:


Ahora la información mostrada en la vista Variables nos dice mucho más.

Si además queremos que se muestre en la columna Value, accedemos a Window - Preferences - Java - Debug - Detail Formatters y seleccionamos la casilla "As the label for variables ..."


Con lo que ahora la vista quedaría así:

miércoles, 13 de mayo de 2009

Hibernate: @Embeddable

Supongamos que estamos ante la siguiente situación: varias clases de nuestro modelo comparten ciertos atributos, y por las razones que sean, no es posible/conveniente plantearlo con herencia. Por ejemplo, varias clases almacenan un peso y una altura. Podríamos tener una clase Medidas, que centralizara estos campos, e indicar que será "embebida":


package es.gmr.pruebas;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class Medidas {
   @Column(name="PESO")
   Integer peso;
   @Column(name="ALTURA")
    Integer altura;

    ...

}


Ahora, cada clase que necesite estos campos, sólo tendrá que añadir una instancia de Medidas y ya tendrá incluida las anotaciones para peso y altura como si fueran atributos propios.

¿Pero qué pasa si para una determinada clase, las columnas de la tabla correspondiente en base de datos no se llaman PESO y ALTURA?. ¿O si una clase en concreto necesita dos instancias de Medidas? En esos casos podríamos sobrescribir el mapeo, con la anotación @AttributeOverrides. Un ejemplo:


package es.gmr.pruebas;

import javax.persistence.*;

@Entity
@Table(name = "MY_CLASE")
public class MyClase {
    // Usará los valores dados por defecto en el mapeo
    Medidas unaMedida;

    @Embedded
    @AttributeOverrides( {
       @AttributeOverride(name="peso", column =
          @Column(name="OTRO_PESO") ),
       @AttributeOverride(name="altura", column =
          @Column(name="OTRA_ALTURA") )
    } )
    IntegerMedidas otraMedida;

    ...
}

lunes, 27 de abril de 2009

Property Editor

Hace ya bastantes días que no escribo nada aquí, pero hoy tengo ingredientes suficientes para hacer un nuevo post: tiempo y un tema. Aunque es el primer día del curso, ya tengo cositas para mantener el blog activo, así que espero que junto a otros temas que tengo pendientes de escribir, pueda mantener esto vivo.

Hasta ahora, cuando definía un bean en Spring, para asignar valores a sus atributos o hacía referencia a otro bean, o a un tipo "simple".


¿Pero qué ocurre si var02 no fuera de tipo Integer, String, List, ... sino que se trata de una clase de nuestro dominio? Para esto, Spring nos ofrece los Property Editor. Para ver su funcionamiento, veamos un ejemplo. Supongamos que tenemos la siguiente clase:

Y que ahora, el atributo var02 de MiClase será una instancia de Usuario. La declaración anterior, nos daría un error, ya que el setVar02 espera un parámetro de tipo Usuario.

El primer paso que debemos dar para solucionar esta situación, es implementar una clase que a partir de una cadena de texto sea capaz de crear una instancia de Usuario, y a la vez, a partir de una instancia de Usuario nos devuelva una cadena de texto, para que se encargue de "traducir" lo que hayamos configurado. Esta clase debe extender a java.beans.PropertyEditorSupport y sobreescribir los métodos:
  1. public void setAsText(String text) throws IllegalArgumentException
  2. public String getAsText()
Para nuestro caso, un ejemplo puede ser la siguiente clase:


El siguiente paso es indicarle a Spring que queremos añadir nuestro propio Property Editors:

Y ahora si que podremos definir miBean, haciendo que var02 se inicialice con una instancia de Usuario, en la que nombre contendrá la cadena "Gregorio" y apellido la cadena "Mena".