# 测试策略设计文档：基于 Docker 环境的组件测试与 Orchestrator 逻辑验证

> **文档使用说明**:
> 本文档不仅作为测试设计方案，也是测试实施过程中的**Living Document (活文档)**。
> 请参阅第 4 节 "执行状态追踪 (Execution Status Tracking)" 了解当前进度、Milestones 和 Pending Tasks。
> 在每次完成重要步骤后，请更新此文档的状态部分。

## 1. 策略概述 (Strategy Overview)

响应“无 Mock、全真实环境”的要求，结合“Rustic 强类型”设计原则，我们将采用 **混合测试策略 (Hybrid Strategy)**：

1.  **I/O 密集型服务 (Providers & ReportGen)**: 采用 **基于 Docker Compose 的组件集成测试**。
    *   直接连接真实的 Postgres, NATS 和第三方 API (Alphavantage/LLM)。
    *   验证“端到端”的功能可用性（Key 是否有效、数据格式是否兼容）。
2.  **逻辑密集型服务 (Orchestrator)**: 采用 **基于 Trait 的内存测试 (In-Memory Testing)**。
    *   通过 Trait 抽象外部依赖，使用简单的内存实现 (Fake) 替代真实服务。
    *   实现毫秒级反馈，覆盖复杂的状态机跳转和边界条件。

---

## 2. 实施阶段 (Implementation Phases)

### Phase 1: 测试基础设施 (Infrastructure)

*   **Docker Environment**: `docker-compose.test.yml`
    *   `postgres-test`: 端口 `5433:5432`
    *   `nats-test`: 端口 `4223:4222`
    *   `persistence-test`: 端口 `3001:3000` (Data Persistence Service 本身也视作基础设施的一部分)
*   **Abstraction (Refactoring)**:
    *   在 `workflow-orchestrator-service` 中定义 `WorkflowRepository` 和 `CommandPublisher` traits，用于解耦逻辑测试。

### Phase 2: 微服务组件测试 (IO-Heavy Services)
**执行方式**: 宿主机运行 `cargo test`，环境变量指向 Phase 1 启动的 Docker 端口。

#### 1. Data Providers (数据源)
验证从 API 获取数据并存入系统的能力。
*   **Alphavantage Provider**: (Key: `alphaventage_key`)
    *   Input: `FetchCompanyDataCommand`
    *   Assert: DB 中存入 SessionData (Profile/Financials)，NATS 发出 `FinancialsPersistedEvent`。
*   **Tushare Provider**: (Key: `tushare_key`)
    *   Input: `FetchCompanyDataCommand` (CN Market)
    *   Assert: 同上。
*   **Finnhub Provider**: (Key: `finnhub_key`)
    *   Input: `FetchCompanyDataCommand`
    *   Assert: 同上。
*   **YFinance Provider**: (No Key)
    *   Input: `FetchCompanyDataCommand`
    *   Assert: 同上。

#### 2. Report Generator (报告生成器)
验证从 Persistence 读取数据并调用 LLM 生成报告的能力。
*   **Key**: `openrouter_key` (Model: `google/gemini-flash-1.5` 或其他低成本模型)
*   **Pre-condition**: 需要先往 Persistence (localhost:3001) 插入一些伪造的 SessionData (Financials/Price)，否则 LLM 上下文为空。
*   **Input**: `GenerateReportCommand`
*   **Logic**: 
    1.  Service 从 Persistence 读取数据。
    2.  Service 组装 Prompt 调用 OpenRouter API。
    3.  Service 将生成的 Markdown 存回 Persistence。
*   **Assert**: 
    *   NATS 收到 `ReportGeneratedEvent`。
    *   Persistence 中能查到 `analysis_report` 类型的 SessionData，且内容非空。

### Phase 3: Orchestrator 逻辑测试 (Logic-Heavy)
**执行方式**: 纯内存单元测试，无需 Docker。

*   **Refactoring**: 将 Orchestrator 的核心逻辑 `WorkflowEngine` 修改为接受 `Box<dyn WorkflowRepository>` 和 `Box<dyn CommandPublisher>`。
*   **Test Suite**:
    *   **DAG Construction**: 给定不同 Template ID，验证生成的 DAG 结构（依赖关系）是否正确。
    *   **State Transition**: 
        *   Scenario 1: Happy Path (所有 Task 成功 -> Workflow 完成)。
        *   Scenario 2: Dependency Failure (上游失败 -> 下游 Skipped)。
        *   Scenario 3: Resume (模拟服务重启，从 Repository 加载状态并继续)。
    *   **Policy Check**: 验证 "At least one provider" 策略是否生效。

