有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将测试类包括到Maven jar中并执行它们?

在Maven项目中,我在同一个包中有测试类和源类,但在不同的物理位置

.../src/main/java/package/** <-- application code
.../src/test/java/package/** <-- test code

在测试类中访问源类没有问题, 但是我想在main方法中运行一个测试运行程序并访问AllTest.class,这样我就可以创建jar并执行我的测试

 public static void main(String[] args) {
    // AllTest not found
    Result result = JUnitCore.runClasses(AllTest.class);
    for (Failure failure : result.getFailures()) {
        System.out.println(failure.toString());
    }
    System.out.println(result.wasSuccessful());
}

但是它不起作用,因为我没有访问测试代码的权限。我不明白,因为它们在同一个包裹里

问题:如何从应用程序类访问测试类?或者,Maven如何打包一个包含测试类的胖jar并执行测试


共 (1) 个答案

  1. # 1 楼答案

    您不应该从应用程序代码访问测试类,而是应该在测试范围中创建一个main(相同的main),并为您的项目创建一个额外的工件

    但是,在这个附加工件(jar)中,您需要:

    • 考试班
    • 应用程序代码类
    • 应用程序代码所需的外部依赖项(在compile范围内)
    • 测试代码所需的外部依赖项(在test范围内)

    这基本上意味着添加了测试类(及其依赖项)的胖罐子。{a1}及其{a2}目标不适合这一需要。{a3}及其{a4}选项也于事无补

    那么,如何在Maven中创建一个包含测试类和外部依赖项的胖jar呢

    在这种情况下,Maven Assembly Plugin是一个完美的候选者

    以下是最低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>
    

    上面的配置是设置您在测试类中定义的主类。但这还不够

    您还需要在src\main\assembly文件夹中创建一个descriptor file文件,其中包含以下内容:

    <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>
    

    以上配置为:

    • 设置要从test范围获取的外部依赖项(这也将获取compile范围)
    • fileset设置为包含已编译的测试类作为打包的fat jar的一部分
    • 使用fat-tests分类器设置最终jar(因此最终文件类似于sampleproject-1.0-SNAPSHOT-fat-tests.jar

    然后可以按如下方式调用main(从target文件夹):

    java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
    

    从这样一个main中,您还可以调用所有测试用例,如下所示:

    • 创建一个JUni测试套件
    • 将相关测试添加到测试套件中
    • 从普通Java主服务器调用测试套件

    测试套件示例:

    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);
        }
    }
    

    然后,上面的main将执行测试套件,该套件将在链中执行所有配置的测试