geo/docs/plans/2026-06-04-010-feat-geo-p1-...

11 KiB
Raw Permalink Blame History

title type status date
feat: GEO P1 — Migration Verification, Core Flow Integration Tests & Test Suite Stabilization feat completed 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 备案、支付商户)在审批中。当前阻塞生产信心的代码层面问题有三:

  1. 数据库迁移验证失效test_database_migration.pyrequired_tables 列表与实际 schema 严重不一致5+ 表名错误或不存在),alembic.ini 硬编码数据库密码,仅有一个初始迁移文件无法检测 schema drift
  2. 核心业务流从未端到端跑通 — 30+ API 模块中仅认证/查询/引用/品牌/支付有集成测试,核心变现闭环(品牌→诊断→策略→内容→分发→监控)缺少深度集成验证
  3. 测试套件不稳定 — 81 failed + 33 errors主要根因是 app.dependency_overrides 污染(测试间隔离失效)和 API 签名漂移(测试与实际接口不一致)

Requirements

数据库迁移验证

R1. test_database_migration.pyrequired_tables 列表与实际 schema 完全一致 R2. alembic.ini 不包含硬编码数据库密码,统一从环境变量读取 R3. alembic check 可正确检测模型与迁移的 driftdrift 存在时测试失败 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.pytest_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 — 移除硬编码数据库 URL
  • backend/alembic/env.py — 确认已从 settings 读取 DATABASE_URL

Approach:

  1. alembic/versions/a79329c23b20_initial_complete_schema.py 中提取实际表名列表,替换 required_tables
  2. alembic.inisqlalchemy.url 留空或使用占位符(env.py 已覆盖此值)
  3. 添加 test_alembic_check_detects_drift 测试:临时修改一个 model 字段,运行 alembic check,验证检测到 drift然后恢复
  4. 为所有需要真实数据库的测试添加 @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:

  1. 核心变现闭环 (test_core_monetization_flow.py):

    • 用户注册→登录→创建品牌→运行诊断→获取 GEO 方案→生成优化内容→创建分发计划→查看监控数据
    • 验证数据在各步骤间正确流转(品牌 ID 贯穿、诊断结果可被方案引用、内容关联到品牌)
    • 错误路径:品牌不存在返回 404、free 用户配额超限返回 403、用户间数据隔离
  2. 定时检测流 (test_detection_flow.py):

    • 创建检测任务→触发执行→查看结果→更新任务→删除任务
    • 验证任务状态机转换正确pending→running→completed/failed
  3. 内容分发流 (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 fixture
  • backend/tests/fixtures/database.py — 确认 session fixture 正确清理

Approach:

  1. conftest.py 中添加 @pytest.fixture(autouse=True)_cleanup_dependency_overrides fixture在 yield 后调用 app.dependency_overrides.clear()
  2. 检查现有测试中手动清理 dependency_overrides 的代码移除冗余清理autouse fixture 已覆盖)
  3. 验证:运行全量测试套件,确认无测试间污染

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:

  1. 运行全量测试,收集所有 FAILED 和 ERROR 测试
  2. 按错误类型分类import 错误、参数不匹配、返回值结构不匹配、fixture 缺失
  3. 批量修复同类错误(如同一服务的多个测试共享同一 mock 模式)
  4. 对于已废弃的 API 端点测试,删除而非维护
  5. 目标:全量失败数降至 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 → completed
  • docs/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

  1. alembic check 在 SQLite 环境下是否可用? — 如果不可用drift 检测测试需要标记为需要 PostgreSQL
  2. 核心变现链路中哪些服务方法已完整实现? — 需要在 U2 实现时逐个验证,未实现的标记 skip