3. 集成测试环境搭建:Docker Compose 编排数据库容器、配置 Liquibase 连接参数、初始化测试数据库
集成测试环境的核心目标是提供一个可重复、隔离、与生产环境高度一致的数据库运行时。本章将使用 Docker Compose 编排 PostgreSQL 容器,配置 Liquibase 连接参数,并完成测试数据库的初始化。整个流程确保每次运行冒烟验证时,数据库状态都是干净且可预测的。
3.1 环境架构概览
下图展示了集成测试环境的核心组件及其交互关系:
3.2 Docker Compose 编排数据库容器
使用 Docker Compose 可以一键启动、停止和重建数据库容器,确保测试环境的一致性和隔离性。以下是一个典型的 docker-compose.yml 配置:
version: '3.8'
services:
postgres-test:
image: postgres:15-alpine
container_name: liquibase-integration-test-db
environment:
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_pass
POSTGRES_DB: integration_test_db
ports:
- "5432:5432"
volumes:
- ./init-scripts:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test_user -d integration_test_db"]
interval: 5s
timeout: 3s
retries: 5
networks:
- test-net
networks:
test-net:
driver: bridge
关键配置说明:
- healthcheck:确保容器在数据库完全就绪后才被标记为健康,避免 Liquibase 在数据库未启动时执行迁移。
- volumes:挂载初始化脚本目录,容器启动时会自动执行
.sql或.sh文件。 - 网络隔离:使用自定义 bridge 网络
test-net,避免与宿主机或其他项目冲突。
3.3 配置 Liquibase 连接参数
Liquibase 通过 liquibase.properties 文件或环境变量获取数据库连接信息。在集成测试中,推荐使用属性文件方式,便于版本控制和参数化:
# liquibase.properties
changeLogFile: db/changelog/db.changelog-master.xml
url: jdbc:postgresql://localhost:5432/integration_test_db
username: test_user
password: test_pass
driver: org.postgresql.Driver
defaultSchemaName: public
liquibaseSchemaName: liquibase_changelog
liquibaseTablespaceName: pg_default
| 参数 | 说明 | 示例值 |
|---|---|---|
changeLogFile |
主变更集文件路径 | db/changelog/db.changelog-master.xml |
url |
JDBC 连接字符串 | jdbc:postgresql://localhost:5432/integration_test_db |
username |
数据库用户名 | test_user |
password |
数据库密码 | test_pass |
liquibaseSchemaName |
存储 Liquibase 元数据的 schema | liquibase_changelog |
注意:在 CI/CD 环境中,密码不应硬编码在属性文件中。建议使用环境变量注入,例如
${LIQUIBASE_PASSWORD},或通过 Docker Compose 的 environment 字段传递。
3.4 初始化测试数据库
数据库初始化分为两个阶段:基础 Schema 创建和Liquibase 变更集执行。
3.4.1 基础初始化脚本
在 init-scripts/ 目录下创建 01-init-schema.sql,用于创建必要的扩展和基础对象:
-- 01-init-schema.sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- 创建测试专用的 schema
CREATE SCHEMA IF NOT EXISTS test_data;
-- 设置默认权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO test_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO test_user;
3.4.2 Liquibase 变更集执行
使用 Maven 插件或命令行执行 Liquibase 迁移。以下是 Maven 插件的配置示例:
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>4.25.0</version>
<configuration>
<propertyFile>src/test/resources/liquibase.properties</propertyFile>
</configuration>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
执行命令:
mvn liquibase:update -P integration-test
3.5 初始化流程时序
下图展示了从容器启动到数据库就绪的完整时序:
3.6 验证环境就绪
执行以下命令验证环境是否搭建成功:
# 1. 启动容器
docker-compose -f docker-compose.yml up -d
# 2. 检查容器健康状态
docker ps --filter "name=liquibase-integration-test-db" --format "{{.Status}}"
# 3. 执行 Liquibase 迁移
mvn liquibase:update -P integration-test
# 4. 验证迁移状态
mvn liquibase:status -P integration-test
预期输出:
- 容器状态显示
Up (healthy)。 - Liquibase 迁移日志显示
Liquibase: Update has been successful.。 - 状态检查显示
0 changesets have not been applied。
3.7 常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 容器启动后立即退出 | 端口冲突或环境变量错误 | 检查 docker logs,确认端口 5432 未被占用 |
| Liquibase 连接超时 | 数据库未就绪时执行迁移 | 增加 healthcheck 等待时间,或使用 depends_on 的 condition: service_healthy |
| 初始化脚本未执行 | 脚本命名不符合规范 | 确保脚本以 .sql 或 .sh 结尾,且按字母顺序命名 |
| 变更集执行失败 | SQL 语法错误或依赖缺失 | 查看 Liquibase 日志,定位具体变更集 ID 和错误行号 |