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

241 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "feat: GEO P1 — Migration Verification, Core Flow Integration Tests & Test Suite Stabilization"
type: feat
status: completed
date: 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.py``required_tables` 列表与实际 schema 严重不一致5+ 表名错误或不存在),`alembic.ini` 硬编码数据库密码,仅有一个初始迁移文件无法检测 schema drift
2. **核心业务流从未端到端跑通** — 30+ API 模块中仅认证/查询/引用/品牌/支付有集成测试,核心变现闭环(品牌→诊断→策略→内容→分发→监控)缺少深度集成验证
3. **测试套件不稳定** — 81 failed + 33 errors主要根因是 `app.dependency_overrides` 污染(测试间隔离失效)和 API 签名漂移(测试与实际接口不一致)
---
## Requirements
**数据库迁移验证**
R1. `test_database_migration.py``required_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.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` — 移除硬编码数据库 URL
- `backend/alembic/env.py` — 确认已从 settings 读取 DATABASE_URL
**Approach:**
1.`alembic/versions/a79329c23b20_initial_complete_schema.py` 中提取实际表名列表,替换 `required_tables`
2. `alembic.ini``sqlalchemy.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