4. 测试环境搭建:Docker Compose 编排 PostgreSQL 与 Redis 服务
在集成测试中,环境的一致性与可重复性是保障测试质量的基础。本章将使用 Docker Compose 对 PostgreSQL(数据持久层)与 Redis(缓存层)进行统一编排,并完成网络隔离与数据持久化配置,为后续的缓存预热与数据校验提供稳定的运行底座。
4.1 服务架构概览
测试环境由两个核心容器组成:PostgreSQL 负责存储业务主数据,Redis 作为缓存加速层。两者通过自定义桥接网络通信,并各自挂载宿主机目录实现数据持久化,避免容器重启导致数据丢失。
4.2 Docker Compose 文件详解
以下 docker-compose.yml 文件定义了 PostgreSQL 与 Redis 的服务规格、网络模式与持久化卷。所有配置均面向集成测试场景优化,避免生产级安全限制带来的调试复杂性。
version: "3.8"
services:
postgres:
image: postgres:15-alpine
container_name: integration-pg
restart: unless-stopped
environment:
POSTGRES_DB: testdb
POSTGRES_USER: tester
POSTGRES_PASSWORD: testpass
ports:
- "5432:5432"
volumes:
- pg_data:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d
networks:
- integration-test-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U tester -d testdb"]
interval: 5s
timeout: 3s
retries: 5
redis:
image: redis:7-alpine
container_name: integration-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- integration-test-net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pg_data:
driver: local
redis_data:
driver: local
networks:
integration-test-net:
driver: bridge
4.3 关键配置项说明
| 配置项 | 作用 | 测试环境注意事项 |
|---|---|---|
POSTGRES_DB / USER / PASSWORD |
初始化数据库、用户与密码 | 测试环境使用固定弱密码,便于自动化脚本连接;生产环境禁止此做法 |
volumes: pg_data |
将 PostgreSQL 数据目录挂载到命名卷 | 容器重启后数据保留;测试前可手动清空卷以重置状态 |
volumes: ./init-scripts |
挂载初始化 SQL 脚本目录 | 首次启动自动执行建表、索引、测试数据插入脚本 |
healthcheck |
容器健康检查 | 集成测试启动前应等待 health 状态为 healthy,避免连接失败 |
networks: integration-test-net |
自定义桥接网络 | 容器间通过服务名(postgres / redis)直接通信,无需依赖宿主机 IP |
4.4 网络配置:容器间服务发现
通过自定义网络 integration-test-net,PostgreSQL 与 Redis 容器可以使用服务名称作为主机名进行互访。例如,Python 测试代码中连接 PostgreSQL 时,主机名直接写 postgres 而非 localhost 或 IP 地址。
网络通信示例:
- PostgreSQL 连接字符串:
postgresql://tester:testpass@postgres:5432/testdb - Redis 连接字符串:
redis://redis:6379/0
这种基于服务名的通信方式,使得容器迁移或扩展时无需修改应用配置。
4.5 持久化卷挂载策略
数据持久化是集成测试环境的重要保障。本方案采用 命名卷(named volumes) 而非绑定挂载(bind mounts),原因如下:
- 命名卷由 Docker 管理,在宿主机上的实际路径对用户透明,避免跨平台路径兼容性问题。
- 绑定挂载虽然便于直接查看文件,但在 Windows 与 macOS 上存在文件权限与性能开销。
- 测试前重置数据时,只需执行
docker compose down -v即可删除卷并重建。
最佳实践:在 CI/CD 流水线中,每次运行集成测试前建议执行 docker compose down -v && docker compose up -d --wait,确保从干净的数据库与缓存状态开始。
4.6 初始化脚本与数据准备
在 ./init-scripts 目录下放置 SQL 初始化文件,容器首次启动时会按文件名顺序自动执行。以下是一个典型的测试表创建脚本:
-- 01_create_tables.sql
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
product_name VARCHAR(200) NOT NULL,
amount NUMERIC(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending'
);
-- 插入基础测试数据
INSERT INTO users (username, email) VALUES
('test_user_1', 'user1@example.com'),
('test_user_2', 'user2@example.com')
ON CONFLICT (username) DO NOTHING;
4.7 启动与验证步骤
完成 docker-compose.yml 与初始化脚本后,按以下步骤启动环境并验证服务可用性:
- 启动所有服务:
docker compose up -d - 等待健康检查通过:
docker compose ps查看状态,或使用--wait参数(Docker Compose v2.20+) - 验证 PostgreSQL:
docker exec integration-pg pg_isready -U tester -d testdb - 验证 Redis:
docker exec integration-redis redis-cli ping,应返回PONG - 测试网络互通:
docker exec integration-pg ping redis(需容器内安装 ping 工具)
常见问题:如果 PostgreSQL 容器启动后立即退出,请检查 ./init-scripts 目录中的 SQL 文件是否存在语法错误。查看日志命令:docker compose logs postgres。
4.8 环境清理与重置
集成测试执行完毕后,建议使用以下命令彻底清理环境,避免残留数据影响下一次测试:
# 停止容器并删除卷(数据完全丢失)
docker compose down -v
# 仅停止容器,保留数据(适用于调试后快速重启)
docker compose down
# 重新启动并等待就绪
docker compose up -d --wait
自动化集成建议:在 pytest 的 conftest.py 中,可以使用 subprocess 模块调用 Docker Compose 命令,配合 @pytest.fixture(scope="session") 实现测试会话级别的环境生命周期管理。