# 测试策略 - 图片OCR与智能文档管理系统

## 项目信息
- **项目名称**: 图片OCR与智能文档管理系统
- **测试策略版本**: 1.0
- **创建日期**: 2026-02-21
- **测试方法论**: TDD (测试驱动开发)

---

## 1. 测试金字塔

```
                    /\
                   /  \
                  / E2E \  <-- 10% 关键用户旅程
                 /------\
                /        \
               /集成测试  \  <-- 30% API和组件交互
              /----------\
             /            \
            /  单元测试    \  <-- 60% 函数和类级测试
           /--------------\
```

### 测试分布

| 测试类型 | 占比 | 数量(预估) | 运行时间 | 覆盖目标 |
|---------|------|-----------|---------|----------|
| 单元测试 | 60% | ~200+ | <30秒 | 80%+ |
| 集成测试 | 30% | ~80+ | <2分钟 | 70%+ |
| E2E测试 | 10% | ~15+ | <5分钟 | 关键路径 |

---

## 2. E2E 测试清单

### 2.1 用户认证流程

#### E2E-AUTH-001: 用户注册登录
- **优先级**: P0
- **描述**: 新用户注册并登录系统
- **步骤**:
  1. 打开注册页面 `/auth`
     - 预期: 显示注册表单（用户名、邮箱、密码）
  2. 输入有效信息并提交
     - 预期: 注册成功，自动登录
  3. 验证跳转到工作台 `/`
     - 预期: 显示工作台首页
  4. 刷新页面
     - 预期: 仍保持登录状态

#### E2E-AUTH-002: 登录失败处理
- **优先级**: P0
- **描述**: 输入错误凭证时显示错误信息
- **步骤**:
  1. 打开登录页面
  2. 输入错误的用户名/密码
  3. 点击登录
     - 预期: 显示"用户名或密码错误"提示
     - 预期: 不跳转页面

#### E2E-AUTH-003: 登出功能
- **优先级**: P0
- **描述**: 用户登出后无法访问受保护页面
- **步骤**:
  1. 登录后点击登出
  2. 尝试访问 `/documents`
     - 预期: 重定向到登录页

### 2.2 图片上传与OCR流程

#### E2E-OCR-001: 成功OCR识别
- **优先级**: P0
- **描述**: 上传清晰图片并成功识别
- **步骤**:
  1. 登录系统
  2. 点击"上传图片"按钮
  3. 选择测试图片（清晰文字图片）
  4. 等待OCR处理
     - 预期: 显示处理中状态
     - 预期: 5秒内完成
  5. OCR完成后显示结果
     - 预期: 显示识别的文字
     - 预期: 置信度 > 80%
  6. 保存为文档
     - 预期: 文档列表中显示新文档

#### E2E-OCR-002: OCR失败处理
- **优先级**: P0
- **描述**: 模糊图片OCR失败时进入待处理列表
- **步骤**:
  1. 上传模糊测试图片
  2. 等待OCR处理
  3. 处理完成但置信度 < 30%
     - 预期: 不自动创建文档
     - 预期: 显示"识别失败，请手动处理"提示
  4. 进入待处理图片页 `/pending-images`
     - 预期: 显示失败的图片
  5. 点击"手动创建文档"
  6. 输入文字并保存
     - 预期: 成功创建文档

#### E2E-OCR-003: 图片增强重试
- **优先级**: P1
- **描述**: 对模糊图片增强后重新OCR
- **步骤**:
  1. 在待处理列表选择图片
  2. 点击"图片增强"（旋转、裁剪）
  3. 点击"重新OCR"
  4. 等待处理
     - 预期: 使用增强后的图片重新识别

### 2.3 文档管理与AI分析流程

#### E2E-DOC-001: AI智能分析
- **优先级**: P0
- **描述**: 对文档进行AI分析，自动打标签和分类
- **步骤**:
  1. 创建文档后点击"AI分析"按钮
  2. 等待AI处理
     - 预期: 显示分析中状态
  3. AI完成后显示结果
     - 预期: 显示3-5个推荐标签
     - 预期: 显示推荐分类
     - 预期: 标签和分类可手动修改
  4. 确认应用
     - 预期: 标签和分类保存到文档

#### E2E-DOC-002: AI创建新分类
- **优先级**: P1
- **描述**: AI识别新内容类型并创建新分类
- **步骤**:
  1. 上传发票图片并OCR
  2. 点击AI分析
  3. AI识别为发票类型
     - 预期: 推荐新分类"发票"
     - 预期: 显示推荐图标 🧾
  4. 确认创建
     - 预期: "发票"分类添加到分类列表

