如何在maven-shade-plugin创建的Jar中包含测试类?
我正在尝试使用Maven将我的测试类打包到一个带有依赖项的可执行jar中,但我很难做到这一点。
到目前为止这是我的pom.xml:
4.0.0 com.c0deattack executable-tests 1.0 jar executable-tests info.cukes cucumber-java 1.0.0 info.cukes cucumber-junit 1.0.0 org.seleniumhq.selenium selenium-java 2.21.0 junit junit 4.10 org.apache.maven.plugins maven-jar-plugin 2.4 test-jar org.apache.maven.plugins maven-shade-plugin 1.6 package shade cucumber-tests cucumber.cli.Main info.cukes:* com.c0deattack executable-tests 1.0 test-jar
当我执行mvn clean package
,构建会创建3个jar:
- executable-tests-1.0.jar //由mvn包阶段构建
- executable-tests-1.0-teststjar //由jar-plugin构建
- cucumber-tests.jar //由shade-plugin构建
Cucumber-tests.jar
包含info.cuke
依赖项,但它不包含executable-tests-1.0-tests.jar
。
我已经做了各种各样的尝试,包括测试课程,但没有任何工作,我缺少什么?
编辑:我已经将我的示例项目推送到GitHub,如果有人想玩它的话:) https://github.com/C0deAttack/ExecutableTests
回答得很晚,但得到了一个可行的解决方案,可以帮助未来的访问者提出这个问题。
我成功使用了一个只使用一个Maven插件的胖jar,包括:
- 测试类
- 应用程序代码类
- 应用程序代码所需的外部依赖项(在
compile
范围内) - 测试代码所需的外部依赖关系(在
test
范围内)
这基本上意味着增加了测试类(及其依赖项)的胖jar。 Maven Jar插件及其test-jar
目标不适合这种需求。 Maven Shade插件及其shadeTestJar
选项也无济于事。
那么,如何在Maven中创建一个带有测试类和外部依赖项的胖jar?
在这种情况下, Maven Assembly Plugin是一个完美的候选者。
这是一个最小的POM样本:
4.0.0 com.sample sample-project 1.0-SNAPSHOT maven-assembly-plugin 2.3 src/main/assembly/assembly.xml make-assembly package single com.sample.TestMain junit junit 4.11 test
上面的配置还设置了在测试类中定义的主类(用于快速检查它是否有效,在答案上)。 但这还不够。
您还需要在src\main\assembly
文件夹中创建一个描述符文件 ,其中包含以下内容的assembly.xml
文件:
fat-tests jar false / true true test ${project.build.directory}/test-classes / **/*.class true
上面的配置是:
- 设置从
test
范围中获取的外部依赖项(也将采用compile
范围) - 设置一个
fileset
以包含已编译的测试类作为打包的胖jar的一部分 - 使用
fat-tests
分类器设置最终jar(因此你的最终文件将类似于sampleproject-1.0-SNAPSHOT-fat-tests.jar
)。
我们怎么测试呢?
建立jar:
mvn clean compile test-compile assembly:single
从target
文件夹运行:
java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
我们将执行main(来自测试类)。 main可以调用其他测试或应用程序代码(因此在compile
或test
范围内都需要外部依赖)并且一切都可以正常工作。
从这样的主程序中,您还可以调用所有测试用例,如下所示:
- 创建一个JUni测试套件
- 将相关测试添加到测试套件中
- 从普通的Java main调用测试套件
测试套件示例:
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 { }
注意:在这种情况下,测试套件仅涉及AppTest
样本测试。
然后你可以有一个主类如下:
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); } }
然后,上面的主要部分将执行测试套件,该套件将链执行所有已配置的测试。
我用不同的方式解决了我的问题; 使用另外两个插件。
首先,我使用maven-dependency-plugin
来获取依赖项并在本地解压缩,然后我使用maven-jar-plugin
创建一个test-jar
并包含来自解压缩依赖项的类。