AI-video-lifeplan-demo/.qoder/repowiki/zh/content/测试策略.md

321 lines
15 KiB
Markdown
Raw Permalink 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.

# 测试策略
<cite>
**本文引用的文件**
- [tests/test_video_cli.py](file://tests/test_video_cli.py)
- [tests/test_video_processor.py](file://tests/test_video_processor.py)
- [tests/fixtures/README.md](file://tests/fixtures/README.md)
- [requirements.txt](file://requirements.txt)
- [PROJECT_README.md](file://PROJECT_README.md)
- [main.py](file://main.py)
- [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py)
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py)
- [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py)
</cite>
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
本文件系统化阐述项目的测试策略与实践,重点覆盖:
- tests/ 目录下的单元测试与集成测试设计原则
- 对 CLI 接口的独立测试工具 test_video_cli.py 的使用与验证路径
- 对视频处理模块 backend/video_processor 的单元测试与数据结构一致性校验
- 测试夹具(fixtures)的组织与生成方法
- 使用 pytest 运行测试套件的方法
- 在 CI/CD 中的测试职责与质量门禁建议
- 面向开发者的新增测试编写指南
目标是帮助开发者快速理解测试体系、可靠地扩展测试覆盖面,并确保后端逻辑的稳定性与正确性。
## 项目结构
测试相关的关键位置与职责如下:
- tests/test_video_cli.py:独立的 CLI 测试工具,用于直接调用视频分析模块,输出结果或进行依赖检查
- tests/test_video_processor.py:针对视频处理模块的单元测试,包含数据结构、工具函数与音频优先策略的端到端验证
- tests/fixtures/README.md:测试夹具(样本视频与期望输出)的生成与维护指南
- backend/video_processor/*:视频分析的核心实现,包括策略选择、数据结构定义与通用工具函数
- main.py:主入口脚本,展示视频分析在整体流水线中的位置(供理解测试上下文)
```mermaid
graph TB
subgraph "测试层"
T1["tests/test_video_cli.py"]
T2["tests/test_video_processor.py"]
F["tests/fixtures/README.md"]
end
subgraph "后端视频处理"
M1["backend/video_processor/__init__.py"]
M2["backend/video_processor/schemas.py"]
M3["backend/video_processor/utils.py"]
M4["backend/video_processor/strategy_audio.py"]
M5["backend/video_processor/strategy_direct.py"]
end
subgraph "主入口"
E["main.py"]
end
T1 --> M1
T2 --> M1
T2 --> M2
T2 --> M3
T2 --> M4
T2 --> M5
E --> M1
```
图表来源
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L1-L161)
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L1-L143)
- [tests/fixtures/README.md](file://tests/fixtures/README.md#L1-L49)
- [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L1-L187)
- [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py#L1-L58)
- [main.py](file://main.py#L1-L305)
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L143-L156)
## 核心组件
- 视频分析入口与策略分发:backend/video_processor/__init__.py 提供 analyze_video 入口,根据 strategy 调用不同策略实现
- 数据结构契约:schemas.py 定义 VideoSegment、KeyMoment、VideoAnalysisResult 等标准输出结构,保证各策略输出一致
- 通用工具:utils.py 封装 FFmpeg/ffprobe 调用,提供时长查询、音频提取、视频切片与依赖检测
- 策略实现:
- strategy_audio.py 实现“音频优先”策略,调用 OpenAI Whisper 获取带时间戳的转录,再生成片段与关键时刻
- strategy_direct.py 为“直接视频分析”占位,当前抛出未实现异常,留待后续迭代
章节来源
- [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L1-L60)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L1-L187)
- [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py#L1-L58)
## 架构总览
测试与被测模块的交互关系如下:
```mermaid
sequenceDiagram
participant CLI as "CLI 测试工具<br/>tests/test_video_cli.py"
participant API as "分析入口<br/>backend/video_processor/__init__.py"
participant Strat as "音频优先策略<br/>strategy_audio.py"
participant Utils as "工具函数<br/>utils.py"
participant Schemas as "数据结构<br/>schemas.py"
CLI->>API : 调用 analyze_video(video_path, strategy, config)
API->>Strat : 选择策略并实例化
Strat->>Utils : 提取音频/获取时长
Strat->>Strat : Whisper 转录带时间戳
Strat->>Schemas : 构造 VideoSegment/KeyMoment/VideoAnalysisResult
Strat-->>API : 返回 VideoAnalysisResult
API-->>CLI : 返回结果并可转换为字典
```
图表来源
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L100-L145)
- [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L31-L60)
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L54-L100)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L13-L164)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L12-L91)
## 详细组件分析
### CLI 测试工具:test_video_cli.py
- 设计目的:独立验证视频分析模块,支持依赖检查、策略选择、语言设置、对比模式与输出到 JSON 文件
- 关键行为:
- 依赖检查:验证 FFmpeg 与 OpenAI 库是否可用
- 输入校验:要求提供输入视频文件;若仅需检查依赖,可通过参数触发
- 分析执行:调用 analyze_video 并将结果转换为字典输出
- 输出控制:默认打印到控制台,也可写入 JSON 文件
- 适用场景:
- 快速验证单个视频的分析流程
- 作为回归测试的辅助工具,配合 fixtures 生成期望输出
章节来源
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L1-L161)
### 单元测试:test_video_processor.py
- 测试范围:
- 数据结构:VideoSegment、KeyMoment、VideoAnalysisResult 的创建与序列化
- 工具函数:FFmpeg 依赖检测、视频时长获取、音频提取(含清理)
- 策略验证:音频优先策略在具备 OPENAI_API_KEY 和 sample.mp4 时的端到端验证
- 测试夹具:
- sample.mp4:短时长日语对话视频,用于测试处理链路
- expected_output.json:由 CLI 工具生成的期望输出,用于回归比对
- 标记与跳过:
- 使用 pytest.mark.skipif 条件跳过:当环境变量或文件缺失时跳过对应测试,避免非必要的失败
- 断言要点:
- 结果对象的字段完整性与类型正确性
- 分析结果中片段数量、重要片段过滤、引号类关键时刻等业务断言
章节来源
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L1-L143)
- [tests/fixtures/README.md](file://tests/fixtures/README.md#L1-L49)
### 数据结构与契约:schemas.py
- VideoSegment:包含起止时间、描述、转录、重要度、标签、说话人等字段,并提供 to_dict 序列化
- KeyMoment:包含时间戳、类型(quote/chart/emotion/action)、内容与上下文,并提供 to_dict 序列化
- VideoAnalysisResult:包含源视频、总时长、策略、片段列表、关键时刻列表、元数据,并提供过滤方法与 to_dict 序列化
- 契约意义:统一各策略输出格式,便于上层流水线消费与渲染
章节来源
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L1-L91)
### 工具函数:utils.py
- get_video_duration:基于 ffprobe 获取视频时长,错误时抛出运行时异常
- extract_audio:基于 ffmpeg 提取音频,支持采样率与编码器配置,返回音频文件路径
- slice_video:基于 ffmpeg 进行流复制切片,不重编码,适合快速片段提取
- check_ffmpeg_installed:检查 ffmpeg/ffprobe 是否在 PATH 中
章节来源
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L1-L164)
### 策略实现:strategy_audio.py
- 初始化:从配置读取语言、模型与提示词,并从环境变量读取 OPENAI_API_KEY
- analyze:按以下步骤执行
- 提取音频
- Whisper 转录(verbose_json,带段级时间戳)
- 将转录段落转换为 VideoSegment 列表
- 识别关键时刻(示例:标记首段为 quote)
- 获取视频总时长
- 清理临时音频文件
- 组装 VideoAnalysisResult 返回
- 错误处理:缺少 OPENAI_API_KEY 时抛出异常;FFmpeg/Whisper 失败时抛出运行时异常
章节来源
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L1-L187)
### 策略实现:strategy_direct.py(占位)
- 当前状态:抛出 NotImplementedError,提示使用音频优先策略
- 后续演进:按计划拆分视频、上传至 Gemini、分析视觉与音频、合并结果
章节来源
- [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py#L1-L58)
### 测试夹具(fixtures)管理
- 目录与用途:
- tests/fixtures/sample.mp4:测试用短视频(git-ignored),用于验证处理链路
- tests/fixtures/expected_output.json:由 CLI 工具生成的期望输出,用于回归测试
- 生成流程:
- 准备 sample.mp4(录制或下载)
- 使用 CLI 工具生成 expected_output.json
- 在测试中加载该文件进行比对(如需)
章节来源
- [tests/fixtures/README.md](file://tests/fixtures/README.md#L1-L49)
### 测试运行与环境
- 运行方式:
- 使用 pytest 运行 tests/test_video_processor.py
- 或在根目录使用命令行运行 pytest
- 依赖安装:
- requirements.txt 中包含 pytest 与 pytest-cov 的注释说明,可在需要时启用覆盖率统计
- 环境变量:
- OPENAI_API_KEY:音频优先策略依赖 Whisper
- FFmpeg/ffprobe:工具函数依赖
章节来源
- [PROJECT_README.md](file://PROJECT_README.md#L151-L156)
- [requirements.txt](file://requirements.txt#L31-L34)
## 依赖关系分析
- 模块耦合:
- analyze_video 作为入口,仅依赖策略实现与工具函数,保持良好解耦
- 策略实现依赖工具函数与数据结构,不反向依赖上层
- 外部依赖:
- FFmpeg/ffprobe:媒体处理
- OpenAI Whisper:音频转录
- 可能的循环依赖:
- 当前结构清晰,无明显循环导入
```mermaid
graph LR
Init["__init__.py<br/>analyze_video"] --> SA["strategy_audio.py"]
Init --> SD["strategy_direct.py"]
SA --> U["utils.py"]
SA --> S["schemas.py"]
SD --> S
```
图表来源
- [backend/video_processor/__init__.py](file://backend/video_processor/__init__.py#L31-L60)
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L54-L100)
- [backend/video_processor/strategy_direct.py](file://backend/video_processor/strategy_direct.py#L43-L58)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L13-L164)
- [backend/video_processor/schemas.py](file://backend/video_processor/schemas.py#L12-L91)
## 性能考量
- 音频优先策略的优势:
- 以文本替代视频帧,显著降低 Token 成本与处理时间
- Whisper 提供精确的时间戳,有利于后续片段定位
- 工具函数的性能注意:
- extract_audio 与 slice_video 使用流复制,避免重编码,提升速度
- get_video_duration 依赖 ffprobe,应确保其可用性与版本兼容
- 测试中的性能关注点:
- 使用 skipif 跳过资源不足的测试,减少无效等待
- 在本地使用小体积 sample.mp4 进行快速回归
章节来源
- [backend/video_processor/strategy_audio.py](file://backend/video_processor/strategy_audio.py#L1-L187)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L13-L164)
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L80-L140)
## 故障排查指南
- 依赖缺失
- FFmpeg/ffprobe 未安装:使用 CLI 的依赖检查功能确认安装
- OPENAI_API_KEY 未设置:音频优先策略会抛出异常,需在环境变量中配置
- 输入问题
- 缺少 sample.mp4:按 fixtures 说明准备测试视频
- 视频路径不存在:CLI 会报错并退出
- 工具函数异常
- get_video_duration/extract_audio/slice_video:当外部命令失败时抛出运行时异常,检查命令行输出与权限
- 测试失败
- 跳过测试:检查 skipif 条件(环境变量、文件存在性)
- 回归比对:核对 expected_output.json 与实际输出差异
章节来源
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L70-L102)
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L80-L140)
- [backend/video_processor/utils.py](file://backend/video_processor/utils.py#L13-L164)
- [tests/fixtures/README.md](file://tests/fixtures/README.md#L1-L49)
## 结论
本项目的测试策略围绕“数据结构契约 + 工具函数封装 + 策略实现”的清晰边界展开,既保证了模块内聚,又便于独立验证与扩展。通过 CLI 测试工具与 pytest 单元测试相结合,能够快速定位问题、稳定回归,并为后续引入更多策略与集成测试打下基础。建议在 CI/CD 中加入:
- 必要依赖检查(FFmpeg/ffprobe)
- 环境变量校验(OPENAI_API_KEY)
- 覆盖率统计(可选)
- 回归测试(基于 fixtures 与 expected_output.json)
## 附录
### 新增测试编写指南
- 遵循的原则
- 以数据结构为中心:先验证 schemas 的创建与序列化
- 以工具函数为边界:验证外部命令可用性与错误分支
- 以策略为场景:在具备必要凭据与资源的前提下验证端到端流程
- 夹具准备
- 在 tests/fixtures 下添加新的样本文件,并在测试中使用 skipif 保护
- 如需生成期望输出,使用 CLI 工具导出 JSON
- 运行与调试
- 使用 pytest 运行指定测试文件或模块
- 通过 -v/-k 等选项筛选与调试
- CI/CD 集成建议
- 在流水线中先行安装依赖与环境变量
- 执行 pytest 并收集覆盖率报告(可选)
- 对关键测试(如音频优先策略)进行条件执行
章节来源
- [tests/test_video_processor.py](file://tests/test_video_processor.py#L1-L143)
- [tests/test_video_cli.py](file://tests/test_video_cli.py#L1-L161)
- [tests/fixtures/README.md](file://tests/fixtures/README.md#L1-L49)
- [PROJECT_README.md](file://PROJECT_README.md#L151-L156)