⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议
Skip to content

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/data
bash
# 启动测试数据库
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 status
bash
# .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_URLdocker-composetmpfs环境隔离

本节小结

测试环境隔离的核心是确保测试永远不会触及生产数据。推荐使用独立数据库配合 Docker 的方案,既保证了隔离性,又兼顾了开发效率。记住:在测试代码中添加安全检查,是防止误操作的最后一道防线。