运行集成测试
虽然你可以非常轻松地从测试(或测试套件)本身启动 Spring Boot 应用程序,但有时可能更希望在构建过程中处理这一点。为了确保 Spring Boot 应用程序的生命周期在集成测试前后得到妥善管理,你可以使用 start 和 stop 目标,如下例所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这种设置现在可以使用 failsafe-plugin 来运行你的集成测试,正如你所期望的那样。
该应用程序在单独的进程中启动,并使用 JMX 与应用程序通信。默认情况下,插件使用端口 9001。如果需要配置 JMX 端口,请参阅专门的示例。
你也可以配置一个更高级的设置,当设置了特定属性时跳过集成测试,参见专门的示例。
在不使用 Spring Boot 父 POM 的情况下使用 Failsafe
Spring Boot 的父 POM spring-boot-starter-parent 将 Failsafe 的 <classesDirectory> 配置为 ${project.build.outputDirectory}。如果没有此配置(该配置使 Failsafe 使用编译后的 class 文件而非重新打包的 jar),Failsafe 将无法加载你的应用程序的类。如果你没有使用父 POM,则应按照如下示例所示,以相同的方式配置 Failsafe:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
</configuration>
</plugin>
spring-boot:start
org.springframework.boot:spring-boot-maven-plugin:3.5.10
启动一个 Spring 应用程序。与 run goal 不同,此操作不会阻塞,并允许其他 goal 对应用程序进行操作。该 goal 通常用于集成测试场景中,在测试套件运行前启动应用程序,并在测试结束后停止。
必需参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| classesDirectory | File | ${project.build.outputDirectory} |
可选参数
| 名称 | 类型 | 默认值 |
|---|---|---|
| addResources | boolean | false |
| additionalClasspathElements | String[] | |
| agents | File[] | |
| arguments | String[] | |
| commandlineArguments | String | |
| environmentVariables | Map | |
| excludeGroupIds | String | |
| excludes | List | |
| includes | List | |
| jmxName | String | org.springframework.boot:type=Admin,name=SpringApplication |
| jmxPort | int | 9001 |
| jvmArguments | String | |
| mainClass | String | |
| maxAttempts | int | 60 |
| noverify | boolean | |
| profiles | String[] | |
| skip | boolean | false |
| systemPropertyVariables | Map | |
| useTestClasspath | Boolean | false |
| wait | long | 500 |
| workingDirectory | File |
参数详情
addResources
直接将 Maven 资源添加到 classpath 中,这允许对资源进行实时的原地编辑。重复的资源会从 target/classes 中移除,以防止在调用 ClassLoader.getResources() 时出现重复。建议考虑向项目中添加 spring-boot-devtools,因为它不仅提供此功能,还包含许多其他特性。
addResources | |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 用户属性 | spring-boot.run.addResources |
| 起始版本 | 1.0.0 |
additionalClasspathElements
应添加到 classpath 中的额外 classpath 元素。一个元素可以是包含类和资源的目录,也可以是一个 jar 文件。
additionalClasspathElements | |
|---|---|
| 类型 | java.lang.String[] |
| 默认值 | |
| 用户属性 | spring-boot.run.additional-classpath-elements |
| 自版本 | 3.2.0 |
agents
Agent JAR 文件的路径。
agents | |
|---|---|
| 类型 | java.io.File[] |
| 默认值 | |
| 用户属性 | spring-boot.run.agents |
| 起始版本 | 2.2.0 |
arguments
应传递给应用程序的参数。
arguments | |
|---|---|
| 类型 | java.lang.String[] |
| 默认值 | |
| 用户属性 | |
| 起始版本 | 1.0.0 |
classesDirectory
包含用于运行应用程序的类和资源文件的目录。
classesDirectory | |
|---|---|
| 类型 | java.io.File |
| 默认值 | ${project.build.outputDirectory} |
| 用户属性 | |
| 自版本 | 1.0.0 |
commandlineArguments
应传递给应用程序的命令行参数。使用空格分隔多个参数,并确保将多个值用引号括起来。当指定此选项时,其优先级高于 #arguments。
commandlineArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.run.arguments |
| 自 | 2.2.3 |
environmentVariables
应与用于运行应用程序的 forked 进程关联的环境变量列表。
environmentVariables | |
|---|---|
| 类型 | java.util.Map |
| 默认值 | |
| 用户属性 | |
| 自版本 | 2.1.0 |
excludeGroupIds
要排除的 groupId 名称的逗号分隔列表(精确匹配)。
excludeGroupIds | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.excludeGroupIds |
| 起始版本 | 1.1.0 |
excludes
要排除的构件定义集合。Exclude 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
excludes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.excludes |
| 起始版本 | 1.1.0 |
includes
要包含的构件定义集合。Include 元素定义了必需的 groupId 和 artifactId 组件,以及一个可选的 classifier 组件。当配置为属性时,值应以逗号分隔,各组件之间用冒号分隔:groupId:artifactId,groupId:artifactId:classifier
includes | |
|---|---|
| 类型 | java.util.List |
| 默认值 | |
| 用户属性 | spring-boot.includes |
| 起始版本 | 1.2.0 |
jmxName
自动部署的 MBean 的 JMX 名称,用于管理 Spring 应用程序的生命周期。
jmxName | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | org.springframework.boot:type=Admin,name=SpringApplication |
| 用户属性 | |
| 起始版本 |
jmxPort
用于暴露平台 MBeanServer 的端口。
jmxPort | |
|---|---|
| 类型 | int |
| 默认值 | 9001 |
| 用户属性 | |
| 起始版本 |
jvmArguments
应与用于运行应用程序的 forked 进程关联的 JVM 参数。在命令行中,请确保将多个值用引号括起来。
jvmArguments | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.run.jvmArguments |
| 自版本 | 1.1.0 |
mainClass
主类的名称。如果未指定,则将使用找到的第一个包含 'main' 方法的已编译类。
mainClass | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | |
| 用户属性 | spring-boot.run.main-class |
| 起始版本 | 1.0.0 |
maxAttempts
检查 Spring 应用是否就绪的最大尝试次数。结合 "wait" 参数,这会给出一个全局超时值(默认为 30 秒)。
maxAttempts | |
|---|---|
| 类型 | int |
| 默认值 | 60 |
| 用户属性 | spring-boot.start.maxAttempts |
| 自 |
noverify
标志,用于表示该 agent 需要 -noverify。
noverify | |
|---|---|
| 类型 | boolean |
| 默认值 | |
| 用户属性 | spring-boot.run.noverify |
| 起始版本 | 1.0.0 |
profiles
要激活的 Spring 配置文件。这是指定 spring.profiles.active 参数的便捷快捷方式。在命令行中,使用逗号分隔多个配置文件。
profiles | |
|---|---|
| 类型 | java.lang.String[] |
| 默认值 | |
| 用户属性 | spring-boot.run.profiles |
| 起始版本 | 1.3.0 |
skip
跳过执行。
skip | |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 用户属性 | spring-boot.run.skip |
| 起始版本 | 1.3.2 |
systemPropertyVariables
要传递给进程的 JVM 系统属性列表。
systemPropertyVariables | |
|---|---|
| 类型 | java.util.Map |
| 默认值 | |
| 用户属性 | |
| 自 | 2.1.0 |
useTestClasspath
运行时包含测试类路径的标志。
useTestClasspath | |
|---|---|
| 类型 | java.lang.Boolean |
| 默认值 | false |
| 用户属性 | spring-boot.run.useTestClasspath |
| 起始版本 |
wait
每次尝试检查 Spring 应用是否就绪之间等待的毫秒数。
wait | |
|---|---|
| 类型 | long |
| 默认值 | 500 |
| 用户属性 | spring-boot.start.wait |
| 起始版本 |
workingDirectory
应用程序使用的当前工作目录。如果未指定,则将使用 basedir。
workingDirectory | |
|---|---|
| 类型 | java.io.File |
| 默认值 | |
| 用户属性 | spring-boot.run.workingDirectory |
| 起始版本 | 1.5.0 |
spring-boot:stop
org.springframework.boot:spring-boot-maven-plugin:3.5.10
停止通过 "start" goal 启动的应用程序。通常在测试套件完成之后调用。
可选参数
参数详情
jmxName
自动部署的 MBean 的 JMX 名称,用于管理应用程序的生命周期。
jmxName | |
|---|---|
| 类型 | java.lang.String |
| 默认值 | org.springframework.boot:type=Admin,name=SpringApplication |
| 用户属性 | |
| 起始版本 |
jmxPort
用于查找平台 MBeanServer 的端口。
jmxPort | |
|---|---|
| 类型 | int |
| 默认值 | 9001 |
| 用户属性 | |
| 自 |
skip
跳过执行。
skip | |
|---|---|
| 类型 | boolean |
| 默认值 | false |
| 用户属性 | spring-boot.stop.skip |
| 起始版本 | 1.3.2 |
示例
集成测试的随机端口
Spring Boot 测试集成的一个很好的特性是,它可以为 Web 应用程序分配一个空闲端口。当使用插件的 start 目标时,Spring Boot 应用程序会单独启动,这使得将实际端口传递给集成测试本身变得困难。
下面的示例展示了如何使用 Build Helper Maven Plugin 实现相同的功能:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>reserve-tomcat-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>tomcat.http.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<arguments>
<argument>--server.port=${tomcat.http.port}</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<test.server.port>${tomcat.http.port}</test.server.port>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
你现在可以在任意集成测试中获取 test.server.port 系统属性,以创建指向服务器的正确 URL。
自定义 JMX 端口
jmxPort 属性允许自定义插件用于与 Spring Boot 应用程序通信的端口。
此示例展示了在 9001 端口已被占用的情况下,如何自定义端口:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jmxPort>9009</jmxPort>
</configuration>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果你需要配置 JMX 端口,请确保如上所示在全局配置中进行设置,以便两个目标(goals)共享该配置。
跳过集成测试
skip 属性允许完全跳过 Spring Boot Maven 插件的执行。
此示例展示了如何通过命令行属性跳过集成测试,同时仍确保 repackage 目标能够执行:
<project>
<properties>
<skip.it>false</skip.it>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-integration-test</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<skip>${skip.it}</skip>
</configuration>
</execution>
<execution>
<id>post-integration-test</id>
<goals>
<goal>stop</goal>
</goals>
<configuration>
<skip>${skip.it}</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skip>${skip.it}</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
默认情况下,集成测试将会运行,但此设置允许你通过命令行轻松禁用它们,如下所示:
$ mvn verify -Dskip.it=true