# 财顾报告Agent MVP 测试分析文档
> 分析依据:
> - 《财顾报告智能化生成产品MVP版本需求文档.md》
> - 《财顾报告Agent-技术架构与选型.md》
> - 《财顾报告生成智能体后端及算法端功能模块描述及其实现思路.md》
---
## 1. 测试范围与不测范围
### 1.1 测试范围
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 本期测试范围 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【功能测试】 │
│ ├── 任务管理:创建、查询、状态流转 │
│ ├── 大纲生成:L1生成、L2生成、JSON结构化输出 │
│ ├── 大纲确认:树状展示、勾选/取消、排序、确认持久化 │
│ ├── 数据准备:多源数据获取(工商/指标/RAG)、数据聚合 │
│ ├── 数据确认:展示、文本补录、确认持久化 │
│ ├── 报告生成:逐段生成、顺序拼接、完整报告 │
│ └── 结果导出:DOCX格式导出 │
│ │
│ 【接口测试】 │
│ ├── Java后端API:任务/大纲/数据/报告接口 │
│ ├── Java→Python契约:大纲生成/段落生成接口 │
│ └── Python→模型:OpenAI兼容接口 │
│ │
│ 【集成测试】 │
│ ├── 前端→Java→Python端到端链路 │
│ ├── Java→行内数据源(工商/指标) │
│ ├── Python→模型集群 │
│ └── Python→向量库(RAG) │
│ │
│ 【非功能测试】 │
│ ├── 性能测试:核心接口响应时间、生成任务吞吐量 │
│ ├── 并发测试:多租户隔离、并发任务执行 │
│ └── 安全测试:鉴权、租户隔离、敏感数据脱敏 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 1.2 不测范围
| 模块 | 说明 | 原因 |
|------|------|------|
| 配置端功能 | 知识体系配置页面 | 本期不建设,后台预置实现 |
| 数据资源配置 | 接口参数在线配置 | 本期不建设,代码绑定实现 |
| 段落级重生成 | 单段内容重新生成 | 本期不纳入,预留扩展 |
| 富文本编辑 | 报告在线精细编辑 | 本期简化,仅查看导出 |
| 复杂协同 | 多人协作、审核流 | 本期不纳入 |
| 浏览器兼容性 | IE等非现代浏览器 | 聚焦Chrome/Edge最新版 |
| 移动端适配 | 手机端页面 | 聚焦桌面端 |
---
## 2. 测试策略
### 2.1 测试金字塔
```
▲
/ \
/ E2E \ 端到端测试 (10%)
/ 测试 \ - 完整链路验证
/─────────\ - 用户场景模拟
/ \
/ 集成测试 \ 集成测试 (30%)
/ \ - 模块间接口
/─────────────────\ - 外部系统集成
/ \
/ 单元测试 \ 单元测试 (60%)
/ \ - 核心业务逻辑
/─────────────────────────\ - 工具函数
/ \
─────────────────────────────
```
### 2.2 分阶段测试策略
| 阶段 | 测试类型 | 目标 | 执行时机 |
|------|----------|------|----------|
| **开发自测** | 单元测试 | 代码质量保障,快速反馈 | 开发过程中 |
| **联调测试** | 接口+集成测试 | 模块间协作正常 | 模块开发完成后 |
| **系统测试** | 功能+E2E测试 | 完整功能可用 | 联调完成后 |
| **回归测试** | 冒烟+核心流程 | 新改动不影响已有功能 | 每次合并前/发布后 |
| **验收测试** | 业务场景测试 | 满足业务需求 | 上线前 |
### 2.3 自动化策略
```yaml
自动化优先级:
P0(必须自动化):
- 任务状态机流转
- 大纲生成API契约
- 租户隔离核心用例
- 完整链路冒烟测试
P1(建议自动化):
- 数据准备多源聚合
- 报告生成段落拼接
- 导出功能
P2(可手工):
- UI交互细节
- 复杂边界场景
- 模型输出质量评估
自动化工具:
Java单元测试: JUnit 5 + Mockito
Python单元测试: pytest
API测试: REST Assured / pytest-requests
E2E测试: Playwright / Cypress
```
---
## 3. 核心测试用例矩阵
### 3.1 功能测试用例
#### TC-任务管理
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-TASK-001 | 创建项目融资报告任务 | 已登录 | 1.选择项目融资
2.填写必填字段
3.提交 | 任务创建成功,返回taskId,状态=PENDING_OUTLINE | P0 |
| TC-TASK-002 | 创建资产管理报告任务 | 已登录 | 同上,选择资产管理 | 同上 | P0 |
| TC-TASK-003 | 创建并购重组报告任务 | 已登录 | 同上,选择并购重组 | 同上 | P0 |
| TC-TASK-004 | 必填字段缺失 | 已登录 | 不填写必填字段直接提交 | 返回明确错误提示,任务未创建 | P0 |
| TC-TASK-005 | 查询任务列表 | 存在任务 | 调用查询接口 | 返回租户下任务列表,分页正确 | P1 |
| TC-TASK-006 | 查询任务详情 | 任务存在 | 调用详情接口 | 返回完整任务信息,含当前状态 | P0 |
#### TC-大纲生成
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-OUT-001 | 生成一级大纲 | 任务已创建 | 调用L1生成接口 | 返回JSON,含chapter_results和overall_logic | P0 |
| TC-OUT-002 | 一级大纲JSON结构校验 | - | 验证返回JSON字段 | 字段完整,类型正确,无缺漏 | P0 |
| TC-OUT-003 | 协议金额约束验证 | - | 测试<50万、50-100万、100-500万、>=500万 | 各档位返回合理的paragraph_count_enum分布 | P1 |
| TC-OUT-004 | 生成二级大纲 | L1已完成 | 调用L2生成接口 | 返回完整章节编号树 | P0 |
| TC-OUT-005 | 二级大纲批次展开 | 存在批次处理型章节 | 提供多个集团板块 | 按对象正确展开子章节 | P0 |
| TC-OUT-006 | 大纲生成超时处理 | - | 模拟模型超时 | 返回超时错误,状态不异常 | P1 |
| TC-OUT-007 | 大纲生成失败重试 | - | 模拟模型返回格式错误 | 触发重试,最终返回错误或成功 | P1 |
#### TC-大纲确认
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-CFM-001 | 确认默认选中 | 二级大纲已生成 | 不做调整直接确认 | 保存最终知识单元清单,状态推进 | P0 |
| TC-CFM-002 | 取消勾选知识单元 | - | 取消部分已勾选 | 确认结果不包含取消项 | P0 |
| TC-CFM-003 | 新增勾选知识单元 | - | 勾选未选中的 | 确认结果包含新增项 | P0 |
| TC-CFM-004 | 调整知识单元顺序 | - | 拖拽调整顺序 | 确认结果顺序正确 | P1 |
| TC-CFM-005 | 尝试新增未配置单元 | - | 尝试添加体系外单元 | 系统拒绝,给出提示 | P0 |
| TC-CFM-006 | 确认后状态推进 | - | 确认提交 | 状态变为PENDING_DATA_PREPARE | P0 |
#### TC-数据准备
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-DATA-001 | 获取工商数据 | 大纲已确认 | 调用数据准备 | 返回工商接口数据 | P0 |
| TC-DATA-002 | 获取指标平台数据 | - | - | 返回指标数据 | P0 |
| TC-DATA-003 | RAG召回 | 已上传材料 | - | 返回相关文本片段 | P0 |
| TC-DATA-004 | 多源数据聚合 | - | - | 各知识单元数据正确组织 | P0 |
| TC-DATA-005 | 数据获取失败处理 | 接口故障 | 模拟接口失败 | 记录失败,可继续文本补录 | P1 |
| TC-DATA-006 | 文本补录 | 数据已获取 | 添加补录文本 | 补录内容与自动数据合并 | P0 |
#### TC-报告生成
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-GEN-001 | 单段生成 | 数据已确认 | 调用段落生成 | 返回段落文本,Token使用正常 | P0 |
| TC-GEN-002 | 整篇报告生成 | - | 执行完整生成 | 按顺序拼接所有段落 | P0 |
| TC-GEN-003 | 四类模板生成 | - | 分别测试四种模板类型 | 输出符合各自约束 | P1 |
| TC-GEN-004 | 单段生成失败 | - | 模拟模型失败 | 可重试或跳过,记录失败 | P1 |
| TC-GEN-005 | 生成进度展示 | - | 执行长报告生成 | 前端能看到进度更新 | P1 |
| TC-GEN-006 | 生成后状态 | - | 完成生成 | 状态变为COMPLETED | P0 |
#### TC-结果导出
| 用例ID | 用例名称 | 前置条件 | 测试步骤 | 预期结果 | 优先级 |
|--------|----------|----------|----------|----------|--------|
| TC-EXP-001 | 在线查看报告 | 报告已生成 | 打开查看页面 | 正确显示章节段落结构 | P0 |
| TC-EXP-002 | 导出DOCX | - | 点击导出 | 下载DOCX文件,格式正确 | P0 |
| TC-EXP-003 | 大报告导出 | 报告很长 | 执行导出 | 异步处理,完成后通知 | P1 |
### 3.2 接口测试用例
#### Java后端API
| 接口 | 方法 | 测试场景 | 预期结果 |
|------|------|----------|----------|
| /api/v1/tasks | POST | 正常创建 | 201, 返回taskId |
| /api/v1/tasks | POST | 参数缺失 | 400, 错误信息明确 |
| /api/v1/tasks | POST | 无权限 | 403 |
| /api/v1/tasks/{id} | GET | 正常查询 | 200, 完整任务信息 |
| /api/v1/tasks/{id} | GET | 跨租户访问 | 404/403 |
| /api/v1/tasks/{id}/outline/l1 | POST | 触发一级生成 | 202, 异步处理 |
| /api/v1/tasks/{id}/outline/confirm | POST | 确认大纲 | 200, 状态推进 |
| /api/v1/tasks/{id}/data | GET | 获取数据 | 200, 按知识单元组织 |
| /api/v1/tasks/{id}/data/confirm | POST | 确认数据 | 200, 状态推进 |
| /api/v1/tasks/{id}/generate | POST | 触发生成 | 202, 异步处理 |
| /api/v1/tasks/{id}/report | GET | 查看报告 | 200, 报告内容 |
| /api/v1/tasks/{id}/export | POST | 导出报告 | 202/200, 文件下载 |
#### Java→Python契约
| 接口 | 测试重点 | 检查项 |
|------|----------|--------|
| POST /v1/outline/l1 | 请求完整性 | 所有必需字段存在 |
| | 响应格式 | JSON结构符合契约 |
| | 枚举值 | paragraph_count_enum只能是P0-P4 |
| POST /v1/outline/l2 | 批次展开 | batch类型正确展开 |
| | 章节编号 | 编号格式正确,连续无跳号 |
| POST /v1/section | 模板类型 | 四类模板正确路由 |
| | 数据注入 | 占位符正确替换 |
---
## 4. 边界与异常场景
### 4.1 边界场景
| 场景 | 描述 | 预期行为 |
|------|------|----------|
| 超大协议金额 | >=500万,需要40-50段 | 系统正确处理,不超模型上下文 |
| 超多集团板块 | 10+业务板块需要批次展开 | 正确展开所有板块,编号连续 |
| 超长报告 | 50+知识单元 | 异步生成,进度可查询 |
| 空知识单元清单 | 用户取消所有章节 | 给出提示,无法进入下一阶段 |
| 全P0一级大纲 | 模型判断全部不呈现 | 给出提示,人工介入 |
### 4.2 异常场景
| 异常 | 触发条件 | 预期处理 |
|------|----------|----------|
| **模型调用超时** | 模型响应超过阈值 | 返回超时错误,可重试,状态不变 |
| **模型返回格式错误** | JSON解析失败 | 重试3次,仍失败则返回错误 |
| **模型拒绝服务** | 429/503错误 | 指数退避重试,降级到备用模型 |
| **行内接口超时** | 工商/指标接口慢 | 超时后返回部分数据,可补录 |
| **行内接口故障** | 接口返回5xx | 记录失败,继续其他数据源 |
| **数据库连接失败** | 数据库不可用 | 返回500,不丢失已生成数据 |
| **并发冲突** | 同一任务多操作 | 分布式锁保护,后操作被拒绝 |
| **跨租户访问** | A租户访问B租户任务 | 404处理,日志记录 |
### 4.3 模型输出质量边界
```python
# 模型输出质量检查点
def validate_model_output(output: str, expected_type: str) -> ValidationResult:
checks = {
"json_valid": is_valid_json(output),
"schema_match": validate_json_schema(output, expected_type),
"no_analysis_words": not contains_words(output, ["因此", "可以看出"]), # 信息陈述型
"no_comparison": not contains_words(output, ["更适合", "优于"]), # 对象分析型
"data_only": not contains_attribution(output), # 指标数据描述型
"no_new_decision": not contains_new_proposal(output), # 综合判断型
}
return ValidationResult(passed=all(checks.values()), details=checks)
```
---
## 5. 非功能测试要点
### 5.1 性能测试
| 指标 | 目标值 | 测试方法 |
|------|--------|----------|
| 任务创建 | <500ms | JMeter 100并发 |
| 一级大纲生成 | <30s | 单用户,模型实际调用 |
| 二级大纲生成 | <60s | 单用户,多章节 |
| 单段生成 | <30s | 单用户,不同模板 |
| 整篇报告生成(30段) | <5min | 单用户,端到端 |
| 页面加载 | <2s | Lighthouse |
| 并发任务数 | 10+ | 10租户各1任务并行 |
### 5.2 并发与隔离测试
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 并发测试场景 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 场景1: 同租户并发 │
│ ├── 同一用户同时创建多个任务 │
│ └── 预期: 各任务独立,状态不干扰 │
│ │
│ 场景2: 多租户并发 │
│ ├── 不同租户同时执行任务 │
│ └── 预期: 数据严格隔离,无串扰 │
│ │
│ 场景3: 同任务并发操作 │
│ ├── 同一任务同时触发多次生成 │
│ └── 预期: 分布式锁保护,后操作被拒绝 │
│ │
│ 场景4: 资源竞争 │
│ ├── 多个任务同时请求Python服务 │
│ └── 预期: 队列处理或优雅降级 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 5.3 安全测试
| 测试项 | 测试方法 | 预期结果 |
|--------|----------|----------|
| 未授权访问 | 不带Token访问API | 401拒绝 |
| Token过期 | 使用过期Token | 401拒绝 |
| 跨租户访问 | 修改tenantId访问其他租户数据 | 404/403 |
| SQL注入 | 输入SQL特殊字符 | 参数化查询,无注入 |
| XSS | 输入脚本标签 | 转义输出,无执行 |
| 敏感数据泄露 | 检查Python请求 | 脱敏字段不下传 |
| OSS权限 | 直接访问OSS路径 | 需预签名URL |
---
## 6. 质量风险与测试数据需求
### 6.1 质量风险
| 风险ID | 风险描述 | 可能性 | 影响 | 缓解措施 |
|--------|----------|--------|------|----------|
| QR-001 | 模型输出不稳定导致验收不通过 | 高 | 高 | 增加人工确认卡点,预留调优时间 |
| QR-002 | 行内接口不稳定影响数据准备 | 中 | 中 | Mock数据准备,降级策略 |
| QR-003 | 多租户隔离缺陷导致数据泄露 | 低 | 极高 | 自动化测试覆盖,代码审查 |
| QR-004 | 大报告生成超时影响用户体验 | 中 | 中 | 异步化+进度推送 |
| QR-005 | 段落风格不一致影响报告质量 | 中 | 中 | Prompt模板统一,业务验收 |
| QR-006 | RAG召回质量差导致生成错误 | 中 | 中 | 召回结果人工确认 |
### 6.2 测试数据需求
| 数据类型 | 数据内容 | 数量 | 来源 |
|----------|----------|------|------|
| 任务输入 | 不同协议金额、企业类型、行业类型的任务参数 | 20+ | 手工构造 |
| 知识体系 | 项目融资类一级/二级章节结构 | 1套完整 | 业务提供 |
| 模拟工商数据 | 企业基本信息、股东信息 | 10条 | Mock服务 |
| 模拟指标数据 | 财务指标、经营指标 | 10条 | Mock服务 |
| 测试文档 | PDF/Word上传材料 | 5份 | 业务提供 |
| 预期大纲 | 不同输入对应的预期大纲结构 | 10套 | 业务提供 |
| 模型输出样本 | L1/L2/Section的模型原始输出 | 各20+ | 实际调用收集 |
### 6.3 Mock服务
```yaml
# Mock服务清单
mocks:
行内数据源:
- 工商接口: 返回企业基本信息、股东结构
- 风险接口: 返回风险事件列表
- 指标平台: 返回财务报表指标
模型服务:
- 正常响应: 按预期格式返回JSON
- 超时响应: 延迟30秒后返回
- 格式错误: 返回非JSON内容
- 拒绝服务: 返回429/503
OSS:
- 本地MinIO模拟OSS服务
```
### 6.4 测试环境需求
| 环境 | 用途 | 配置 |
|------|------|------|
| 开发环境 | 开发自测 | 各开发者本地 |
| 测试环境 | 功能/集成测试 | 与生产同配置(缩容) |
| 预发布环境 | 回归/验收测试 | 与生产同配置 |
| 压测环境 | 性能测试 | 与生产同配置 |
---
## 7. 测试交付物
| 交付物 | 说明 | 交付时间 |
|--------|------|----------|
| 测试计划 | 本文档 | Sprint开始 |
| 测试用例 | 详细的测试用例文档(Excel/禅道) | 开发完成前 |
| 自动化脚本 | 单元/接口/E2E自动化脚本 | 持续交付 |
| 测试报告 | 功能/性能/安全测试报告 | 上线前 |
| 缺陷报告 | 缺陷跟踪与修复验证 | 持续更新 |
| 验收报告 | 业务验收签字 | 上线前 |
---
*文档版本:MVP阶段*
*最后更新:2026-03-31*