Files
PicAnalysis/.project/test-strategy.md
wjl 1a0ebde95d feat: 初始化 PicAnalysis 项目
完整的前后端图片分析应用,包含:
- 后端:Express + Prisma + SQLite,101个单元测试全部通过
- 前端:React + TypeScript + Vite,47个单元测试,89.73%覆盖率
- E2E测试:Playwright 测试套件
- MCP集成:Playwright MCP配置完成并测试通过

功能模块:
- 用户认证(JWT)
- 文档管理(CRUD)
- 待办管理(三态工作流)
- 图片管理(上传、截图、OCR)

测试覆盖:
- 后端单元测试:101/101 
- 前端单元测试:47/47 
- E2E测试:通过 
- MCP Playwright测试:通过 

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 20:10:11 +08:00

566 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试策略 - 图片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
生成开发计划
```