### 2.4 待办事项管理流程

#### E2E-TODO-001: 创建待办事项
- **优先级**: P0
- **描述**: 从文档创建待办事项
- **步骤**:
  1. 在文档详情页点击"转为待办"
  2. 设置优先级为"高"
  3. 设置截止日期为明天
  4. 保存
     - 预期: 待办出现在"未完成"列表
     - 预期: 显示高优先级标签
     - 预期: 显示截止日期

#### E2E-TODO-002: 三状态流转
- **优先级**: P0
- **描述**: 待办从未完成→已完成→已确认
- **步骤**:
  1. 在"未完成"列表点击"完成"
     - 预期: 待办移到"已完成"列表
  2. 在"已完成"列表查看
     - 预期: 显示完成时间
  3. 点击"确认"
     - 预期: 待办移到"已确认"列表
  4. 在"已确认"列表查看
     - 预期: 显示确认时间
     - 预期: 只读状态

#### E2E-TODO-003: 批量操作
- **优先级**: P1
- **描述**: 批量完成和确认待办
- **步骤**:
  1. 在"未完成"列表选择3个待办
  2. 点击"批量完成"
     - 预期: 3个待办都移到"已完成"列表
  3. 在"已完成"列表全选
  4. 点击"批量确认"
     - 预期: 所有待办移到"已确认"列表

### 2.5 完整用户旅程

#### E2E-JOURNEY-001: 截图→待办完整流程
- **优先级**: P0
- **描述**: 从截图到创建待办的完整流程
- **步骤**:
  1. 用户登录
  2. 点击"系统截图"
  3. 截取包含待办事项的图片
  4. OCR识别成功
  5. 编辑OCR结果
  6. 保存为文档
  7. AI分析生成标签和分类
  8. 转为待办事项
  9. 设置优先级和截止日期
  10. 保存到未完成列表
     - 预期: 全流程不超过5个主要操作
     - 预期: 总耗时 < 2分钟

---

## 3. 集成测试清单

### 3.1 后端API集成

#### INT-API-001: 用户认证API
- **测试**: 完整的注册登录流程
- **涉及组件**: AuthController, UserService, JWTMiddleware, Database
- **Mock**: 密码加密、邮件服务
- **断言**:
  - 注册成功返回JWT token
  - 密码使用bcrypt加密存储
  - token验证中间件正确拦截
  - 过期token被拒绝

#### INT-API-002: OCR处理API
- **测试**: 图片上传到OCR完成的异步流程
- **涉及组件**: OCRController, OCRService, OCRProvider, ImageStorage
- **Mock**: OCR provider响应
- **断言**:
  - 图片正确存储
  - OCR任务异步处理
  - 轮询接口返回正确状态
  - 置信度低于阈值时不创建文档

#### INT-API-003: AI分析API
- **测试**: AI分析调用的完整流程
- **涉及组件**: AIController, AIService, AIProviders (GLM/MiniMax/DeepSeek)
- **Mock**: AI provider API响应
- **断言**:
  - 正确调用配置的AI provider
  - 返回的标签和分类格式正确
  - 新标签/新分类正确创建
  - API失败时降级处理

#### INT-API-004: 待办状态流转API
- **测试**: 待办状态变更的API调用
- **涉及组件**: TodoController, TodoService, Database
- **断言**:
  - pending → completed 正确更新completed_at
  - completed → confirmed 正确更新confirmed_at
  - confirmed 不能回到其他状态
  - 批量操作事务性正确

### 3.2 数据库集成

#### INT-DB-001: 数据模型关系
- **测试**: 验证实体关系正确性
- **涉及组件**: Prisma ORM, Database
- **断言**:
  - 用户级联删除正确
  - Image.document_id 可为NULL
  - Tag/Category usage_count 自动更新
  - 事务回滚正确

#### INT-DB-002: 查询性能
- **测试**: 验证查询效率
- **涉及组件**: Database, Indexes
- **断言**:
  - 待处理图片查询 < 100ms
  - 带筛选的文档查询 < 200ms
  - 全文搜索 < 500ms

### 3.3 前端组件集成

#### INT-FE-001: 图片上传组件
- **测试**: 拖拽上传、文件选择、预览
- **涉及组件**: ImageUpload, OCRService, Toast
- **Mock**: OCR API
- **断言**:
  - 拖拽正确触发上传
  - 文件类型验证
  - 进度条正确显示
  - 错误正确提示

#### INT-FE-002: 三状态待办列表
- **测试**: Tab切换和状态流转
- **涉及组件**: TodoList, TodoCard, TodoAPI
- **Mock**: Todo API
- **断言**:
  - Tab切换正确筛选数据
  - 状态变更后列表正确更新
  - 批量操作正确选中
  - 撤销操作正确恢复状态

