原创 | TDD 工具集:JUnit、AssertJ 和 Mockito (二十七) 运行测试 - 在构建工具中运行测试

505 阅读3分钟

在构建工具中运行测试

1. Maven

Maven默认在test阶段启动maven-surefire-plugin插件,执行项目中的所有测试。

1.1 插件和依赖

要支持JUnit平台,maven-surefire-plugin插件和maven-failsafe-plugin插件的版本要在2.20.0以上,同时,测试类路径中必须包含至少一个TestEngine实现。

如果只需要支持JUnit Jupiter,可以这样配置pom.xml

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.22.2</version>
        </plugin>
    </plugins>
</build>
<!-- ... -->
<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <!-- ... -->
</dependencies>
<!-- ... -->

如果要支持JUnit 4编写的测试,要添加junit-vintage-engine测试依赖项:

<!-- ... -->
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.22.2</version>
        </plugin>
    </plugins>
</build>
<!-- ... -->
<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <!-- ... -->
</dependencies>
<!-- ... -->

1.2 根据测试类文件名过滤测试

Maven Surefire插件默认会在项目测试类路径中扫描测试类,将全限定类名符合下面模式的测试类包含到测试中:

  • **/Test*.java
  • **/*Test.java
  • **/*Tests.java
  • **/*TestCase.java

默认情况下,会忽略掉嵌套测试类。

可以配置maven-surefire-plugin插件的includeexclude规则,改变上面的默认值。例如:

<!-- ... -->
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
            <configuration>
                <includes>
                  <include>**/*.Test.java</include>
                  <include>**/*.Spec.java</include>
                </includes>
                <excludes>
                  <exclude>../Abstract*.java</excluse>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
<!-- ... -->

1.3 根据@Tag过滤测试

可以根据测试类或测试方法的@Tag注解来包含或排除某些测试。可以通过Tag表达式来组合Tag。

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.2</version>
                    <executions>
                        <execution>
                            <id>unit-test</id>
                            <goals>
                                <goal>test</goal>
                            </goals>
                            <phase>test</phase>
                            <configuration>
                                <excludedGroups>integration, acceptance</excludedGroups>
                            </configuration>
                        </execution>
                        <execution>
                            <id>integration-test</id>
                            <goals>
                                <goal>test</goal>
                            </goals>
                            <phase>integration-test</phase>
                            <configuration>
                                <groups>integration | acceptance</groups>
                            </configuration>
                        </execution>
                    </executions>
                    <configuration>
                        <includes>
                            <include>**/*</include>
                        </includes>
                    </configuration>
                </plugin>

1.4 配置测试参数

可以像下面的示例那样配置测试平台的全局测试参数,其效果等价于在junit-platform.properties文件中设置全局测试参数:

<!-- ... -->
<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
            <configuration>
                <properties>
                    <configurationParameters>
                        junit.jupiter.conditions.deactivate = *
                        junit.jupiter.extensions.autodetection.enabled = true
                        junit.jupiter.testinstance.lifecycle.default = per_class
                    </configurationParameters>
                </properties>
            </configuration>
        </plugin>
    </plugins>
</build>
<!-- ... -->

1.5 执行测试

maven构建生命周期的test阶段,默认绑定了maven-surefire-plugin插件,会自动执行项目中的单元测试。在进入终端命令解释器之后,在项目的根目录下执行:

mvn clean test

就会自动根据pom.xml中的配置,执行项目中的全部或部分单元测试。

2. Gradle

Gradle 4.6版开始,提供了对JUnit平台的直接支持。

2.1 配置依赖项

build.gradle文件中添加JUnit依赖项:

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.2")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.2")
}

2.2 配置测试引擎

test节中指定使用JUnit

test {
    useJUnitPlatform()
}

如果要根据@Tag注解对测试进行过滤,需要在useJUnitPlatform()内部指定includeTags和/或excludeTags

test {
    useJUnitPlatform {
        includeTags 'fast', 'smoke & feature-a'
        excludeTags 'slow', 'ci'
    }
}

还可以在useJUnitPlatform()内部指定包含或排除特定的测试引擎:

