如何在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可以调用其他测试或应用程序代码(因此在compiletest范围内都需要外部依赖)并且一切都可以正常工作。


从这样的主程序中,您还可以调用所有测试用例,如下所示:

  • 创建一个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并包含来自解压缩依赖项的类。