From 7404d08ad11abd97a46d93fb33440a9ded9e5eb5 Mon Sep 17 00:00:00 2001 From: chiguyong Date: Thu, 4 Jun 2026 22:12:42 +0800 Subject: [PATCH] docs: add P1 plan - migration verification, core flow tests, test stabilization --- ...ration-coreflow-test-stabilization-plan.md | 240 ++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 docs/plans/2026-06-04-010-feat-geo-p1-migration-coreflow-test-stabilization-plan.md diff --git a/docs/plans/2026-06-04-010-feat-geo-p1-migration-coreflow-test-stabilization-plan.md b/docs/plans/2026-06-04-010-feat-geo-p1-migration-coreflow-test-stabilization-plan.md new file mode 100644 index 0000000..9dedd8a --- /dev/null +++ b/docs/plans/2026-06-04-010-feat-geo-p1-migration-coreflow-test-stabilization-plan.md @@ -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` 可正确检测模型与迁移的 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` — 移除硬编码数据库 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