9.2.1 测试不能影响生产——测试环境配置:独立的数据库与服务
测试环境与生产环境的隔离程度,决定了你的数据安全底线。
隔离策略对比
| 方案 | 隔离程度 | 成本 | 推荐场景 |
|---|---|---|---|
| 独立数据库 | 高 | 中 | 团队开发 |
| 独立 Schema | 中 | 低 | 个人开发 |
| Docker 容器 | 最高 | 低 | CI/CD |
方案一:独立数据库(推荐)
PostgreSQL 配置
sql
-- 创建测试数据库
CREATE DATABASE myapp_test;
-- 创建测试用户(可选,更安全)
CREATE USER test_user WITH PASSWORD 'test_password';
GRANT ALL PRIVILEGES ON DATABASE myapp_test TO test_user;Prisma 配置
prisma
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}bash
# .env.test
DATABASE_URL="postgresql://test_user:test_password@localhost:5432/myapp_test"
# .env.development
DATABASE_URL="postgresql://dev_user:dev_password@localhost:5432/myapp_dev"
# .env.production
DATABASE_URL="postgresql://prod_user:prod_password@prod-host:5432/myapp_prod"方案二:Docker 容器(CI/CD 首选)
使用 Docker Compose 为测试创建临时数据库:
yaml
# docker-compose.test.yml
version: '3.8'
services:
test-db:
image: postgres:15-alpine
environment:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: myapp_test
ports:
- "5433:5432"
tmpfs:
- /var/lib/postgresql/databash
# 启动测试数据库
docker-compose -f docker-compose.test.yml up -d
# 运行测试
DATABASE_URL="postgresql://test:test@localhost:5433/myapp_test" npm test
# 销毁测试数据库
docker-compose -f docker-compose.test.yml down使用 tmpfs 加速测试
tmpfs 将数据存储在内存中,显著提升测试速度:
yaml
services:
test-db:
# ...
tmpfs:
- /var/lib/postgresql/data # 数据存内存,容器销毁即清除方案三:使用 Supabase 本地实例
bash
# 安装 Supabase CLI
npm install -g supabase
# 初始化本地 Supabase
supabase init
# 启动本地实例(包含独立的 PostgreSQL)
supabase start
# 获取连接信息
supabase statusbash
# .env.test
DATABASE_URL="postgresql://postgres:postgres@localhost:54322/postgres"隔离外部服务
除了数据库,还需要隔离其他外部服务:
typescript
// lib/config.ts
export const config = {
// 数据库
databaseUrl: process.env.DATABASE_URL!,
// 外部 API
stripeKey: process.env.STRIPE_KEY!,
sendgridKey: process.env.SENDGRID_KEY!,
// 判断是否测试环境
isTest: process.env.NODE_ENV === 'test',
};
// 测试环境使用 Mock
export function getStripe() {
if (config.isTest) {
return createMockStripe();
}
return new Stripe(config.stripeKey);
}bash
# .env.test
NODE_ENV=test
STRIPE_KEY=sk_test_xxx # 使用测试模式的 Key
SENDGRID_KEY= # 留空,测试中不发邮件验证隔离有效性
typescript
// test/setup.ts
beforeAll(() => {
// 安全检查:确保不在生产环境运行测试
if (process.env.NODE_ENV === 'production') {
throw new Error('不能在生产环境运行测试!');
}
// 检查数据库 URL 是否包含 "_test"
const dbUrl = process.env.DATABASE_URL || '';
if (!dbUrl.includes('_test') && !dbUrl.includes('localhost')) {
throw new Error('测试数据库配置错误:URL 应包含 _test 或指向 localhost');
}
});常见错误及解决方案
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 测试影响生产数据 | 环境变量配置错误 | 添加安全检查 |
| 测试运行缓慢 | 使用远程数据库 | 改用本地/Docker |
| 并行测试冲突 | 共享同一数据库 | 使用事务回滚 |
| CI 测试失败 | 缺少数据库服务 | 配置 Docker 服务 |
AI 协作指南
配置测试环境时,可以这样与 AI 沟通:
核心意图:配置独立的测试环境
需求定义公式:
帮我配置测试环境: - 数据库类型:[PostgreSQL/MySQL/SQLite] - 隔离方式:[独立数据库/Docker/Schema] - 需要隔离的服务:[Stripe/SendGrid/...]
关键术语:DATABASE_URL、docker-compose、tmpfs、环境隔离
本节小结
测试环境隔离的核心是确保测试永远不会触及生产数据。推荐使用独立数据库配合 Docker 的方案,既保证了隔离性,又兼顾了开发效率。记住:在测试代码中添加安全检查,是防止误操作的最后一道防线。
