ad06fe7de4
Consolidate backend modules/tests under the backend package while syncing Supabase compose/env config and related plans.
4.6 KiB
4.6 KiB
测试数据隔离方案(Supabase + Python 后端)
背景现状
- 后端在
backend/src/core/config/settings.py使用SOCIAL_DATABASE__*生成database_url。 - 本地 Supabase 通过
supabase-db容器提供 Postgres,宿主端口由SOCIAL_DATABASE__PORT控制(默认映射到容器 5432)。 - 注意:
supabase-pooler的 5432 仅用于连接池;测试与迁移应直连supabase-db的宿主端口。 - 单元数据库测试目前使用 SQLite 内存库(见
tests/unit/database/*),不影响开发库。 - 真实 Postgres 的集成/E2E 当前未统一隔离策略;当开始接入真实 DB 时,需要按本文方案隔离与清理。
目标
- 测试过程不污染开发数据。
- 测试可重复、可并行、可在本地与 CI 稳定运行。
- 变更成本可控,优先在现有架构上落地。
结论(适配本项目)
采用“事务回滚 + 独立测试数据库”的混合策略:
- 默认测试使用事务回滚,快速、零污染(适用于单连接/单事务场景)。
- 需要真实提交、并发或触发器行为的测试使用独立测试数据库。
方案设计
A. 事务回滚(默认)
适用:单元测试、绝大多数集成测试(当这些测试连接真实 Postgres 时)。
核心思路:
- 每个测试在事务中运行。
- 测试结束自动回滚。
优点:
- 速度快,无需新增数据库。
- 测试间完全隔离。
限制:
- 无法验证真实 COMMIT 结果。
- 并发、多连接事务隔离测试不准确。
B. 独立测试数据库(E2E/并发)
适用:E2E、并发、触发器、LISTEN/NOTIFY 等需要真实提交的场景。
核心思路:
- 在现有 Supabase Postgres 实例中创建独立数据库。
- 测试使用专用
SOCIAL_DATABASE__NAME连接,端口/账号/密码来自SOCIAL_DATABASE__*。 - 测试前应用迁移,测试后清理。
优点:
- 行为最接近真实环境。
- 与开发数据完全隔离。
成本:
- 需要迁移与清理策略。
与现有测试模块的衔接
tests/unit/database/*已使用 SQLite 内存库,无需改造。- 未来若
tests/integration/*或tests/e2e/*连接真实 Postgres,应切换到本文的测试库策略。 - 使用
SOCIAL_DATABASE__NAME=postgres_test启动测试,以避免污染开发库。
实施步骤(与项目当前结构对齐)
1) 创建独立测试数据库
在本地 Supabase 容器中创建测试库:
docker exec -e PGPASSWORD="$SOCIAL_DATABASE__PASSWORD" supabase-db \
psql -U "$SOCIAL_DATABASE__USER" -c "CREATE DATABASE postgres_test;"
说明:
- 容器名为
supabase-db(已在infra/docker运行)。 - 数据库名建议
postgres_test,与.env的SOCIAL_DATABASE__NAME=postgres区分。
2) 运行迁移到测试库
使用测试环境变量指向测试库后,应用 Alembic 迁移:
SOCIAL_RUNTIME__ENVIRONMENT=test \
SOCIAL_DATABASE__NAME=postgres_test \
uv run alembic upgrade head
说明:
- 执行位置:
/home/qzl/Code/social-app/backend。 - 仍使用当前
.env中的SOCIAL_DATABASE__HOST与SOCIAL_DATABASE__PORT。
3) 事务回滚测试(默认)
测试执行时注入事务回滚机制:
- 在测试会话层创建单连接事务。
- 对每个测试用例使用 SAVEPOINT(或嵌套事务)。
- 测试结束回滚到 SAVEPOINT。
这套策略可保持速度与隔离性,同时不需要额外数据库。
4) 独立测试数据库执行(E2E/并发)
对于需要真实提交的测试,使用测试库运行:
SOCIAL_RUNTIME__ENVIRONMENT=test \
SOCIAL_DATABASE__NAME=postgres_test \
uv run pytest tests/e2e
清理策略(二选一):
- 小规模测试:TRUNCATE public schema 的业务表(不影响
auth等系统 schema)。 - 大规模测试:
DROP DATABASE postgres_test;后重建并迁移。
5) 本地/CI 统一策略
- 本地默认:事务回滚。
- CI:独立测试库(保证完全隔离、无隐式依赖)。
风险与规避
- 不要在清理时操作
auth、storage等 Supabase 系统 schema。 - E2E 使用独立数据库,避免与开发数据交叉。
- 迁移必须由 Alembic 统一维护,禁止手动改库。
落地检查清单
- 已创建
postgres_test数据库。 - 测试库迁移已应用。
- 事务回滚测试已接入(默认路径)。
- E2E 使用测试库运行。
- 清理策略执行脚本可复用。
备注
本方案基于当前项目的 Supabase 本地 Docker 结构与后端配置方式(SOCIAL_DATABASE__*)。
无需变更 Supabase 组件,优先在测试层完成隔离与清理。