### Phase 4: 全链路验收测试 (E2E)
**执行方式**: `scripts/run_e2e.sh` (Docker + Rust Test Runner)

*   **配置策略**:
    *   动态注入测试配置 (`setup_test_environment`): 
        *   注册 `simple_test_analysis` 模板。
        *   配置 LLM Provider (`openrouter`/`new_api`) 使用 `google/gemini-2.5-flash-lite`。
*   **超时控制**:
    *   SSE 连接监听设置 60秒硬性超时，防止长连接假死。
*   **Scenarios**:
    *   **Scenario A (Happy Path)**: 使用 `simple_test_analysis` 模板完整运行。
    *   **Scenario B (Recovery)**: 模拟 Orchestrator 重启，验证状态恢复。 (SKIPPED: Requires DB Persistence)
    *   **Scenario C (Partial Failure)**: 模拟非关键 Provider (Tushare) 故障，验证工作流不受影响。
    *   **Scenario D (Invalid Input)**: 使用无效 Symbol，验证错误传播和快速失败。
    *   **Scenario E (Module Failure)**: 模拟 Analysis 模块内部错误（如配置错误），验证工作流终止。
    *   **Status**: ✅ Completed (2025-11-21)

---

## 3. 执行计划 (Action Plan)

1.  **Environment**: 创建 `docker-compose.test.yml` 和控制脚本。 ✅
2.  **Providers Test**: 编写 4 个 Data Provider 的集成测试。 ✅
3.  **ReportGen Test**: 编写 Report Generator 的集成测试（含数据预埋逻辑）。 ✅
4.  **Orchestrator Refactor**: 引入 Traits 并编写内存测试。 ✅
5.  **Final Verification**: 运行全套测试。 ✅

---

## 4. 执行状态追踪 (Execution Status Tracking)

### 当前状态 (Current Status)
*   **日期**: 2025-11-21
*   **阶段**: Phase 4 - E2E Testing Completed
*   **最近活动**: 
    *   修复了测试模板配置错误导致 Scenario A 超时的问题。
    *   修复了 Orchestrator 错误广播 Analysis 失败导致 Scenario C 误判的问题。
    *   完整验证了 Scenario A, C, D, E。
    *   暂时跳过 Scenario B (待持久化层就绪后启用)。

### 历史记录 (Milestones)
| 日期 | 阶段 | 事件/变更 | 状态 |
| :--- | :--- | :--- | :--- |
| 2025-11-20 | Planning | 完成测试策略文档编写，确定混合测试方案。 | ✅ Completed |
| 2025-11-20 | Phase 1 | 创建 `docker-compose.test.yml` 和基础设施。 | ✅ Completed |
| 2025-11-20 | Phase 2 | 完成 Data Providers 集成测试代码。 | ✅ Completed |
| 2025-11-20 | Phase 2 | 完成 Report Generator 集成测试代码。 | ✅ Completed |
| 2025-11-20 | Phase 3 | 完成 Orchestrator 重构与内存测试。 | ✅ Completed |
| 2025-11-21 | Phase 4 | 修复 SSE 超时问题，增加动态配置注入。 | ✅ Completed |
| 2025-11-21 | Phase 4 | 实现并验证异常场景 (Partial Failure, Invalid Input, Module Error)。 | ✅ Completed |

### 待处理项 (Next Steps)
- [ ] **Persistence**: 为 Orchestrator 引入 Postgres 存储，启用 Scenario B。
- [ ] **CI Integration**: 将 `run_e2e.sh` 集成到 CI 流水线。

## 5. 未来展望 (Future Outlook)

随着系统演进，建议增加以下测试场景：

1.  **Network Resilience (网络分区)**: 
    *   使用 `toxiproxy` 或 Docker Network 操作模拟网络中断。
    *   验证服务的重试机制 (Retry Policy) 和幂等性。
2.  **Concurrency & Load (并发与负载)**:
    *   同时启动 10+ 个工作流，验证 Orchestrator 调度和 Provider 吞吐量。
    *   验证 Rate Limiting 是否生效（避免被上游 API 封禁）。
3.  **Long-Running Workflows (长流程)**:
    *   测试包含数十个步骤、运行时间超过 5 分钟的复杂模板。
    *   验证 SSE 连接保活和超时处理。
4.  **Data Integrity (数据一致性)**:
    *   验证 Fetch -> Persistence -> Report Gen 链路中的数据精度（小数位、时区）。
