docs: add P1 plan - migration verification, core flow tests, test stabilization

This commit is contained in:
chiguyong 2026-06-04 22:12:42 +08:00
parent 79139bc504
commit 7404d08ad1
1 changed files with 240 additions and 0 deletions

View File

@ -0,0 +1,240 @@
---
title: "feat: GEO P1 — Migration Verification, Core Flow Integration Tests & Test Suite Stabilization"
type: feat
status: active
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