运行集成测试

虽然你可以很容易地从测试(或测试套件)本身启动 Spring Boot 应用,但有时希望在构建过程中管理这一流程。 为了确保 Spring Boot 应用在集成测试期间的生命周期被正确管理,你可以使用 startstop 目标,如下例所示:

<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 会使用已打包的 jar 而不是编译后的类,导致无法加载应用类。 如果你未使用父 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.0

Start a spring application. Contrary to the run goal, this does not block and allows other goals to operate on the application. This goal is typically used in integration test scenario where the application is started before a test suite and stopped after.

Required parameters

Name Type Default

classesDirectory

File

${project.build.outputDirectory}

Optional parameters

Name Type Default

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

Parameter details

addResources

Add maven resources to the classpath directly, this allows live in-place editing of resources. Duplicate resources are removed from target/classes to prevent them from appearing twice if ClassLoader.getResources() is called. Please consider adding spring-boot-devtools to your project instead as it provides this feature and many more.

Name

addResources

Type

boolean

Default value

false

User property

spring-boot.run.addResources

Since

1.0.0

additionalClasspathElements

Additional classpath elements that should be added to the classpath. An element can be a directory with classes and resources or a jar file.

Name

additionalClasspathElements

Type

java.lang.String[]

Default value

User property

spring-boot.run.additional-classpath-elements

Since

3.2.0

agents

Path to agent jars.

Name

agents

Type

java.io.File[]

Default value

User property

spring-boot.run.agents

Since

2.2.0

arguments

Arguments that should be passed to the application.

Name

arguments

Type

java.lang.String[]

Default value

User property

Since

1.0.0

classesDirectory

Directory containing the classes and resource files that should be used to run the application.

Name

classesDirectory

Type

java.io.File

Default value

${project.build.outputDirectory}

User property

Since

1.0.0

commandlineArguments

Arguments from the command line that should be passed to the application. Use spaces to separate multiple arguments and make sure to wrap multiple values between quotes. When specified, takes precedence over #arguments.

Name

commandlineArguments

Type

java.lang.String

Default value

User property

spring-boot.run.arguments

Since

2.2.3

environmentVariables

List of Environment variables that should be associated with the forked process used to run the application.

Name

environmentVariables

Type

java.util.Map

Default value

User property

Since

2.1.0

excludeGroupIds

Comma separated list of groupId names to exclude (exact match).

Name

excludeGroupIds

Type

java.lang.String

Default value

User property

spring-boot.excludeGroupIds

Since

1.1.0

excludes

Collection of artifact definitions to exclude. The Exclude element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

excludes

Type

java.util.List

Default value

User property

spring-boot.excludes

Since

1.1.0

includes

Collection of artifact definitions to include. The Include element defines mandatory groupId and artifactId components and an optional classifier component. When configured as a property, values should be comma-separated with colon-separated components: groupId:artifactId,groupId:artifactId:classifier

Name

includes

Type

java.util.List

Default value

User property

spring-boot.includes

Since

1.2.0

jmxName

The JMX name of the automatically deployed MBean managing the lifecycle of the spring application.

Name

jmxName

Type

java.lang.String

Default value

org.springframework.boot:type=Admin,name=SpringApplication

User property

Since

jmxPort

The port to use to expose the platform MBeanServer.

Name

jmxPort

Type

int

Default value

9001

User property

Since

jvmArguments

JVM arguments that should be associated with the forked process used to run the application. On command line, make sure to wrap multiple values between quotes.

Name

jvmArguments

Type

java.lang.String

Default value

User property

spring-boot.run.jvmArguments

Since

1.1.0

mainClass

The name of the main class. If not specified the first compiled class found that contains a 'main' method will be used.

Name

mainClass

Type

java.lang.String

Default value

User property

spring-boot.run.main-class

Since

1.0.0

maxAttempts

The maximum number of attempts to check if the spring application is ready. Combined with the "wait" argument, this gives a global timeout value (30 sec by default)

Name

maxAttempts

Type

int

Default value

60

User property

spring-boot.start.maxAttempts

Since

noverify

Flag to say that the agent requires -noverify.

Name

noverify

Type

boolean

Default value

User property

spring-boot.run.noverify

Since

1.0.0

profiles

The spring profiles to activate. Convenience shortcut of specifying the 'spring.profiles.active' argument. On command line use commas to separate multiple profiles.

Name

profiles

Type

java.lang.String[]

Default value

User property

spring-boot.run.profiles

Since

1.3.0

skip

Skip the execution.

Name

skip

Type

boolean

Default value

false

User property

spring-boot.run.skip

Since

1.3.2

systemPropertyVariables

List of JVM system properties to pass to the process.

Name

systemPropertyVariables

Type

java.util.Map

Default value

User property

Since

2.1.0

useTestClasspath

Flag to include the test classpath when running.

Name

useTestClasspath

Type

java.lang.Boolean

Default value

false

User property

spring-boot.run.useTestClasspath

Since

wait

The number of milliseconds to wait between each attempt to check if the spring application is ready.

Name

wait

Type

long

Default value

500

User property

spring-boot.start.wait

Since

workingDirectory

Current working directory to use for the application. If not specified, basedir will be used.

Name

workingDirectory

Type

java.io.File

Default value

User property

spring-boot.run.workingDirectory

Since

1.5.0

spring-boot:stop

org.springframework.boot:spring-boot-maven-plugin:3.5.0

Stop an application that has been started by the "start" goal. Typically invoked once a test suite has completed.

Optional parameters

Name Type Default

jmxName

String

org.springframework.boot:type=Admin,name=SpringApplication

jmxPort

int

9001

skip

boolean

false

Parameter details

jmxName

The JMX name of the automatically deployed MBean managing the lifecycle of the application.

Name

jmxName

Type

java.lang.String

Default value

org.springframework.boot:type=Admin,name=SpringApplication

User property

Since

jmxPort

The port to use to look up the platform MBeanServer.

Name

jmxPort

Type

int

Default value

9001

User property

Since

skip

Skip the execution.

Name

skip

Type

boolean

Default value

false

User property

spring-boot.stop.skip

Since

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 端口,请确保如上所示在全局配置中设置,以便两个目标共享。

跳过集成测试

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