Maven multimodule y attached tests

En mi vuelta al mundo java, una de las cosas que he retomado es el utilizar de forma habitual proyectos maven multimodule, lo que facilita controlar mejor las dependencias y segregar el empaquetado.

Así podemos hacer separación de responsabilidades dependiendo de nuestros intereses. Por ejemplo, algunos escenarios por los que podríamos querer usarlos serían:

  • Partir en vertical una aplicación por temas funcionales.
  • Publicar de forma independiente una librería que sale de nuestro proyecto para reutilización de terceros.
  • Partición horizontal de una aplicación o servicio: core, diferentes APIs, persistencia…

El último escenario es el que he empezado a utilizar de forma habitual, separando el modelo de dominio de los detalles de implementación de infraestructura y mecanismo de entrega. Así evitamos en lo posible tener dependencias en los módulos core a través aproximaciones de arquitectura hexagonal.

El problema que surge frente a tenerlo en un sólo módulo maven es lo respectivo a la duplicidad en cuanto código de test.

Un ejemplo es reutilizar algunos helpers de tests. En nuestro caso, implementaciones de patrones que nos facilitan la mantenibilidad como el builder o el object mother. Tener objetos fake (puede que incluso algún dummy) para usarlos como colaboradores y desacoplarnos de las implementaciones reales. O tener especificaciones en lenguaje gherkin desde el módulo core, para que sean compartidos con los módulos responsables de tener implementados los tests de cucumber.

Gracias a Maven JAR Plugin podemos evitar estas duplicidades, ya que nos permite empaquetar los tests de un módulo en un JAR sin tener que mezclarlo en los paquetes de código de producción.

Por ejemplo, para compartir los tests del módulo core deberíamos configurar la construcción del JAR de test de este modo:

<project>
  ...
  <build>
   <plugins>
     ...
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>3.1.1</version>
       <executions>
         <execution>
           <goals>
             <goal>test-jar</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
   </plugins>
  </build>
</project>

Mientras que en los módulos que queramos usar el JAR de los tests deberemos incluir la dependencia así:

<project>
  <dependencies>
  ...
    <dependency>
      <groupId>com.danilat.killerapp</groupId>
      <artifactId>core</artifactId>
      <version>X.Y.Z</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Con esto ya podemos reutilizar los helpers de test o especificaciones de cucumber en diferentes módulos de maven.