1. 概述
在项目生命周期中,集成测试的设置是一个常见需求。本教程将介绍如何使用Maven Cargo插件来实现这一场景。
2. Maven集成测试构建阶段
幸运的是,Maven为这种特定场景提供了内置支持。默认构建生命周期(参见Maven官方文档)中的以下阶段:
- pre-integration-test: 在执行集成测试之前执行所需操作。这可能包括设置所需的环境。
- integration-test: 如果需要,处理并部署包到一个可以运行集成测试的环境中。
- post-integration-test: 在执行完集成测试后执行所需操作。这可能包括清理环境。
3. 设置Cargo插件
让我们逐步了解所需的设置。
3.1. 从Surefire插件排除集成测试
首先,需要配置maven-surefire-plugin,以排除标准构建生命周期中的集成测试:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
</configuration>
</plugin>
测试的排除通过ant风格的路径表达式完成,因此所有集成测试必须遵循此模式,并以IntegrationTest.java
结尾。
3.2. 配置Cargo插件
接下来,我们将使用cargo-maven3-plugin,因为Cargo为嵌入式Web服务器提供了顶级的开箱即用支持。当然,如果服务器环境需要特定配置,Cargo也知道如何根据存档包构建服务器并部署到外部服务器。
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<version>1.9.9</version>
<configuration>
<configuration>
<properties>
<cargo.servlet.port>8080</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
定义了一个默认的嵌入式Jetty 9 Web服务器,监听8080端口。
在Cargo的新版本(1.1.0及以上)中,cargo:start
目标的默认值wait被改为false。这个目标只应用于运行集成测试,并绑定到Maven生命周期;对于开发,应该使用cargo:run
目标,其默认值为wait=true
。
为了让package
Maven阶段生成一个可部署的war
文件,项目的打包类型必须是<packaging>war</packaging>
。
3.3. 添加新的Maven配置文件
接下来,创建一个新的集成Maven配置文件,以便仅在激活此配置文件时运行集成测试,而不是作为标准构建生命周期的一部分。
<profiles>
<profile>
<id>integration</id>
<build>
<plugins>
...
</plugins>
</build>
</profile>
</profiles>
这个配置文件将包含剩余的所有配置细节。
现在,Jetty服务器被配置在pre-integration-test
阶段启动,在post-integration-test
阶段停止。
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
这确保了cargo:start
和cargo:stop
目标将在integration-test
阶段之前和之后执行。请注意,由于有两个独立的执行定义,所以id元素必须在两个地方都存在且不同,以便Maven可以接受配置。
3.4. 在新配置文件中配置集成测试
接下来,需要在integration
配置文件中覆盖maven-surefire-plugin的配置,以便将默认生命周期中排除的集成测试包含并运行:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
有几个值得注意的地方:
maven-surefire-plugin的
test
目标在integration-test
阶段执行;此时,Jetty已经启动,项目已部署,因此集成测试应该可以顺利运行。集成测试现在被包含在执行中。为了实现这一点,需要重写排除规则——这是由于Maven在配置文件内处理插件配置的方式。
基础配置并没有完全被覆盖,而是在配置文件内部添加了新的配置元素。
正因为如此,原始的<excludes>
配置仍然存在于配置文件中,需要被覆盖,否则它会与<includes>
配置冲突,测试仍然无法运行。
- 注意,由于只有一个
<execution>
元素,不需要定义id
。
现在整个过程可以运行:
mvn clean install -Pintegration
4. 总结
逐步配置Maven涵盖了作为项目生命周期一部分设置集成测试的全过程。
通常,这会在持续集成环境中设置,最好在每次提交后进行。如果CI服务器已经有了运行并占用端口的服务器,那么Cargo配置将需要处理这种情况,我将在后续的文章中详细介绍。
要查看完整的配置示例,请参阅REST GitHub项目。
此外,还可以阅读这篇文章,了解最佳实践,关于如何组织项目结构和安排单元测试和集成测试。