java - shadedartifactattached - shade shade maven
¿Cómo incluir clases de prueba en Jar creadas por maven-shade-plugin? (2)
Estoy tratando de empaquetar mis clases de prueba en un jar ejecutable con dependencias usando Maven, pero estoy luchando por hacerlo bien.
Este es mi pom.xml hasta ahora:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.c0deattack</groupId>
<artifactId>executable-tests</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>executable-tests</name>
<dependencies>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.21.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>cucumber-tests</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cucumber.cli.Main</mainClass>
</transformer>
</transformers>
<artifactSet>
<includes>
<include>info.cukes:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.c0deattack</groupId>
<artifactId>executable-tests</artifactId>
<version>1.0</version>
<type>test-jar</type>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Cuando mvn clean package la compilación crea 3 tarros:
- executable-tests-1.0.jar // construido por la fase del paquete mvn
- executable-tests-1.0-teststjar // creado por el complemento jar
- cucumber-tests.jar // construir por el complemento de sombra
Cucumber-tests.jar contiene las dependencias info.cuke pero no contiene el executable-tests-1.0-tests.jar .
He hecho todo tipo de cosas para probar y tener las clases de prueba incluidas pero nada ha funcionado, ¿qué me estoy perdiendo?
Edición: he llevado mi proyecto de ejemplo a GitHub si a alguien le gusta jugar con él :) https://github.com/C0deAttack/ExecutableTests
He resuelto mi problema de una manera diferente; utilizando otros dos complementos.
Primero uso el maven-dependency-plugin para obtener las dependencias y desempaquetarlas localmente, luego uso el maven-jar-plugin para crear un test-jar e incluir las clases de las dependencias desempaquetadas.
Respondió tarde, pero obtuvo una solución de trabajo que puede ayudar a los futuros visitantes de esta pregunta.
Logro tener un frasco de grasa utilizando solo un complemento de Maven e incluyendo:
- Las clases de prueba
- Las clases de código de aplicación.
- Dependencias externas requeridas por el código de la aplicación (en el alcance de
compile) - Dependencias externas requeridas por el código de prueba (en el alcance de la
test)
Lo que básicamente significa un frasco de grasa con la adición de clases de prueba (y sus dependencias). El Plugin Maven Jar y su objetivo de test-jar no se adaptarían a esta necesidad. El complemento de sombra de Maven y su opción shadeTestJar no ayudaron a ninguno de los dos.
Entonces, ¿cómo crear en Maven un frasco gordo con clases de prueba y dependencias externas?
El complemento de ensamblaje de Maven es un candidato perfecto en este caso.
Aquí hay una muestra mínima de POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-project</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.sample.TestMain</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
La configuración anterior también establece una clase principal definida en las clases de prueba (para una verificación rápida de si funciona o no, en la respuesta). Pero eso no es suficiente.
También debe crear un archivo descriptor , en la carpeta src/main/assembly un archivo assembly.xml con el siguiente contenido:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>fat-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
La configuración anterior es:
- configuración de las dependencias externas que se tomarán del alcance de la
test(que también tomará el alcance decompile) - configurar un
filesetdefilesetpara incluir clases de prueba compiladas como parte delfilesetde grasa empaquetado - establecer un frasco final con el clasificador de
fat-tests(por lo tanto, su archivo final será algo así comosampleproject-1.0-SNAPSHOT-fat-tests.jar).
¿Cómo podemos probarlo?
Construir el frasco:
mvn clean compile test-compile assembly:single
Ejecutando desde la carpeta de target :
java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
Conseguiríamos ejecutar el principal (de las clases de pruebas). El main puede invocar otras pruebas o código de aplicación (y, por lo tanto, requerir dependencias externas, tanto en el ámbito de compile como en el de test ) y todo funcionará bien.
Desde una página principal, también puede invocar todos sus casos de prueba de la siguiente manera:
- Crear un conjunto de pruebas JUni
- Agregue al conjunto de pruebas las pruebas correspondientes.
- Invoque el conjunto de pruebas desde su principal Java plano
Ejemplo de conjunto de pruebas:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({ AppTest.class })
public class AllTests {
}
Nota: en este caso, el conjunto de pruebas solo se refiere a la prueba de muestra AppTest .
Entonces podrías tener una clase principal como sigue:
import org.junit.internal.TextListener;
import org.junit.runner.JUnitCore;
public class MainAppTest {
public static void main(String[] args) {
System.out.println("Running tests!");
JUnitCore engine = new JUnitCore();
engine.addListener(new TextListener(System.out)); // required to print reports
engine.run(AllTests.class);
}
}
La línea principal anterior ejecutaría el conjunto de pruebas, que ejecutará en cadena todas las pruebas configuradas.