如何在OpenShift上用JUnit和Fabric8插件管理测试数据库容器生命周期
嘿,这个需求我刚好帮团队落地过,用JUnit + Maven Fabric8插件完全能实现“测试前部署带预定义数据的数据库、测试后自动销毁”的闭环,下面一步步给你拆解:
整体思路
核心逻辑是借助Maven的生命周期钩子,让Fabric8插件在预集成测试阶段自动创建OpenShift资源(数据库Deployment、数据初始化Job、Service),等资源就绪后执行JUnit集成测试,测试完成后在集成测试后阶段自动清理所有测试资源,全程无需手动干预。
具体实现步骤
1. 配置Maven Fabric8插件
在项目根pom.xml的<build><plugins>节点下添加Fabric8插件配置,绑定到Maven的测试生命周期:
<plugin> <groupId>io.fabric8</groupId> <artifactId>fabric8-maven-plugin</artifactId> <version>4.1.0</version> <!-- 用最新稳定版即可 --> <executions> <!-- 预测试阶段:生成并应用OpenShift资源 --> <execution> <id>f8-resources</id> <phase>pre-integration-test</phase> <goals> <goal>resource</goal> <goal>apply</goal> </goals> </execution> <!-- 测试完成后:删除所有测试资源 --> <execution> <id>f8-cleanup</id> <phase>post-integration-test</phase> <goals> <goal>delete</goal> </goals> </execution> </executions> <configuration> <!-- 使用临时命名空间,避免污染现有环境 --> <namespace>${project.artifactId}-test-${maven.build.timestamp}</namespace> <!-- 等待资源就绪的超时配置 --> <wait> <deployment> <timeout>300</timeout> <!-- 等待Deployment就绪的超时(秒) --> </deployment> <job> <timeout>300</timeout> <!-- 等待数据初始化Job完成的超时(秒) --> </job> </wait> </configuration> </plugin>
2. 准备OpenShift测试资源
在项目的src/test/fabric8目录下创建测试用的OpenShift YAML文件:
2.1 数据库Deployment + Service(以PostgreSQL为例)
创建postgresql-deployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: test-postgres spec: replicas: 1 selector: matchLabels: app: test-postgres template: metadata: labels: app: test-postgres spec: containers: - name: postgres image: postgres:14-alpine env: - name: POSTGRES_USER value: test-user - name: POSTGRES_PASSWORD value: test-pass - name: POSTGRES_DB value: test-db ports: - containerPort: 5432 --- apiVersion: v1 kind: Service metadata: name: test-postgres spec: ports: - port: 5432 targetPort: 5432 selector: app: test-postgres
2.2 数据初始化Job
创建postgres-init-job.yaml,用来执行预定义的SQL脚本:
apiVersion: batch/v1 kind: Job metadata: name: postgres-init spec: template: spec: containers: - name: init-db image: postgres:14-alpine command: ["psql", "-h", "test-postgres", "-U", "test-user", "-d", "test-db", "-f", "/init/init-data.sql"] env: - name: PGPASSWORD value: test-pass volumeMounts: - name: init-scripts mountPath: /init volumes: - name: init-scripts configMap: name: init-sql restartPolicy: Never backoffLimit: 3 --- apiVersion: v1 kind: ConfigMap metadata: name: init-sql data: init-data.sql: | -- 这里写你的预测试数据初始化SQL CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name VARCHAR(50)); INSERT INTO users (name) VALUES ('Alice'), ('Bob');
3. 编写JUnit集成测试
使用Vert.x的JUnit扩展,结合Fabric8 Java客户端(可选)来编写测试:
import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import io.vertx.rxjava3.core.Vertx; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; @ExtendWith(VertxExtension.class) public class IntegrationTest { // 可选:用Fabric8客户端检查资源状态 private final KubernetesClient k8sClient = new DefaultKubernetesClient(); @Test void testPredefinedDataExists(Vertx vertx, VertxTestContext testContext) { // 从OpenShift Service获取数据库地址(也可以通过系统属性传递) String dbHost = k8sClient.services().withName("test-postgres").get().getSpec().getClusterIP(); String jdbcUrl = String.format("jdbc:postgresql://%s:5432/test-db?user=test-user&password=test-pass", dbHost); // 用Vert.x JDBC客户端查询预定义数据 vertx.rxCreateSqlClient(jdbcUrl) .flatMap(client -> client.rxQuery("SELECT name FROM users WHERE name = 'Alice'")) .subscribe(resultSet -> { assert resultSet.getRowCount() == 1; testContext.completeNow(); }, testContext::failNow); } }
4. 执行测试
直接运行Maven命令:
mvn clean verify
Fabric8会自动完成:
- 创建临时命名空间
- 部署数据库、Service、初始化Job
- 等待所有资源就绪
- 执行JUnit集成测试
- 测试完成后删除所有测试资源
关键细节提醒
- 临时命名空间:用时间戳生成唯一命名空间,确保每次测试都是独立环境,不会互相干扰。
- 资源就绪等待:Fabric8的
wait配置一定要加,避免测试开始时数据库还没启动或数据还没初始化完成。 - 数据初始化脚本:把SQL脚本放在ConfigMap里,比打包到镜像里更灵活,修改脚本无需重新构建镜像。
- Vert.x应用配置:如果你的Vert.x应用也需要部署到测试环境,记得在应用的Deployment里配置环境变量指向测试数据库的Service名称(比如
DB_HOST=test-postgres)。
内容的提问来源于stack exchange,提问作者rico
相关产品推荐
相关产品推荐

