在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 )中,您将需要具有:

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

  • 从根本上讲,这意味着增加了测试类(以及它们的依赖项),这是一个胖子。 Maven Jar Plugin及其 test-jar 目标不适合此需求。 Maven Shade Plugin及其 shadeTestJar 选项均无济于事。

    那么,如何在Maven中创建一个带有测试类和外部依赖项的胖子呢?

    在这种情况下,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>
    

    上面的配置是:
  • 设置要从assembly.xml范围获取的外部依赖项(也将采用test范围)
  • 设置compile以包括已编译的测试类作为打包的 fat jar
  • 的一部分
  • 使用fileset分类器设置最终jar(因此,最终文件将类似于fat-tests)。

  • 然后,您可以按以下方式调用主程序(从sampleproject-1.0-SNAPSHOT-fat-tests.jar文件夹中):
    java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
    

    从这样的主体中,您还可以按以下方式调用所有测试用例:
  • 创建一个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 {
    
    }
    

    注意:在这种情况下,测试套件仅涉及target示例测试。

    然后,您可以拥有一个如下的主类:
    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将执行测试套件,该套件将链式执行所有已配置的测试。

    关于java - 如何在Maven jar中包含测试类并执行它们?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36047637/

    10-12 07:34
    查看更多