# 测试数据隔离方案(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 容器中创建测试库: ```bash 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 迁移: ```bash 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/并发) 对于需要真实提交的测试,使用测试库运行: ```bash 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 组件,优先在测试层完成隔离与清理。