#### INT-FE-003: AI分析UI
- **测试**: AI分析按钮和结果显示
- **涉及组件**: AIAnalysisButton, TagSelector, CategorySelector
- **Mock**: AI API
- **断言**:
  - 加载状态正确显示
  - 新标签/新分类高亮显示
  - 确认后正确应用
  - 取消后不应用

---

## 4. 单元测试清单

### 4.1 后端单元测试

#### UNIT-AUTH-001: 密码加密
- **测试**: `UserService.hashPassword()`
  - 输入: "plaintext123"
  - 预期输出: bcrypt hash (60字符)
  - 边界: 空字符串、超长密码、特殊字符

#### UNIT-AUTH-002: JWT生成和验证
- **测试**: `AuthService.generateToken()`, `verifyToken()`
  - 输入: user_id = "uuid-123"
  - 预期输出: 有效JWT token
  - 边界: 过期token、伪造token

#### UNIT-OCR-001: 置信度阈值判断
- **测试**: `OCRService.shouldCreateDocument()`
  - 输入: confidence = 0.31, 阈值 = 0.3
  - 预期输出: true
  - 边界: 0.3, 0.29, 1.0, 0.0

#### UNIT-OCR-002: 图片质量检测
- **测试**: `ImageQualityAnalyzer.assess()`
  - 输入: 模糊图片base64
  - 预期输出: { quality: 'poor', score: < 0.5 }
  - 边界: 清晰图片、全黑图片、超大图片

#### UNIT-AI-001: 标签提取
- **测试**: `AIService.extractTags()`
  - 输入: "会议记录：讨论项目进度..."
  - 预期输出: ["会议", "项目", "进度"]
  - 边界: 空文本、纯数字、混合语言

#### UNIT-AI-002: 分类推荐
- **测试**: `AIService.suggestCategory()`
  - 输入: 文本内容 + 现有分类列表
  - 预期输出: 匹配的分类 或 新分类建议
  - 边界: 无现有分类、完全匹配、部分匹配

#### UNIT-TODO-001: 待办状态验证
- **测试**: `TodoService.validateStatusTransition()`
  - 输入: "pending" → "completed"
  - 预期输出: true
  - 边界: "confirmed" → "pending" (应返回false)

#### UNIT-TODO-002: 待办排序
- **测试**: `TodoService.sortTodos()`
  - 输入: 待办列表 + 排序规则
  - 预期输出: 按优先级和截止日期排序
  - 边界: 空列表、相同优先级、无截止日期

### 4.2 前端单元测试

#### UNIT-FE-001: 图片预览组件
- **测试**: `ImagePreview`
  - 输入: imageUrl = "http://..."
  - 预期: 渲染img标签
  - 边界: 加载失败、超大图片

#### UNIT-FE-002: 标签选择器
- **测试**: `TagSelector`
  - 输入: tags = [], 新标签输入
  - 预期: 调用onTagsChange
  - 边界: 重复标签、空标签

#### UNIT-FE-003: 待办卡片
- **测试**: `TodoCard`
  - 输入: todo对象
  - 预期: 正确显示优先级颜色
  - 边界: 无截止日期、已完成状态

#### UNIT-FE-004: OCR结果编辑器
- **测试**: `OCResultEditor`
  - 输入: initialText, onChangeText
  - 预期: 文本变更触发回调
  - 边界: 超长文本、特殊字符

### 4.3 工具函数测试

#### UNIT-UTIL-001: 文件大小格式化
- **测试**: `formatFileSize()`
  - 输入: 1024 → "1 KB"
  - 输入: 1048576 → "1 MB"
  - 边界: 0, 负数

#### UNIT-UTIL-002: 日期格式化
- **测试**: `formatDate()`
  - 输入: "2024-01-15" → "1月15日"
  - 边界: 无效日期、未来日期

#### UNIT-UTIL-003: 搜索高亮
- **测试**: `highlightSearch()`
  - 输入: "hello world", "world"
  - 预期: "hello <mark>world</mark>"
  - 边界: 空搜索词、多个匹配

---

## 5. 测试矩阵

