2. 集成测试环境搭建:使用 Docker Compose 编排多服务(Web+DB+Cache)测试环境
在集成测试中,测试环境需要真实地模拟生产部署的拓扑结构。本章将使用 Docker Compose 编排一个包含 Web 应用、PostgreSQL 数据库和 Redis 缓存的典型三服务测试环境,并确保服务间网络互通、启动顺序正确、数据可初始化。
2.1 环境拓扑与组件职责
测试环境由三个核心容器组成,每个容器承担明确的测试角色:
| 服务名 | 镜像 | 端口映射 | 测试环境职责 |
|---|---|---|---|
| web | python:3.11-slim | 8080:8000 | 运行 FastAPI 应用,提供 REST 接口供测试脚本调用 |
| db | postgres:15-alpine | 5432:5432 | 存储业务数据,测试数据通过初始化脚本注入 |
| cache | redis:7-alpine | 6379:6379 | 缓存会话与热点数据,验证缓存穿透/击穿场景 |
设计原则: 测试环境使用与生产环境相同的镜像版本(alpine 变体),但资源限制更小、日志级别更高,便于调试。
2.2 Docker Compose 编排文件
在项目根目录创建 docker-compose.yml,定义三个服务、共享网络、数据卷及健康检查:
version: "3.9"
services:
db:
image: postgres:15-alpine
container_name: test-db
environment:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: testdb
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"]
interval: 5s
timeout: 3s
retries: 5
networks:
- test_network
cache:
image: redis:7-alpine
container_name: test-cache
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
networks:
- test_network
web:
build:
context: ./app
dockerfile: Dockerfile.test
container_name: test-web
ports:
- "8080:8000"
environment:
DATABASE_URL: postgresql://testuser:testpass@db:5432/testdb
REDIS_URL: redis://cache:6379/0
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
volumes:
- ./app:/app
networks:
- test_network
volumes:
pgdata:
networks:
test_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
关键配置解读:
•
• 使用
• 显式指定
•
depends_on 配合 condition: service_healthy 确保 Web 在 DB 和 Cache 就绪后才启动。• 使用
healthcheck 替代简单的 sleep,避免竞态条件。• 显式指定
subnet 便于测试脚本固定 IP 白名单。
2.3 数据库初始化脚本
在 init-scripts/ 目录下创建 01-init.sql,注入测试所需的表结构和种子数据:
-- 01-init.sql
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO users (username, email) VALUES
('test_user_1', 'test1@example.com'),
('test_user_2', 'test2@example.com'),
('admin', 'admin@example.com')
ON CONFLICT (username) DO NOTHING;
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
amount NUMERIC(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO orders (user_id, amount, status) VALUES
(1, 99.99, 'completed'),
(1, 150.00, 'pending'),
(2, 45.50, 'completed');
2.4 启动与验证步骤
- 启动环境:
docker compose up -d --build - 检查服务状态:
docker compose ps确认三个容器均为Up (healthy) - 验证网络连通:
docker compose exec web ping -c 2 db - 验证数据库初始化:
docker compose exec db psql -U testuser -d testdb -c "SELECT * FROM users;" - 验证缓存可用:
docker compose exec cache redis-cli ping应返回PONG
常见问题:
• 端口冲突:宿主机 5432/6379 已被占用时,修改
• 初始化脚本未执行:检查
• 健康检查超时:若容器启动较慢,适当增加
• 端口冲突:宿主机 5432/6379 已被占用时,修改
ports 映射为宿主机其他端口(如 15432:5432)。• 初始化脚本未执行:检查
volumes 挂载路径是否正确,PostgreSQL 仅首次启动时执行 init 目录下的脚本。• 健康检查超时:若容器启动较慢,适当增加
interval 和 retries 参数。
2.5 环境清理与数据持久化
测试结束后,使用以下命令清理环境:
# 停止并移除容器、网络
docker compose down
# 同时删除数据卷(谨慎:会丢失所有测试数据)
docker compose down -v
# 仅重启服务(保留数据卷)
docker compose restart
| 命令 | 容器 | 网络 | 数据卷 | 适用场景 |
|---|---|---|---|---|
docker compose down |
删除 | 删除 | 保留 | 日常测试迭代,保留数据加速下次启动 |
docker compose down -v |
删除 | 删除 | 删除 | CI/CD 流水线,确保每次从干净状态开始 |
docker compose restart |
重启 | 保留 | 保留 | 修改配置后快速生效 |
2.6 集成测试环境验证清单
环境搭建完成后,执行以下快速验证,确保所有组件正常工作:
- Web 接口可达:
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health应返回200 - 数据库读写: 调用 POST
/api/users创建用户,再 GET/api/users/1验证数据持久化 - 缓存命中: 连续两次请求同一接口,第二次响应时间应显著降低(
X-Cache: HIT头) - 日志输出:
docker compose logs web应显示应用启动日志,无数据库连接错误
自动化集成: 将上述验证步骤写入
Makefile 或 scripts/verify_env.sh,在 CI 流水线中作为前置检查步骤,确保测试环境始终可用。