test {
    useJUnitPlatform {
        includeEngines 'junit-jupiter'
        excludeEngines 'junit-vintage'
    }
}

2.3 配置全局测试参数

还可以指定配置测试平台的全局测试参数:

test {
    // ...
    systemProperty 'junit.jupiter.conditions.deactivate', '*'
    systemProperties = [
        'junit.jupiter.extensions.autodetection.enabled': 'true',
        'junit.jupiter.testinstance.lifecycle.default': 'per_class'
    ]
    // ...
}

2.4 执行测试

在终端窗口中,进入gradle项目的根目录,执行下面的命令:

gradle build

会根据build.gradle中的配置,自动执行项目中全部或部分单元测试。

3. Ant

1.10.3版本开始,Ant通过junitlauncher任务可以执行启动JUnit平台。从1.10.6版开始,支持将测试fork到独立的JVM中执行。

build.xml文件示例配置如下:

<path id="test.classpath">
    <!-- The location where you have your compiled test classes -->
    <pathelement location="${build.classes.dir}" />
</path>
<!-- ... -->
<junitlauncher>
    <classpath refid="test.classpath" />
</junitlauncher>

junitlauncher任务可以在类路径中找到所有测试类,交给测试引擎执行测试。

可以通过在junitlauncher中定义test子任务的方式,让junitlauncher只执行指定的测试:

<junitlauncher>
    <classpath refid="test.classpath" />
    <test name="org.myapp.test.MyFirstJUnit5Test" />
</junitlauncher>

可以通过在junitlauncher中定义testclasses子任务的方式,让junitlauncher搜索单元测试:

<junitlauncher>
    <classpath refid="test.classpath" />
    <testclasses outputdir="${output.dir}">
        <fileset dir="${build.classes.dir}">
            <include name="org/example/**/demo/**/" />
        </fileset>
        <fileset dir="${some.other.dir}">
            <include name="org/myapp/**/" />
        </fileset>
    </testclasses>
</junitlauncher>

完整build.xml文件例子:

<project>
    <property name="output.dir" value="${basedir}/build"/>
    <property name="src.test.dir" value="${basedir}/src/test"/>
    <property name="build.classes.dir" value="${output.dir}/classes"/>

    <target name="init">
        <mkdir dir="${output.dir}"/>
    </target>

    <path id="junit.platform.libs.classpath">
        <fileset dir="${basedir}/src/lib/junit-platform/"/>
    </path>

    <path id="junit.engine.jupiter.classpath">
        <fileset dir="${basedir}/src/lib/jupiter/"/>
    </path>

    <target name="compile-test" depends="init">
        <mkdir dir="${build.classes.dir}"/>
        <javac srcdir="${src.test.dir}"
           destdir="${build.classes.dir}">
           <!-- our tests only need JUnit Jupiter engine
           libraries in our compile classpath for the tests -->
           <classpath refid="junit.engine.jupiter.classpath"/>
        </javac>
    </target>

    <target name="test" depends="compile-test">
        <junitlauncher>
            <!-- include the JUnit platform related libraries
            required to run the tests -->
            <classpath refid="junit.platform.libs.classpath"/>

            <!-- include the JUnit Jupiter engine libraries -->
            <classpath refid="junit.engine.jupiter.classpath"/>

            <classpath>
                <!-- the test classes themselves -->
                <pathelement location="${build.classes.dir}"/>
            </classpath>
            <testclasses outputdir="${output.dir}">
                <fileset dir="${build.classes.dir}"/>
                <listener type="legacy-brief" sendSysOut="true"/>
                <listener type="legacy-xml" sendSysErr="true" sendSysOut="true"/>
            </testclasses>
        </junitlauncher>
    </target>
</project>

运行下面的命令执行测试:

ant test

具体代码示例请戳这里↓↓↓

TDD工具集:JUnit、AssertJ和Mockito (二十七)运行测试-在构建工具中运行测试

本文相关开源代码戳这里下载↓↓↓

代码下载 | TDD工具集原创开源代码免费下载!

这一节就讲到这里,下一节我们讲讲**"运行测试中的在终端控制台中运行测试"**。

如果觉得有收获,点个【赞】鼓励一下呗!