La Coctelera

foo-bar

Un blog sobre esto y lo otro

15 Septiembre 2008

Uso del plugin Cobertura dentro de un proyecto multi-módulo en Maven 2

Situación inicial: supongamos la siguiente estructura de proyecto

./project
|-pom.xml
|-project-api
| |- pom.xml
|-project-impl-1
| |- pom.xml
|-project-tests
| |- pom.xml
  • En este proyecto los tests correspondientes a project-api se encuentran en el módulo project-tests, lo cuál está considerado como una buena práctica. Este módulo únicamente contiene los tests, es decir, las carpetas ./src/main/java, ./src/main/resources, etc. están vacías.
  • El plugin de Cobertura se encuentra configurado correctamente.

El problema: los tests de project-tests se ejecutan correctamente, si bien no se está obteniendo la cobertura de los mismos, el plugin de Cobertura solamente es capaz de dar la cobertura del código dentro de un mismo módulo.

Análisis: Cobertura sólo instrumenta las clases dentro de un mismo módulo, dejándolas en el directorio ./target/generated-classes/cobertura, para luego usarlas al calcular la cobertura del código. Buscando la manera de solucionar todo esto, la única referencia la he encontrado en la documentación de Seam, el framework open source de la gente de Hibernate y compañía (de hecho este post ha sido fusiladotiene exactamente la misma estructura que la página referenciada).

La solución que se propone en el enlace anterior pasa por incrustar un script de Ant que copia las clases instrumentadas de un módulo a otro, ejecuta el plugin de Cobertura y deja los resultados en el proyecto inicial. La solución que se va a exponer deja los resultados del test de cobertura en el proyecto correspondiente a los tests (lo cual me parece más correcto), es más concisa y más a la Maven way.

Solución: el plugin de Cobertura se ejecuta al lanzar el site del proyecto, por lo que vamos a aprovechar para montar un jar con las clases instrumentadas y subirlo a nuestro repositorio local (es decir, ejecutar un install y no un deploy, ya que no nos interesará que este nuevo .jar esté en nuestro repositorio público). Enlazaremos la ejecución de los plugins a la fase de site, que es cuándo se generan las clases instrumentadas de Cobertura.

Así pues, en el pom.xml del módulo project-impl-1 incluimos las siguientes entradas:

[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution><!-- jar con las clases instrumentadas por cobertura -->
<id>cobertura-jar</id>
<phase>site</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>cobertura</classifier>
<classesDirectory>${basedir}/target/generated-classes/cobertura</classesDirectory>
</configuration>
</execution>
</executions>
</plugin>

<plugin><!-- instalamos el jar en el repositorio local -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>cobertura-install</id>
<phase>site</phase>
<goals>
<goal>install</goal>
</goals>
<configuration>
<classifier>cobertura</classifier>
</configuration>
</execution>
</executions>
</plugin>
[...]
</plugins>
[...]
</build>
[...]

La clave está en el elemento classifier, que nos permite generar el jar que queremos añadiéndole el sufijo que le indicamos, lo cual nos permite generar varios .jars distintos dentro de un mismo proyecto Maven 2.

En el módulo de tests, configuramos el plugin de Cobertura para que utilice el .jar con las clases instrumentadas (esto es, lo añadimos como dependencia al plugin) y sobreescribimos el elemento sourceDirectory. Este último paso es necesario debido a que Cobertura necesita tener acceso a los fuentes para generar el informe de cobertura del código. En fin, que en el pom.xml correspondiente a project-tests incluimos las siguientes entradas:

<build>
<sourceDirectory>${basedir}/../project-impl-1/src/main/java</sourceDirectory>

<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<dependencies>
<dependency><!-- cobertura necesita tener las clases instrumentadas en el classpath -->
<groupId>atlas.dpugd</groupId>
<artifactId>project-impl-1</artifactId>
<version>1.0.0</version><!-- se sobreentiende que esta versión es la generada en el pom de <tt>project-impl-1</tt> -->
<classifier>cobertura</classifier>
</dependency>
</dependencies>
</plugin>
</plugins>

</build>

et le vôila, ya hemos conseguido la cobertura de los tests dentro de un proyecto multi-módulo de Maven 2 y lo más importante, integrándolo de un modo transparente dentro del proceso de generación de la documentación, sin tener que efectuar ningún paso intermedio adicional.

servido por foobar 3 comentarios compártelo

3 comentarios · Escribe aquí tu comentario

Anjani

Anjani dijo

Can you convert the explanation into english please.

Thanks in Advance,
Anjani

11 Febrero 2009 | 09:50 AM

Coen

Coen dijo

Ola!

great post.

Can you also add a pom.xml/example for multiple source directories? I have 5 code directories I want to add, but I can only add one to a build.

Thanks!
Coenos

8 Junio 2009 | 06:27 PM

foobar

foobar dijo

@Anjani: I should do it, however I don't have too much time these days (4 months to answer!)... but translating the article is on the TO-DO list.

@Coen: Maven 2, by default, does not allow more than one source directory per project. You can take a look to Build Helper Maven plugin, specifically to the add-source goal, which should come in handy.

9 Junio 2009 | 11:51 PM

Escribe tu comentario


Sobre mí

    Como se puede observar en esta foto, visto chistera, tengo monóculo, fumo puros y, probablemente, bebo cerveza.

    Para regalarme jamones, ofrecerme dinero o simplemente mandarme unas líneas, nada como usar el formulario de contacto.

Tag de sabiduría

Estadísticas




    spam posion

Fotos

foobar todavía no ha subido ninguna foto.

¡Anímale a hacerlo!

Buscar

suscríbete

Selecciona el agregador que utilices para suscribirte a este blog (también puedes obtener la URL de los feeds):

¿Qué es esto?

Crea tu blog gratis en La Coctelera