585 lines
24 KiB
Markdown
585 lines
24 KiB
Markdown
# 测试策略
|
||
|
||
<cite>
|
||
**本文引用的文件**
|
||
- [tests/conftest.py](file://tests/conftest.py)
|
||
- [tests/test_auth.py](file://tests/test_auth.py)
|
||
- [tests/test_business_flow.py](file://tests/test_business_flow.py)
|
||
- [tests/test_citation_engine.py](file://tests/test_citation_engine.py)
|
||
- [tests/test_citations.py](file://tests/test_citations.py)
|
||
- [tests/test_queries.py](file://tests/test_queries.py)
|
||
- [tests/test_scheduler.py](file://tests/test_scheduler.py)
|
||
- [backend/app/main.py](file://backend/app/main.py)
|
||
- [backend/app/api/deps.py](file://backend/app/api/deps.py)
|
||
- [backend/app/services/auth.py](file://backend/app/services/auth.py)
|
||
- [backend/app/workers/citation_engine.py](file://backend/app/workers/citation_engine.py)
|
||
- [backend/app/workers/scheduler.py](file://backend/app/workers/scheduler.py)
|
||
- [backend/app/api/auth.py](file://backend/app/api/auth.py)
|
||
- [backend/app/api/citations.py](file://backend/app/api/citations.py)
|
||
- [backend/app/api/queries.py](file://backend/app/api/queries.py)
|
||
- [backend/app/database.py](file://backend/app/database.py)
|
||
- [backend/app/config.py](file://backend/app/config.py)
|
||
</cite>
|
||
|
||
## 更新摘要
|
||
**变更内容**
|
||
- 新增业务流程测试章节,涵盖端到端业务场景测试
|
||
- 新增调度器测试章节,包括定时任务调度和频率计算测试
|
||
- 完善测试最佳实践,增加业务流程测试和调度器测试的最佳实践指导
|
||
- 更新测试策略以反映新增的测试覆盖范围
|
||
|
||
## 目录
|
||
1. [引言](#引言)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [业务流程测试策略](#业务流程测试策略)
|
||
7. [调度器测试策略](#调度器测试策略)
|
||
8. [依赖分析](#依赖分析)
|
||
9. [性能考虑](#性能考虑)
|
||
10. [故障排查指南](#故障排查指南)
|
||
11. [结论](#结论)
|
||
12. [附录](#附录)
|
||
|
||
## 引言
|
||
本测试策略文档面向GEO项目的Pytest测试体系,覆盖单元测试、集成测试和业务流程测试的设计与实施要点。内容包括:测试夹具与模拟对象的组织方式、测试数据管理策略、认证模块、引用引擎、查询处理、业务流程和调度器等关键功能的测试用例设计思路;同时给出测试最佳实践,包括覆盖率目标、持续集成配置建议以及测试环境管理方案,并提供调试技巧与性能测试方法。
|
||
|
||
## 项目结构
|
||
测试目录位于仓库根目录下的tests,采用按功能模块划分的组织方式,配合Pytest的conftest集中式夹具与模拟对象,确保测试隔离与可重复性。后端应用以FastAPI为核心,API层通过依赖注入获取当前用户与数据库会话,服务层封装业务逻辑,工作器(worker)负责异步任务与平台适配。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "测试层"
|
||
C["tests/conftest.py"]
|
||
TA["tests/test_auth.py"]
|
||
TQ["tests/test_queries.py"]
|
||
TC["tests/test_citations.py"]
|
||
TCE["tests/test_citation_engine.py"]
|
||
TB["tests/test_business_flow.py"]
|
||
TS["tests/test_scheduler.py"]
|
||
end
|
||
subgraph "后端应用"
|
||
M["backend/app/main.py"]
|
||
D["backend/app/api/deps.py"]
|
||
DB["backend/app/database.py"]
|
||
CFG["backend/app/config.py"]
|
||
AUTH_API["backend/app/api/auth.py"]
|
||
QUERIES_API["backend/app/api/queries.py"]
|
||
CITATIONS_API["backend/app/api/citations.py"]
|
||
CE["backend/app/workers/citation_engine.py"]
|
||
QS["backend/app/workers/scheduler.py"]
|
||
end
|
||
C --> TA
|
||
C --> TQ
|
||
C --> TC
|
||
C --> TCE
|
||
C --> TB
|
||
C --> TS
|
||
TA --> AUTH_API
|
||
TQ --> QUERIES_API
|
||
TC --> CITATIONS_API
|
||
TCE --> CE
|
||
TS --> QS
|
||
AUTH_API --> D
|
||
QUERIES_API --> D
|
||
CITATIONS_API --> D
|
||
D --> DB
|
||
DB --> CFG
|
||
M --> AUTH_API
|
||
M --> QUERIES_API
|
||
M --> CITATIONS_API
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/conftest.py:1-123](file://tests/conftest.py#L1-L123)
|
||
- [backend/app/main.py:1-56](file://backend/app/main.py#L1-L56)
|
||
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
|
||
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/api/citations.py:1-78](file://backend/app/api/citations.py#L1-L78)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
- [backend/app/workers/scheduler.py:1-182](file://backend/app/workers/scheduler.py#L1-L182)
|
||
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
|
||
- [backend/app/config.py:1-23](file://backend/app/config.py#L1-L23)
|
||
|
||
**章节来源**
|
||
- [tests/conftest.py:1-123](file://tests/conftest.py#L1-L123)
|
||
- [backend/app/main.py:1-56](file://backend/app/main.py#L1-L56)
|
||
|
||
## 核心组件
|
||
- 测试夹具与模拟
|
||
- 会话级调度器模拟:在测试启动时替换查询调度器,避免真实后台任务影响测试稳定性。
|
||
- 用户与令牌:提供模拟用户对象、JWT访问令牌及请求头,便于认证相关接口测试。
|
||
- 异步HTTP客户端:基于ASGI传输创建异步HTTP客户端,用于端到端API测试。
|
||
- 依赖覆盖:通过依赖注入覆盖当前用户解析逻辑,简化认证流程。
|
||
- 内存数据库:使用SQLite内存数据库进行集成测试,确保测试隔离性。
|
||
- 测试数据管理
|
||
- 使用pytest fixture生成模拟模型对象(如查询、引用记录),保证测试数据一致性与可读性。
|
||
- 通过patch对服务层函数进行桩替,隔离外部依赖,提升测试确定性。
|
||
- 直接操作数据库模型进行复杂场景测试,如权限隔离和统计计算。
|
||
- 测试运行与并发
|
||
- 使用pytest-asyncio标记异步测试,确保事件循环正确初始化与清理。
|
||
- 支持并行执行多个测试文件,提高测试执行效率。
|
||
|
||
**章节来源**
|
||
- [tests/conftest.py:19-123](file://tests/conftest.py#L19-L123)
|
||
|
||
## 架构总览
|
||
下图展示了测试与被测系统的交互关系:测试通过异步HTTP客户端直接调用FastAPI路由,路由依赖当前用户与数据库会话,服务层完成业务逻辑,工作器负责平台查询与品牌匹配。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant T as "测试用例"
|
||
participant AC as "异步HTTP客户端"
|
||
participant APP as "FastAPI应用"
|
||
participant R_AUTH as "认证路由"
|
||
participant R_QUERIES as "查询路由"
|
||
participant R_CIT as "引用路由"
|
||
participant DEPS as "依赖注入(get_current_user)"
|
||
participant SVC as "服务层"
|
||
participant DB as "数据库"
|
||
T->>AC : 发起HTTP请求
|
||
AC->>APP : ASGI传输调用
|
||
APP->>DEPS : 解析当前用户
|
||
DEPS->>DB : 查询用户
|
||
DB-->>DEPS : 返回用户
|
||
APP->>R_AUTH : 认证相关端点
|
||
APP->>R_QUERIES : 查询相关端点
|
||
APP->>R_CIT : 引用相关端点
|
||
R_AUTH->>SVC : 调用服务
|
||
R_QUERIES->>SVC : 调用服务
|
||
R_CIT->>SVC : 调用服务
|
||
SVC->>DB : 数据持久化/查询
|
||
DB-->>SVC : 返回结果
|
||
SVC-->>APP : 返回响应
|
||
APP-->>AC : 序列化响应
|
||
AC-->>T : 断言结果
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/conftest.py:117-123](file://tests/conftest.py#L117-L123)
|
||
- [backend/app/main.py:38-42](file://backend/app/main.py#L38-L42)
|
||
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
|
||
- [backend/app/api/auth.py:13-43](file://backend/app/api/auth.py#L13-L43)
|
||
- [backend/app/api/queries.py:15-86](file://backend/app/api/queries.py#L15-L86)
|
||
- [backend/app/api/citations.py:25-78](file://backend/app/api/citations.py#L25-L78)
|
||
- [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29)
|
||
|
||
## 详细组件分析
|
||
|
||
### 认证模块测试策略
|
||
- 测试目标
|
||
- 注册成功与重复邮箱错误处理
|
||
- 登录成功与密码错误场景
|
||
- 当前用户信息获取(已认证与未认证)
|
||
- 关键测试点
|
||
- 使用patch对注册与登录服务函数进行桩替,控制返回值与异常
|
||
- 通过依赖覆盖与令牌头验证路由鉴权中间件行为
|
||
- 用例设计要点
|
||
- 成功路径断言状态码与响应体字段
|
||
- 失败路径断言HTTP状态码与错误详情
|
||
- 未认证路径断言401并检查依赖覆盖清理
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant T as "测试用例"
|
||
participant AC as "异步HTTP客户端"
|
||
participant AUTH as "认证路由"
|
||
participant SVC as "认证服务"
|
||
participant DEPS as "依赖注入(get_current_user)"
|
||
T->>AC : POST /api/v1/auth/register
|
||
AC->>AUTH : 路由处理
|
||
AUTH->>SVC : 注册服务
|
||
SVC-->>AUTH : 返回用户或抛出异常
|
||
AUTH-->>AC : 201/400
|
||
AC-->>T : 断言
|
||
T->>AC : POST /api/v1/auth/login
|
||
AC->>AUTH : 路由处理
|
||
AUTH->>SVC : 登录服务
|
||
SVC-->>AUTH : 返回用户或None
|
||
AUTH-->>AC : 200/401
|
||
AC-->>T : 断言
|
||
T->>AC : GET /api/v1/auth/me
|
||
AC->>AUTH : 路由处理
|
||
AUTH->>DEPS : 解析当前用户
|
||
DEPS-->>AUTH : 返回用户或抛出401
|
||
AUTH-->>AC : 200/401
|
||
AC-->>T : 断言
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/test_auth.py:25-104](file://tests/test_auth.py#L25-L104)
|
||
- [backend/app/api/auth.py:13-43](file://backend/app/api/auth.py#L13-L43)
|
||
- [backend/app/services/auth.py:37-69](file://backend/app/services/auth.py#L37-L69)
|
||
- [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43)
|
||
|
||
**章节来源**
|
||
- [tests/test_auth.py:1-104](file://tests/test_auth.py#L1-L104)
|
||
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
|
||
- [backend/app/services/auth.py:1-69](file://backend/app/services/auth.py#L1-L69)
|
||
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
|
||
|
||
### 引擎与查询处理测试策略
|
||
- 测试目标
|
||
- 品牌匹配器:精确、别名、模糊匹配与无匹配场景
|
||
- 竞争品牌检测器:在文本中识别除目标品牌外的竞争品牌
|
||
- 引擎执行流程:单平台查询、任务状态更新、记录创建与异常处理
|
||
- 关键测试点
|
||
- 单元测试直接构造BrandMatcher与CompetitorDetector,断言匹配结果与置信度、位置等字段
|
||
- 集成测试通过patch平台适配器返回AI响应,验证引擎整合后的综合输出
|
||
- 用例设计要点
|
||
- 文本分段与位置提取:验证引用出现在第几段及上下文截取
|
||
- 平台适配器替换:确保引擎执行单平台流程时能捕获异常并写入失败记录
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class BrandMatcher {
|
||
+match(text) dict
|
||
-_extract_candidates(text) list
|
||
-_extract_position_and_context(text, keyword) tuple
|
||
}
|
||
class CompetitorDetector {
|
||
+detect(text, target_brand) list
|
||
}
|
||
class CitationEngine {
|
||
+execute_query(query, db) list
|
||
+execute_single_platform(keyword, platform, target_brand, brand_aliases) dict
|
||
-_get_or_create_task(db, query_id, platform) QueryTask
|
||
-_calculate_next_query_at(frequency) datetime
|
||
+close() void
|
||
}
|
||
BrandMatcher <.. CitationEngine : "使用"
|
||
CompetitorDetector <.. CitationEngine : "使用"
|
||
```
|
||
|
||
**图表来源**
|
||
- [backend/app/workers/citation_engine.py:19-120](file://backend/app/workers/citation_engine.py#L19-L120)
|
||
- [backend/app/workers/citation_engine.py:122-146](file://backend/app/workers/citation_engine.py#L122-L146)
|
||
- [backend/app/workers/citation_engine.py:148-309](file://backend/app/workers/citation_engine.py#L148-L309)
|
||
|
||
**章节来源**
|
||
- [tests/test_citation_engine.py:1-127](file://tests/test_citation_engine.py#L1-L127)
|
||
- [backend/app/workers/citation_engine.py:1-309](file://backend/app/workers/citation_engine.py#L1-L309)
|
||
|
||
### 引用数据与报告测试策略
|
||
- 测试目标
|
||
- 引用列表查询与统计聚合
|
||
- 立即运行查询任务
|
||
- CSV导出格式与响应头校验
|
||
- 关键测试点
|
||
- 通过patch服务函数返回预设数据,断言分页、总数与字段
|
||
- 校验CSV内容类型、附件头与关键字段存在性
|
||
- 用例设计要点
|
||
- 统计聚合断言整体指标与按平台细分
|
||
- 导出接口断言响应头与正文内容
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant T as "测试用例"
|
||
participant AC as "异步HTTP客户端"
|
||
participant CIT as "引用路由"
|
||
participant REP as "报告路由"
|
||
participant SVC as "服务层"
|
||
T->>AC : GET /api/v1/citations/?skip=&limit=
|
||
AC->>CIT : 路由处理
|
||
CIT->>SVC : 获取引用列表
|
||
SVC-->>CIT : 返回(items,total)
|
||
CIT-->>AC : 200 + JSON
|
||
AC-->>T : 断言
|
||
T->>AC : GET /api/v1/citations/stats
|
||
AC->>CIT : 路由处理
|
||
CIT->>SVC : 获取统计
|
||
SVC-->>CIT : 返回统计聚合
|
||
CIT-->>AC : 200 + JSON
|
||
AC-->>T : 断言
|
||
T->>AC : GET /api/v1/reports/export/csv?query_id=
|
||
AC->>REP : 路由处理
|
||
REP->>SVC : 导出CSV
|
||
SVC-->>REP : 返回CSV字符串
|
||
REP-->>AC : 200 + text/csv + attachment
|
||
AC-->>T : 断言
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/test_citations.py:23-93](file://tests/test_citations.py#L23-L93)
|
||
- [backend/app/api/citations.py:25-78](file://backend/app/api/citations.py#L25-L78)
|
||
|
||
**章节来源**
|
||
- [tests/test_citations.py:1-93](file://tests/test_citations.py#L1-L93)
|
||
- [backend/app/api/citations.py:1-78](file://backend/app/api/citations.py#L1-L78)
|
||
|
||
### 查询管理测试策略
|
||
- 测试目标
|
||
- 创建查询(含配额限制场景)
|
||
- 列表查询与分页
|
||
- 更新查询(字段变更)
|
||
- 删除查询
|
||
- 查询不存在与跨用户访问控制
|
||
- 关键测试点
|
||
- 通过patch服务函数返回模拟查询对象或抛出权限异常
|
||
- 断言HTTP状态码与响应体字段
|
||
- 用例设计要点
|
||
- 权限异常断言403与错误详情
|
||
- 跨用户访问断言404(模拟查询归属判定)
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant T as "测试用例"
|
||
participant AC as "异步HTTP客户端"
|
||
participant Q as "查询路由"
|
||
participant SVC as "服务层"
|
||
T->>AC : POST /api/v1/queries/
|
||
AC->>Q : 路由处理
|
||
Q->>SVC : 创建查询
|
||
SVC-->>Q : 返回查询或抛出权限异常
|
||
Q-->>AC : 201/403
|
||
AC-->>T : 断言
|
||
T->>AC : GET /api/v1/queries/?skip=&limit=
|
||
AC->>Q : 路由处理
|
||
Q->>SVC : 获取查询列表
|
||
SVC-->>Q : 返回(items,total)
|
||
Q-->>AC : 200 + JSON
|
||
AC-->>T : 断言
|
||
T->>AC : PUT /api/v1/queries/{id}
|
||
AC->>Q : 路由处理
|
||
Q->>SVC : 更新查询
|
||
SVC-->>Q : 返回更新后的查询或None
|
||
Q-->>AC : 200/404
|
||
AC-->>T : 断言
|
||
T->>AC : DELETE /api/v1/queries/{id}
|
||
AC->>Q : 路由处理
|
||
Q->>SVC : 删除查询
|
||
SVC-->>Q : 返回True/False
|
||
Q-->>AC : 204/404
|
||
AC-->>T : 断言
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/test_queries.py:29-154](file://tests/test_queries.py#L29-L154)
|
||
- [backend/app/api/queries.py:15-86](file://backend/app/api/queries.py#L15-L86)
|
||
|
||
**章节来源**
|
||
- [tests/test_queries.py:1-154](file://tests/test_queries.py#L1-L154)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
|
||
## 业务流程测试策略
|
||
|
||
### 测试目标
|
||
业务流程测试旨在验证GEO应用的核心业务场景,包括用户完整注册登录流程、查询词生命周期管理、权限隔离机制、配额限制控制、统计计算准确性以及CSV导出功能。
|
||
|
||
### 关键测试场景
|
||
- **完整用户流程**:从注册到登录再到查询管理的端到端流程
|
||
- **查询生命周期**:创建、更新、暂停、恢复、删除的完整生命周期
|
||
- **权限隔离**:确保用户间数据完全隔离
|
||
- **配额限制**:免费用户的查询数量限制验证
|
||
- **统计准确性**:引用统计数据的正确性验证
|
||
- **CSV导出**:导出功能的完整性测试
|
||
|
||
### 测试实现策略
|
||
- **用户管理**:通过fixture创建真实用户账户,模拟完整的用户生命周期
|
||
- **权限测试**:使用两个独立用户账户验证权限隔离机制
|
||
- **数据验证**:直接操作数据库模型验证统计计算的准确性
|
||
- **端到端验证**:通过异步HTTP客户端验证完整的业务流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant T as "业务流程测试"
|
||
participant AC as "异步HTTP客户端"
|
||
participant AUTH as "认证路由"
|
||
participant QUERIES as "查询路由"
|
||
participant CITATIONS as "引用路由"
|
||
participant DB as "数据库"
|
||
T->>AC : 注册用户
|
||
AC->>AUTH : POST /api/v1/auth/register
|
||
AUTH->>DB : 创建用户记录
|
||
AUTH-->>AC : 201 Created
|
||
T->>AC : 登录用户
|
||
AC->>AUTH : POST /api/v1/auth/login
|
||
AUTH-->>AC : 200 OK + Token
|
||
T->>AC : 创建查询
|
||
AC->>QUERIES : POST /api/v1/queries/
|
||
QUERIES->>DB : 创建查询记录
|
||
QUERIES-->>AC : 201 Created
|
||
T->>AC : 验证统计
|
||
AC->>CITATIONS : GET /api/v1/citations/stats
|
||
CITATIONS->>DB : 查询引用记录
|
||
CITATIONS-->>AC : 200 OK + 统计数据
|
||
AC-->>T : 断言业务流程正确性
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/test_business_flow.py:83-126](file://tests/test_business_flow.py#L83-L126)
|
||
- [tests/test_business_flow.py:131-186](file://tests/test_business_flow.py#L131-L186)
|
||
- [tests/test_business_flow.py:192-222](file://tests/test_business_flow.py#L192-L222)
|
||
- [tests/test_business_flow.py:228-296](file://tests/test_business_flow.py#L228-L296)
|
||
|
||
### 测试用例设计要点
|
||
- **用户隔离**:使用独立fixture创建多个用户,确保权限测试的准确性
|
||
- **数据完整性**:通过直接操作数据库模型验证统计计算的正确性
|
||
- **流程完整性**:覆盖业务流程的所有关键节点和异常场景
|
||
- **边界条件**:测试配额限制、权限边界等关键边界条件
|
||
|
||
**章节来源**
|
||
- [tests/test_business_flow.py:1-441](file://tests/test_business_flow.py#L1-L441)
|
||
|
||
## 调度器测试策略
|
||
|
||
### 测试目标
|
||
调度器测试专注于验证查询调度器的定时任务执行能力,包括调度器的启动/关闭、查询任务筛选机制、频率计算逻辑以及遗留任务处理功能。
|
||
|
||
### 关键测试场景
|
||
- **调度器生命周期**:启动、正常运行和优雅关闭
|
||
- **查询筛选机制**:仅执行活跃且到期的查询任务
|
||
- **频率计算**:daily和weekly频率的next_query_at计算
|
||
- **遗留任务处理**:处理超过1分钟未执行的pending任务
|
||
- **异常处理**:查询执行失败时的异常处理和日志记录
|
||
|
||
### 测试实现策略
|
||
- **调度器控制**:通过patch替换真实的APScheduler,使用AsyncMock控制调度器行为
|
||
- **数据库隔离**:使用独立的测试会话,确保调度器测试不影响其他测试
|
||
- **时间控制**:通过精确的时间戳控制查询的到期状态
|
||
- **频率验证**:使用datetime.utcnow()进行精确的时间计算验证
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class QueryScheduler {
|
||
+start() void
|
||
+check_and_execute_queries() void
|
||
+check_and_execute_pending_tasks() void
|
||
+shutdown() void
|
||
-_run_check() void
|
||
-_run_pending_tasks_check() void
|
||
-_execute_single_query(query, db) void
|
||
}
|
||
class CitationEngine {
|
||
+execute_query(query, db) list
|
||
+execute_single_platform(keyword, platform, target_brand, brand_aliases) dict
|
||
}
|
||
class AsyncIOScheduler {
|
||
+add_job(job, trigger, id, name) void
|
||
+start() void
|
||
+shutdown() void
|
||
}
|
||
QueryScheduler --> CitationEngine : "调用"
|
||
QueryScheduler --> AsyncIOScheduler : "使用"
|
||
```
|
||
|
||
**图表来源**
|
||
- [backend/app/workers/scheduler.py:27-182](file://backend/app/workers/scheduler.py#L27-L182)
|
||
|
||
### 测试用例设计要点
|
||
- **调度器生命周期**:验证调度器启动时添加的定时任务和名称
|
||
- **查询筛选**:通过创建不同状态和到期时间的查询验证筛选逻辑
|
||
- **频率计算**:使用绝对误差容差验证next_query_at的计算精度
|
||
- **遗留任务处理**:验证pending任务的兜底处理机制
|
||
- **异常处理**:确保查询执行失败时不会中断整个调度流程
|
||
|
||
**章节来源**
|
||
- [tests/test_scheduler.py:1-123](file://tests/test_scheduler.py#L1-L123)
|
||
- [backend/app/workers/scheduler.py:1-182](file://backend/app/workers/scheduler.py#L1-L182)
|
||
|
||
## 依赖分析
|
||
- 测试与被测模块耦合
|
||
- 测试通过ASGI传输直接调用路由,避免引入额外适配层
|
||
- 通过依赖覆盖与patch解耦服务层与数据库、第三方平台
|
||
- 业务流程测试直接操作数据库模型,确保测试数据的准确性
|
||
- 外部依赖与集成点
|
||
- 数据库:通过异步引擎与会话管理,测试中可使用内存数据库或独立测试库
|
||
- JWT:通过服务层令牌生成与校验,测试中直接构造令牌头
|
||
- 平台适配器:通过patch替换,避免真实网络请求
|
||
- 调度器:通过patch替换真实的APScheduler,使用AsyncMock控制调度行为
|
||
- 循环依赖与风险
|
||
- 当前结构清晰,无明显循环依赖;注意在测试中避免对真实调度器的依赖
|
||
|
||
```mermaid
|
||
graph LR
|
||
T_AUTH["测试: 认证"] --> A_AUTH["路由: 认证"]
|
||
T_QUERIES["测试: 查询"] --> A_QUERIES["路由: 查询"]
|
||
T_CIT["测试: 引用"] --> A_CIT["路由: 引用"]
|
||
T_BUSINESS["测试: 业务流程"] --> A_QUERIES
|
||
T_BUSINESS --> A_CIT
|
||
T_SCHED["测试: 调度器"] --> QS["调度器: QueryScheduler"]
|
||
A_AUTH --> S_AUTH["服务: 认证"]
|
||
A_QUERIES --> S_QUERY["服务: 查询"]
|
||
A_CIT --> S_CIT["服务: 引用"]
|
||
S_AUTH --> DB["数据库"]
|
||
S_QUERY --> DB
|
||
S_CIT --> DB
|
||
QS --> CE["引擎: CitationEngine"]
|
||
QS --> DB
|
||
DB --> CFG["配置"]
|
||
```
|
||
|
||
**图表来源**
|
||
- [tests/test_auth.py:1-104](file://tests/test_auth.py#L1-L104)
|
||
- [tests/test_business_flow.py:1-441](file://tests/test_business_flow.py#L1-L441)
|
||
- [tests/test_scheduler.py:1-123](file://tests/test_scheduler.py#L1-L123)
|
||
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
|
||
- [backend/app/api/queries.py:1-86](file://backend/app/api/queries.py#L1-L86)
|
||
- [backend/app/api/citations.py:1-78](file://backend/app/api/citations.py#L1-L78)
|
||
- [backend/app/workers/scheduler.py:1-182](file://backend/app/workers/scheduler.py#L1-L182)
|
||
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
|
||
- [backend/app/config.py:1-23](file://backend/app/config.py#L1-L23)
|
||
|
||
**章节来源**
|
||
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
|
||
- [backend/app/config.py:1-23](file://backend/app/config.py#L1-L23)
|
||
|
||
## 性能考虑
|
||
- 测试并发与资源
|
||
- 使用pytest-asyncio并行执行异步测试,减少总耗时
|
||
- 通过会话级调度器模拟避免真实后台任务带来的不稳定因素
|
||
- 业务流程测试使用内存数据库,避免磁盘I/O开销
|
||
- 数据库与缓存
|
||
- 建议使用独立测试数据库实例,避免与开发/生产数据冲突
|
||
- 对高频查询场景,可在测试中模拟数据库延迟,评估路由与服务层的超时与重试策略
|
||
- 调度器测试使用AsyncMock,避免真实的定时任务执行
|
||
- 接口响应与序列化
|
||
- 对大列表与统计聚合接口,关注JSON序列化开销与分页参数边界
|
||
- 业务流程测试中直接操作数据库模型,避免不必要的API调用
|
||
- 平台适配器性能
|
||
- 通过patch模拟不同响应时延与错误率,评估引擎的容错与降级策略
|
||
- 调度器测试中使用精确的时间控制,避免真实的等待时间
|
||
|
||
## 故障排查指南
|
||
- 常见问题定位
|
||
- 认证失败:检查令牌生成与头设置、依赖覆盖是否生效
|
||
- 404查询:确认查询ID与用户归属,检查服务层查询逻辑
|
||
- 403配额:检查服务层权限异常抛出与HTTP状态映射
|
||
- 调度器异常:检查APScheduler的启动状态和job配置
|
||
- 业务流程失败:检查数据库事务和fixture的使用
|
||
- 调试技巧
|
||
- 在conftest中临时打印依赖解析过程,定位get_current_user解析失败原因
|
||
- 使用pytest的-v与-s选项查看详细输出,结合patch的side_effect观察异常传播
|
||
- 对数据库相关测试,开启SQLAlchemy echo以查看生成的SQL
|
||
- 调度器测试中使用AsyncMock的assert_called_once()验证调度器行为
|
||
- 性能与稳定性
|
||
- 对于长时间运行的异步测试,确保事件循环正确关闭
|
||
- 对需要真实网络请求的场景,优先使用patch模拟,必要时增加超时与重试
|
||
- 业务流程测试中合理使用fixture,避免重复创建昂贵的对象
|
||
|
||
## 结论
|
||
本测试策略以Pytest为核心,结合会话级调度器模拟、依赖覆盖与patch技术,实现了对认证、查询、引用、引擎模块以及业务流程和调度器的全面覆盖。通过明确的夹具与测试数据管理,确保测试的可维护性与可重复性。新增的业务流程测试和调度器测试进一步完善了测试体系,涵盖了端到端业务场景和定时任务调度的关键功能。建议在CI中启用并行执行与覆盖率统计,并为数据库与平台适配器建立稳定的模拟层,持续提升测试效率与质量。
|
||
|
||
## 附录
|
||
- 测试覆盖率要求建议
|
||
- 语句覆盖率:≥80%
|
||
- 分支覆盖率:≥70%
|
||
- 行覆盖率:≥80%
|
||
- 函数/方法覆盖率:≥90%
|
||
- 业务流程覆盖率:≥95%
|
||
- 调度器覆盖率:≥90%
|
||
- 持续集成配置建议
|
||
- 使用GitHub Actions或GitLab CI,包含Python版本矩阵、依赖安装、数据库准备、pytest执行与覆盖率上传
|
||
- 将测试与lint、类型检查并行,确保主干分支质量
|
||
- 为业务流程测试和调度器测试单独配置执行时间限制
|
||
- 测试环境管理
|
||
- 使用独立测试数据库与Redis实例,避免污染
|
||
- 通过环境变量切换测试配置,确保敏感信息不泄露
|
||
- 业务流程测试使用内存数据库,调度器测试使用AsyncMock
|
||
- 性能测试方法
|
||
- 使用pytest-benchmark或locust对高频路由进行基准测试
|
||
- 对引擎执行流程进行压力测试,评估平台适配器与数据库写入瓶颈
|
||
- 调度器测试中使用时间控制和AsyncMock,避免真实的定时等待
|
||
- 业务流程测试中评估端到端流程的响应时间和吞吐量 |