You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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会自动完成:

  1. 创建临时命名空间
  2. 部署数据库、Service、初始化Job
  3. 等待所有资源就绪
  4. 执行JUnit集成测试
  5. 测试完成后删除所有测试资源
关键细节提醒
  • 临时命名空间:用时间戳生成唯一命名空间,确保每次测试都是独立环境,不会互相干扰。
  • 资源就绪等待:Fabric8的wait配置一定要加,避免测试开始时数据库还没启动或数据还没初始化完成。
  • 数据初始化脚本:把SQL脚本放在ConfigMap里,比打包到镜像里更灵活,修改脚本无需重新构建镜像。
  • Vert.x应用配置:如果你的Vert.x应用也需要部署到测试环境,记得在应用的Deployment里配置环境变量指向测试数据库的Service名称(比如DB_HOST=test-postgres)。

内容的提问来源于stack exchange,提问作者rico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:28:48