java 如何在 maven-shade-plugin 创建的 Jar 中包含测试类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10307652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to include test classes in Jar created by maven-shade-plugin?
提问by C0deAttack
I'm trying to package my test classes in to an executable jar with dependencies using Maven, but I'm struggling to get this right.
我正在尝试使用 Maven 将我的测试类打包到一个具有依赖项的可执行 jar 中,但我正在努力做到这一点。
This is my pom.xml so far:
到目前为止,这是我的 pom.xml:
<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>
When I execute mvn clean package
the build creates 3 jars:
当我执行mvn clean package
构建时会创建 3 个 jar:
- executable-tests-1.0.jar // built by the mvn package phase
- executable-tests-1.0-teststjar // built by the jar-plugin
- cucumber-tests.jar // build by the shade-plugin
- executable-tests-1.0.jar // 由 mvn 包阶段构建
- executable-tests-1.0-teststjar // 由 jar-plugin 构建
- Cucumber-tests.jar // 由 shade-plugin 构建
Cucumber-tests.jar
contains the info.cuke
dependencies but it doesn't contain the executable-tests-1.0-tests.jar
.
Cucumber-tests.jar
包含info.cuke
依赖项,但不包含executable-tests-1.0-tests.jar
.
I've done all sorts of things to try and have the test classes included but nothing has worked, what am I missing?
我已经做了各种各样的事情来尝试并包含测试类,但没有任何效果,我错过了什么?
Edit:I've pushed my example project to GitHub if any one fancies playing around with it :) https://github.com/C0deAttack/ExecutableTests
编辑:如果有人喜欢玩它,我已将我的示例项目推送到 GitHub :) https://github.com/C0deAttack/ExecutableTests
采纳答案by C0deAttack
I've solved my problem a different way; using two other plugins.
我以不同的方式解决了我的问题;使用其他两个插件。
First I use the maven-dependency-plugin
to get the dependencies and unpack them locally, then I use the maven-jar-plugin
to create a test-jar
and include the classes from the unpacked dependencies.
首先我使用maven-dependency-plugin
来获取依赖项并在本地解压它们,然后我使用maven-jar-plugin
来创建一个test-jar
并包含解压后的依赖项中的类。
回答by A_Di-Matteo
Answering late, but got a working solution which may help future visitors of this question.
回答晚了,但得到了一个可行的解决方案,可以帮助这个问题的未来访问者。
I succeed on having a fat jar using only one Maven plugin and including:
我仅使用一个 Maven 插件就成功创建了一个胖 jar,其中包括:
- The test classes
- The application code classes
- External dependencies required by application code (in
compile
scope) - External dependencies required by the test code (in
test
scope)
- 测试类
- 应用程序代码类
- 应用程序代码所需的外部依赖项(在
compile
范围内) - 测试代码所需的外部依赖项(在
test
范围内)
Which basically means a fat jar with the addition of test classes (and their dependencies). The Maven Jar Pluginand its test-jar
goal would not suit this need. The Maven Shade Pluginand its shadeTestJar
option would not help neither.
这基本上意味着添加了测试类(及其依赖项)的胖 jar。在Maven的Jar插件和它的test-jar
目标将无法满足这一需求。在Maven的阴影插件和它的shadeTestJar
方案不会也不帮助。
So, how to create in Maven a fat jar with test classes and external dependencies?
那么,如何在 Maven 中创建一个带有测试类和外部依赖项的胖 jar 呢?
The Maven Assembly Pluginis a perfect candidate in this case.
在这种情况下,Maven 程序集插件是一个完美的候选者。
Here is a minimal POM sample:
这是一个最小的 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>
The configuration above is also setting a main class defined in test classes (for a quick check whether it works or not, down on the answer). But that's not enough.
上面的配置还设置了一个在测试类中定义的主类(为了快速检查它是否有效,请看答案)。但这还不够。
You also need to create a descriptor file, in the src\main\assembly
folder an assembly.xml
file with the following content:
您还需要创建一个描述符文件,在src\main\assembly
文件夹中创建一个assembly.xml
包含以下内容的文件:
<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>
The configuration above is:
上面的配置是:
- setting external dependencies to be taken from the
test
scope (which will also take thecompile
scope as well) - setting a
fileset
to include compiled test classes as part of the packaged fat jar - setting a final jar with
fat-tests
classifier (hence your final file will be something likesampleproject-1.0-SNAPSHOT-fat-tests.jar
).
- 设置要从
test
范围中获取的外部依赖项(也将获取compile
范围) - 设置 a
fileset
以将编译的测试类包含在打包的 fat jar 中 - 使用
fat-tests
分类器设置最终 jar (因此您的最终文件将类似于sampleproject-1.0-SNAPSHOT-fat-tests.jar
)。
How can we test it?
我们如何测试它?
Build the jar:
构建罐子:
mvn clean compile test-compile assembly:single
Running from the target
folder:
从target
文件夹运行:
java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
We would get the main (from tests classes) executed. The main may invoke others tests or application code (and hence require external dependencies, in both compile
or test
scope) and everything would work fine.
我们将执行主要(来自测试类)。main 可能会调用其他测试或应用程序代码(因此在两者compile
或test
范围内都需要外部依赖项)并且一切正常。
From such a main, you could also invoke all of your test cases as following:
从这样的主,您还可以调用所有的测试用例如下:
- Create a JUni test suite
- Add to the test suite the concerned tests
- Invoke the test suite from your plain Java main
- 创建 JUni 测试套件
- 将相关测试添加到测试套件中
- 从纯 Java 主程序调用测试套件
Example of test suite:
测试套件示例:
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 {
}
Note: in this case the test suite is only concerning the AppTest
sample test.
注意:在这种情况下,测试套件仅与AppTest
示例测试有关。
Then you could have a main class as following:
然后你可以有一个主类如下:
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);
}
}
The main above would then execute the test suite which will in chain execute all of the configured tests.
然后上面的 main 将执行测试套件,该套件将在链中执行所有配置的测试。