| 功能模块 | 单元测试 | 集成测试 | E2E测试 | 覆盖率目标 | 关键测试 |
|---------|---------|---------|---------|-----------|----------|
| 用户认证 | 15 | 4 | 3 | 85% | 登录/权限/数据隔离 |
| 图片上传 | 12 | 3 | 2 | 80% | 拖拽/格式验证/大小限制 |
| OCR处理 | 20 | 5 | 3 | 80% | 置信度/失败处理/重试 |
| 文档管理 | 18 | 4 | 2 | 80% | CRUD/搜索/关联 |
| AI分析 | 25 | 6 | 2 | 75% | 标签/分类/新分类创建 |
| 待办管理 | 30 | 6 | 4 | 85% | 三状态/批量/流转 |
| 标签分类 | 15 | 3 | 1 | 75% | 创建/关联/统计 |
| 待处理图片 | 12 | 3 | 2 | 80% | 手动创建/增强/删除 |
| 配置管理 | 10 | 2 | 0 | 70% | CRUD/测试配置 |
| **总计** | **157** | **36** | **19** | **80%** | - |

---

## 6. 测试数据管理

### 6.1 测试图片

| 类型 | 文件名 | 用途 | 预期结果 |
|------|--------|------|----------|
| 清晰中文 | `clear-zh.png` | 基础OCR测试 | 置信度 > 90% |
| 清晰英文 | `clear-en.png` | 英文OCR测试 | 置信度 > 90% |
| 模糊图片 | `blur.png` | 失败处理测试 | 置信度 < 30% |
| 混合语言 | `mixed.png` | 多语言测试 | 正确识别 |
| 手写文字 | `handwriting.png` | 手写测试 | 置信度 50-70% |
| 发票样本 | `invoice.png` | 类型识别测试 | 识别为发票 |
| 会议记录 | `meeting.png` | 类型识别测试 | 识别为会议 |
| 超大图片 | `large.png` | 大小限制测试 | 拒绝 (>10MB) |

### 6.2 测试用户

| 用户名 | 角色 | 用途 |
|--------|------|------|
| test_user | 普通用户 | 常规测试 |
| admin_user | 管理员 | 管理功能测试 |
| new_user | 新用户 | 注册流程测试 |

### 6.3 Mock数据

- **AI响应**: 预设的标签和分类推荐
- **OCR响应**: 不同置信度的识别结果
- **API响应**: 成功/失败/超时场景

---

## 7. 性能测试

### 7.1 响应时间

| 操作 | 目标 | 测试方法 |
|------|------|----------|
| 页面加载 | <2s | Lighthouse |
| API响应 | <500ms | k6 |
| OCR处理 | <5s | 计时测试 |
| AI分析 | <10s | 计时测试 |

### 7.2 并发测试

- 5个用户同时上传图片
- 10个并发API请求
- 数据库连接池压力测试

---

## 8. 测试环境

### 8.1 本地开发
```bash
# 运行所有测试
npm test

# 单元测试
npm run test:unit

# 集成测试
npm run test:integration

# E2E测试
npm run test:e2e

# 覆盖率报告
npm run test:coverage
```

### 8.2 CI/CD
```yaml
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
  test:
    steps:
      - run: npm run test:unit
      - run: npm run test:integration
      - run: npm run test:e2e
      - run: npm run test:coverage
```

---

## 9. 测试工具

### 9.1 后端
- **框架**: Jest
- **Mock**: jest.mock
- **覆盖率**: istanbul
- **API测试**: supertest

### 9.2 前端
- **框架**: Vitest
- **组件测试**: Testing Library
- **Mock**: vi.mock
- **E2E**: Playwright

### 9.3 工具
- **覆盖率**: c8 / istanbul
- **性能**: Lighthouse, k6
- **Mock服务器**: MSW (Mock Service Worker)

---

## 10. 测试质量标准

### 10.1 代码覆盖率
- **整体覆盖率**: ≥ 80%
- **核心模块**: ≥ 85%
- **工具函数**: ≥ 90%

### 10.2 测试质量
- 所有测试独立且可重复
- 测试命名清晰描述意图
- 每个测试只有一个断言原因
- 边界条件都有测试覆盖

### 10.3 CI/CD门禁
- 所有测试必须通过
- 覆盖率不能下降
- Lint必须通过
- 构建时间 < 5分钟

---

## 11. 风险和缓解

| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| AI API不稳定 | 测试失败 | 使用Mock，减少真实调用 |
| OCR耗时 | 测试慢 | 使用预设结果，跳过真实OCR |
| 测试数据污染 | 测试失败 | 每次测试前清理数据库 |
| E2E测试不稳定 | CI失败 | 增加重试机制，优化选择器 |

---

## 12. 下一步

测试策略已制定完成。下一步：

1. **生成TDD开发计划** - 详细的Sprint计划
2. **创建测试骨架** - 生成测试文件模板
3. **开始TDD开发** - 红-绿-重构循环

```bash
# 查看开发计划
@skill tdd-planner
生成开发计划
```
