11 KiB
| title | type | status | date |
|---|---|---|---|
| feat: GEO P1 — Migration Verification, Core Flow Integration Tests & Test Suite Stabilization | feat | active | 2026-06-04 |
GEO P1 — Migration Verification, Core Flow Integration Tests & Test Suite Stabilization
Summary
完成 P1 阶段三项核心工作:修复数据库迁移验证(required_tables 不匹配、alembic.ini 硬编码密码、单迁移文件 drift 检测)、补充核心变现链路深度集成测试(注册→品牌→诊断→策略→内容→分发→监控闭环)、清理剩余测试失败(测试隔离污染和 API 签名漂移)。完成后平台核心业务流可端到端跑通,测试套件稳定可依赖。
Problem Frame
Plan 008/009 的生产加固工作已完成,P0 外部事项(ICP 备案、支付商户)在审批中。当前阻塞生产信心的代码层面问题有三:
- 数据库迁移验证失效 —
test_database_migration.py中required_tables列表与实际 schema 严重不一致(5+ 表名错误或不存在),alembic.ini硬编码数据库密码,仅有一个初始迁移文件无法检测 schema drift - 核心业务流从未端到端跑通 — 30+ API 模块中仅认证/查询/引用/品牌/支付有集成测试,核心变现闭环(品牌→诊断→策略→内容→分发→监控)缺少深度集成验证
- 测试套件不稳定 — 81 failed + 33 errors,主要根因是
app.dependency_overrides污染(测试间隔离失效)和 API 签名漂移(测试与实际接口不一致)
Requirements
数据库迁移验证
R1. test_database_migration.py 中 required_tables 列表与实际 schema 完全一致
R2. alembic.ini 不包含硬编码数据库密码,统一从环境变量读取
R3. alembic check 可正确检测模型与迁移的 drift,drift 存在时测试失败
R4. 迁移测试在 CI 环境(无 PostgreSQL)中可正确 skip 而非 error
核心链路集成测试
R5. 品牌创建→诊断→GEO 方案→内容生成→分发→监控的完整闭环有深度集成测试 R6. 集成测试使用真实异步数据库会话(非 mock),验证数据在各模块间正确流转 R7. 集成测试覆盖关键错误路径(品牌不存在、配额超限、权限隔离)
测试套件稳定化
R8. app.dependency_overrides 在每个测试后正确清理,消除测试间污染
R9. API 测试中 mock 数据与实际接口签名一致,消除签名漂移导致的失败
R10. 全量测试运行失败数降至 20 以下
Key Technical Decisions
KTD1. 迁移测试采用"先修正 required_tables,再添加 drift 检测"策略。 修正 required_tables 是最小改动修复现有测试;添加 alembic check 测试确保未来 schema 变更不会遗漏迁移文件。不生成增量迁移文件 — 当前模型与单迁移文件一致,无需拆分。
KTD2. 核心链路集成测试使用 SQLite 内存数据库 + 真实异步会话。 与现有 test_full_flow.py 和 test_business_flow.py 保持一致,避免引入 PostgreSQL 测试依赖。对于 PostgreSQL 特有功能(ENUM 类型),在测试中用 String 替代或标记 skip。这确保 CI 可运行且测试速度不受数据库启动影响。
KTD3. 测试隔离采用 app.dependency_overrides 自动清理 fixture。 在 tests/conftest.py 中添加 autouse=True 的 cleanup fixture,确保每个测试后 app.dependency_overrides.clear() 被调用。这是最小侵入的修复方式,不需要修改每个测试文件。
KTD4. API 签名漂移采用"测试适配实际"策略。 不修改 API 实现来适应测试,而是修正测试中的 mock 数据和断言以匹配当前 API 签名。对于已废弃的 API 端点,删除对应测试而非维护死代码。
Implementation Units
U1. 修复数据库迁移测试
Goal: 修正 required_tables 列表、清理 alembic.ini 硬编码密码、添加 drift 检测测试
Requirements: R1, R2, R3, R4
Dependencies: none
Files:
backend/tests/test_infrastructure/test_database_migration.py— 修正 required_tables,添加 drift 检测测试backend/alembic.ini— 移除硬编码数据库 URLbackend/alembic/env.py— 确认已从 settings 读取 DATABASE_URL
Approach:
- 从
alembic/versions/a79329c23b20_initial_complete_schema.py中提取实际表名列表,替换required_tables alembic.ini中sqlalchemy.url留空或使用占位符(env.py已覆盖此值)- 添加
test_alembic_check_detects_drift测试:临时修改一个 model 字段,运行alembic check,验证检测到 drift,然后恢复 - 为所有需要真实数据库的测试添加
@pytest.mark.skipif条件(检查数据库连接可用性)
Test scenarios:
required_tables中每个表名在迁移文件中存在对应create_table调用alembic.ini不包含明文密码- drift 检测测试在 schema 不匹配时失败
- 无数据库连接时测试 skip 而非 error
Verification: pytest tests/test_infrastructure/test_database_migration.py --no-cov 全部通过或正确 skip
U2. 核心变现链路集成测试
Goal: 品牌创建→诊断→GEO 方案→内容生成→分发→监控的深度集成测试
Requirements: R5, R6, R7
Dependencies: U1(确保迁移测试不阻塞)
Files:
backend/tests/test_integration/test_core_monetization_flow.py— 新建,核心变现闭环测试backend/tests/test_integration/test_detection_flow.py— 新建,定时检测任务流测试backend/tests/test_integration/test_content_distribution_flow.py— 新建,内容生成→分发流测试
Approach:
-
核心变现闭环 (
test_core_monetization_flow.py):- 用户注册→登录→创建品牌→运行诊断→获取 GEO 方案→生成优化内容→创建分发计划→查看监控数据
- 验证数据在各步骤间正确流转(品牌 ID 贯穿、诊断结果可被方案引用、内容关联到品牌)
- 错误路径:品牌不存在返回 404、free 用户配额超限返回 403、用户间数据隔离
-
定时检测流 (
test_detection_flow.py):- 创建检测任务→触发执行→查看结果→更新任务→删除任务
- 验证任务状态机转换正确(pending→running→completed/failed)
-
内容分发流 (
test_content_distribution_flow.py):- 生成内容→创建分发计划→执行分发→查看分发状态
- 验证平台规则校验(min_tags/max_tags)
Patterns to follow: backend/tests/test_integration/test_business_flow.py(现有集成测试模式:async_session fixture + 真实服务调用 + 数据验证)
Test scenarios:
- 核心闭环:注册→品牌→诊断→方案→内容→分发→监控,每步数据正确传递
- 错误路径:品牌不存在 404、配额超限 403、权限隔离
- 检测任务:创建→触发→查看→更新→删除完整生命周期
- 内容分发:生成→分发→状态更新,平台规则校验生效
Verification: pytest tests/test_integration/ --no-cov 全部通过
U3. 测试隔离修复
Goal: 消除 app.dependency_overrides 污染,确保测试间完全隔离
Requirements: R8
Dependencies: none
Files:
backend/tests/conftest.py— 添加 autouse cleanup fixturebackend/tests/fixtures/database.py— 确认 session fixture 正确清理
Approach:
- 在
conftest.py中添加@pytest.fixture(autouse=True)的_cleanup_dependency_overridesfixture,在 yield 后调用app.dependency_overrides.clear() - 检查现有测试中手动清理
dependency_overrides的代码,移除冗余清理(autouse fixture 已覆盖) - 验证:运行全量测试套件,确认无测试间污染
Test scenarios:
- 两个使用不同
dependency_overrides的测试顺序运行,后者不受前者影响 - 全量运行与单独运行的测试结果一致
Verification: 全量 pytest tests/ --no-cov 失败数显著下降
U4. API 签名漂移修复
Goal: 修正测试中 mock 数据与实际 API 签名的不一致
Requirements: R9, R10
Dependencies: U3(先修复隔离问题,避免误判)
Files:
backend/tests/test_api/— 修正 mock 数据和断言backend/tests/test_services/— 修正服务层测试签名
Approach:
- 运行全量测试,收集所有 FAILED 和 ERROR 测试
- 按错误类型分类:import 错误、参数不匹配、返回值结构不匹配、fixture 缺失
- 批量修复同类错误(如同一服务的多个测试共享同一 mock 模式)
- 对于已废弃的 API 端点测试,删除而非维护
- 目标:全量失败数降至 20 以下
Test scenarios:
- 修复后的测试单独运行通过
- 修复后的测试在全量运行中通过(验证隔离修复有效)
Verification: pytest tests/ --no-cov 失败数 < 20
U5. Plan 008/009 状态关闭
Goal: 将已完成的 Plan 008 和 Plan 009 标记为 completed
Requirements: implicit
Dependencies: U1-U4
Files:
docs/plans/2026-06-04-008-chore-geo-production-readiness-plan.md— status: active → completeddocs/plans/2026-06-04-009-chore-geo-production-hardening-test-infra-plan.md— status: active → completed
Approach: 将两个计划文件的 frontmatter status 改为 completed
Test expectation: none — 文档变更
Verification: 文件中 status: completed
Scope Boundaries
In Scope
- 数据库迁移测试修复和 drift 检测
- 核心变现链路深度集成测试(3 个新测试文件)
- 测试隔离和 API 签名漂移修复
- Plan 008/009 状态关闭
Out of Scope
- P0 外部事项(ICP 备案、支付商户申请、域名部署)
- 全模块浅层冒烟测试(15+ 未覆盖模块的 1-2 个冒烟测试)
- 性能/负载测试(Locust/k6)
- 前端组件单元测试扩展
- 数据库增量迁移文件生成(当前模型与单迁移文件一致)
- Next.js 15 / Tailwind 4 升级
- 视觉回归测试
Deferred to Follow-Up Work
- 剩余 15+ API 模块的集成测试补充
- PostgreSQL 兼容性集成测试(需 Testcontainers 或真实 PG 实例)
- 性能基线测试
- 前端测试覆盖率提升
Risks & Dependencies
| 风险 | 影响 | 缓解 |
|---|---|---|
| SQLite 与 PostgreSQL 行为差异 | 集成测试可能无法捕获 PG 特有问题 | 核心业务逻辑不依赖 PG 特有功能;ENUM 类型在测试中用 String 替代 |
| API 签名漂移修复量大 | 81+ 失败需逐个分析 | 按错误类型批量修复,优先修复影响最多的模式 |
dependency_overrides 清理可能破坏部分测试 |
某些测试可能依赖前一个测试的 override | 逐个验证,必要时调整测试顺序 |
| 核心链路测试依赖的服务可能未完全实现 | 某些服务方法可能是 stub | 测试中标记 @pytest.mark.skip 并记录 TODO |
Open Questions
alembic check在 SQLite 环境下是否可用? — 如果不可用,drift 检测测试需要标记为需要 PostgreSQL- 核心变现链路中哪些服务方法已完整实现? — 需要在 U2 实现时逐个验证,未实现的标记 skip