# 集成测试 **本文引用的文件** - [tests/conftest.py](file://tests/conftest.py) - [backend/app/main.py](file://backend/app/main.py) - [backend/app/database.py](file://backend/app/database.py) - [backend/app/config.py](file://backend/app/config.py) - [docker-compose.yml](file://docker-compose.yml) - [tests/test_auth.py](file://tests/test_auth.py) - [tests/test_queries.py](file://tests/test_queries.py) - [tests/test_citations.py](file://tests/test_citations.py) - [backend/app/api/deps.py](file://backend/app/api/deps.py) - [backend/app/api/auth.py](file://backend/app/api/auth.py) - [backend/app/api/queries.py](file://backend/app/api/queries.py) - [backend/app/api/citations.py](file://backend/app/api/citations.py) - [backend/app/workers/scheduler.py](file://backend/app/workers/scheduler.py) - [backend/app/services/auth.py](file://backend/app/services/auth.py) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向GEO项目的集成测试,系统性阐述端到端测试的实现方法与最佳实践,覆盖以下方面: - FastAPI应用测试:通过ASGI传输层在内存中启动应用,使用异步HTTP客户端进行端到端请求验证。 - 数据库连接测试:基于异步SQLAlchemy引擎与会话管理,确保依赖注入与数据库交互正确。 - 外部服务集成测试:通过依赖注入覆盖与模拟(patch)实现对外部平台(如wenxin、kimi)的模拟调用。 - 测试环境配置:测试数据库、异步客户端、依赖注入覆盖与后台调度器的处理策略。 - 完整用户工作流:从认证到查询创建、执行到结果返回的端到端流程验证。 - 数据库事务与测试数据隔离:通过依赖注入覆盖与会话生命周期管理保障隔离性。 - 性能与负载测试:提供可扩展的测试方法与建议。 ## 项目结构 GEO采用前后端分离架构,后端使用FastAPI + SQLAlchemy异步ORM,测试位于tests目录,通过pytest与pytest-asyncio驱动异步测试。数据库与缓存服务通过Docker Compose编排,便于本地与CI环境一致化。 ```mermaid graph TB subgraph "测试环境" TC["测试客户端
AsyncClient(ASGI)"] CFG["测试配置
Settings(.env)"] DC["Docker Compose
db, redis, backend, frontend"] end subgraph "后端" APP["FastAPI 应用
app.main"] DEPS["依赖注入
api.deps"] AUTH["认证路由
api.auth"] QUERIES["查询路由
api.queries"] CITATIONS["引用路由
api.citations"] SCHED["调度器
workers.scheduler"] DB["数据库引擎/会话
database.py"] end DC --> APP CFG --> APP TC --> APP APP --> AUTH APP --> QUERIES APP --> CITATIONS APP --> SCHED AUTH --> DB QUERIES --> DB CITATIONS --> DB DEPS --> DB ``` 图表来源 - [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48) - [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/database.py:1-29](file://backend/app/database.py#L1-L29) - [backend/app/workers/scheduler.py:1-95](file://backend/app/workers/scheduler.py#L1-L95) - [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71) 章节来源 - [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48) - [docker-compose.yml:1-71](file://docker-compose.yml#L1-L71) ## 核心组件 - 异步HTTP客户端与ASGI传输层:通过ASGITransport在内存中启动FastAPI应用,避免真实网络开销,提升测试速度与稳定性。 - 依赖注入覆盖:使用app.dependency_overrides在测试中替换真实依赖(如认证用户),以模拟不同业务场景。 - 认证与令牌:通过create_access_token生成JWT,配合OAuth2PasswordBearer在路由中校验令牌。 - 数据库引擎与会话:异步SQLAlchemy引擎与会话工厂,确保测试中数据库交互的可控性与隔离性。 - 后台调度器:QueryScheduler负责周期性检查并触发查询任务,测试中通过mock屏蔽真实调度,防止后台任务干扰测试。 章节来源 - [tests/conftest.py:19-71](file://tests/conftest.py#L19-L71) - [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43) - [backend/app/services/auth.py:24-34](file://backend/app/services/auth.py#L24-L34) - [backend/app/database.py:6-29](file://backend/app/database.py#L6-L29) - [backend/app/workers/scheduler.py:25-95](file://backend/app/workers/scheduler.py#L25-L95) ## 架构总览 下图展示测试视角下的端到端调用链路,从异步客户端发起请求,经由FastAPI路由、依赖注入、服务层,最终访问数据库或外部平台(通过模拟)。 ```mermaid sequenceDiagram participant Test as "测试客户端" participant App as "FastAPI 应用" participant Dep as "依赖注入
get_current_user" participant Auth as "认证路由
/api/v1/auth/*" participant Queries as "查询路由
/api/v1/queries/*" participant Citations as "引用路由
/api/v1/citations/*" participant DB as "数据库引擎/会话" Test->>App : "POST /api/v1/auth/register" App->>Dep : "解析令牌/校验用户" App->>Auth : "注册逻辑" Auth->>DB : "写入用户" DB-->>Auth : "提交成功" Auth-->>Test : "201 用户信息" Test->>App : "POST /api/v1/auth/login" App->>Auth : "登录校验" Auth-->>Test : "200 {access_token}" Test->>App : "POST /api/v1/queries/" App->>Dep : "校验令牌并解析用户" App->>Queries : "创建查询" Queries->>DB : "插入查询记录" DB-->>Queries : "提交成功" Queries-->>Test : "201 查询详情" Test->>App : "GET /api/v1/citations/?query_id=..." App->>Dep : "校验令牌并解析用户" App->>Citations : "查询引用数据" Citations->>DB : "读取引用记录" DB-->>Citations : "返回数据" Citations-->>Test : "200 引用列表" ``` 图表来源 - [tests/test_auth.py:25-104](file://tests/test_auth.py#L25-L104) - [tests/test_queries.py:29-154](file://tests/test_queries.py#L29-L154) - [tests/test_citations.py:23-93](file://tests/test_citations.py#L23-L93) - [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/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43) - [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29) ## 详细组件分析 ### 测试环境与配置 - 测试数据库与外部服务:通过Docker Compose启动PostgreSQL与Redis,确保测试与生产环境一致;数据库URL与Redis URL在配置类中定义,便于在测试中覆盖。 - 异步客户端:使用ASGITransport在内存中启动FastAPI应用,避免网络抖动对测试的影响。 - 依赖注入覆盖:在conftest中定义override_get_current_user,使所有需要认证的路由在测试中自动获得模拟用户。 - 调度器屏蔽:通过mock_scheduler在测试期间禁用真实调度器,防止后台任务影响测试稳定性。 章节来源 - [docker-compose.yml:4-51](file://docker-compose.yml#L4-L51) - [backend/app/config.py:7-14](file://backend/app/config.py#L7-L14) - [tests/conftest.py:19-71](file://tests/conftest.py#L19-L71) ### 认证与用户工作流测试 - 注册与登录:通过patch模拟注册与登录服务,断言状态码与响应字段,确保认证流程正确。 - 当前用户信息:在依赖注入覆盖下,调用/me接口返回当前用户信息。 - 未认证访问:移除依赖注入覆盖后,访问受保护路由应返回401。 ```mermaid sequenceDiagram participant C as "测试客户端" participant A as "认证路由" participant S as "认证服务" participant D as "数据库" C->>A : "POST /api/v1/auth/register" A->>S : "register_user()" S->>D : "查询邮箱是否存在" S->>D : "插入新用户" D-->>S : "提交成功" S-->>A : "返回用户" A-->>C : "201 Created" C->>A : "POST /api/v1/auth/login" A->>S : "authenticate_user()" S->>D : "查询用户并校验密码" D-->>S : "返回用户" S-->>A : "生成JWT" A-->>C : "200 {access_token}" ``` 图表来源 - [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) 章节来源 - [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) ### 查询管理端到端测试 - 创建查询:在依赖注入覆盖与令牌头下,调用创建接口,断言返回字段与状态码。 - 列表与详情:通过patch模拟服务层返回值,断言分页与字段一致性。 - 更新与删除:断言更新后的字段与删除后的状态码。 - 权限限制:当超过配额时,断言403错误与错误信息。 - 资源不存在:断言404错误与错误信息。 ```mermaid sequenceDiagram participant C as "测试客户端" participant Q as "查询路由" participant S as "查询服务" participant D as "数据库" C->>Q : "POST /api/v1/queries/" Q->>S : "create_query()" S->>D : "插入查询记录" D-->>S : "提交成功" S-->>Q : "返回查询" Q-->>C : "201 Created" C->>Q : "GET /api/v1/queries/?skip=&limit=" Q->>S : "get_queries()" S->>D : "查询记录" D-->>S : "返回列表" S-->>Q : "返回分页" Q-->>C : "200 OK" C->>Q : "PUT /api/v1/queries/{id}" Q->>S : "update_query()" S->>D : "更新记录" D-->>S : "提交成功" S-->>Q : "返回更新后记录" Q-->>C : "200 OK" C->>Q : "DELETE /api/v1/queries/{id}" Q->>S : "delete_query()" S->>D : "删除记录" D-->>S : "提交成功" S-->>Q : "返回True" Q-->>C : "204 No Content" ``` 图表来源 - [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:29-154](file://tests/test_queries.py#L29-L154) - [backend/app/api/queries.py:15-86](file://backend/app/api/queries.py#L15-L86) ### 引用数据与统计导出测试 - 引用列表:断言分页、字段与过滤参数生效。 - 统计信息:断言总量、引用率、按平台分布与趋势数据。 - CSV导出:断言内容类型、附件头与CSV内容片段。 ```mermaid sequenceDiagram participant C as "测试客户端" participant R as "引用路由" participant RS as "引用服务" participant D as "数据库" C->>R : "GET /api/v1/citations/?query_id=&platform=&start_date=&end_date=&skip=&limit=" R->>RS : "get_citations()" RS->>D : "查询引用记录" D-->>RS : "返回列表" RS-->>R : "返回分页" R-->>C : "200 OK" C->>R : "GET /api/v1/citations/stats?query_id=" R->>RS : "get_citation_stats()" RS->>D : "聚合统计" D-->>RS : "返回统计" RS-->>R : "返回统计" R-->>C : "200 OK" C->>R : "GET /api/v1/reports/export/csv?query_id=" R->>RS : "export_citations_csv()" RS-->>R : "返回CSV内容" R-->>C : "200 OK, text/csv, attachment" ``` 图表来源 - [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:23-93](file://tests/test_citations.py#L23-L93) - [backend/app/api/citations.py:25-78](file://backend/app/api/citations.py#L25-L78) ### 数据库事务管理与测试数据隔离 - 会话生命周期:get_db提供异步会话生成与关闭,确保每次请求在独立会话中执行,避免跨请求污染。 - 依赖注入覆盖:通过app.dependency_overrides在测试中替换get_current_user,保证路由依赖始终可用且可控。 - 事务隔离:测试中通过patch模拟服务层,不直接写入真实数据;若需真实写入,应在测试事务中回滚或使用独立测试库。 ```mermaid flowchart TD Start(["测试开始"]) --> Override["依赖注入覆盖
get_current_user"] Override --> Session["获取异步会话
get_db()"] Session --> Exec["执行路由/服务逻辑"] Exec --> Commit{"提交/回滚?"} Commit --> |提交| Close["关闭会话"] Commit --> |回滚| Close Close --> End(["测试结束"]) ``` 图表来源 - [tests/conftest.py:42-50](file://tests/conftest.py#L42-L50) - [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29) 章节来源 - [tests/conftest.py:42-50](file://tests/conftest.py#L42-L50) - [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29) ### 外部服务集成测试 - 平台模拟:通过patch将平台调用替换为模拟实现,断言触发查询任务与返回的任务信息。 - 调度器屏蔽:在测试期间mock调度器,避免真实后台任务执行,确保测试确定性。 章节来源 - [tests/test_citations.py:75-93](file://tests/test_citations.py#L75-L93) - [tests/conftest.py:19-26](file://tests/conftest.py#L19-L26) ## 依赖分析 - 应用生命周期:FastAPI应用在lifespan中启动调度器,并在关闭时优雅shutdown。 - 路由依赖:认证与查询/引用路由均依赖get_current_user与get_db,形成清晰的依赖链。 - 服务层:认证、查询、引用服务分别封装业务逻辑,便于在测试中通过patch进行替换。 ```mermaid graph LR APP["FastAPI 应用"] --> LIFE["lifespan 启停调度器"] APP --> AUTH["认证路由"] APP --> QUERIES["查询路由"] APP --> CITATIONS["引用路由"] AUTH --> DEPS["get_current_user"] QUERIES --> DEPS CITATIONS --> DEPS DEPS --> DB["get_db/AsyncSession"] ``` 图表来源 - [backend/app/main.py:13-22](file://backend/app/main.py#L13-L22) - [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43) - [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29) 章节来源 - [backend/app/main.py:13-22](file://backend/app/main.py#L13-L22) - [backend/app/api/deps.py:16-43](file://backend/app/api/deps.py#L16-L43) - [backend/app/database.py:23-29](file://backend/app/database.py#L23-L29) ## 性能考虑 - 内存测试:使用ASGI传输层与异步客户端,避免网络开销,提升测试吞吐量。 - 调度器控制:在测试中禁用真实调度器,减少后台任务对测试性能的影响。 - 数据库隔离:通过独立测试库或事务回滚策略,避免并发测试导致的数据竞争。 - 负载测试建议:可在现有测试基础上扩展压力测试脚本,结合异步客户端批量发送请求,监控响应时间与错误率;注意在测试环境中使用独立数据库实例以避免影响生产数据。 ## 故障排查指南 - 401未认证:确认测试中是否正确设置依赖注入覆盖与Authorization头。 - 403权限不足:检查配额限制逻辑与用户计划,确保测试数据符合预期。 - 404资源不存在:确认查询ID与用户归属,确保服务层返回None时路由抛出404。 - 调度器干扰:若出现不可预期的后台任务行为,确认是否启用了mock_scheduler。 章节来源 - [tests/test_auth.py:88-104](file://tests/test_auth.py#L88-L104) - [tests/test_queries.py:50-71](file://tests/test_queries.py#L50-L71) - [tests/test_queries.py:127-154](file://tests/test_queries.py#L127-L154) - [tests/conftest.py:19-26](file://tests/conftest.py#L19-L26) ## 结论 本文档提供了GEO项目集成测试的完整方法论与实施细节,涵盖FastAPI应用测试、数据库连接、外部服务模拟、端到端用户工作流验证、事务与隔离策略以及性能与负载测试建议。通过依赖注入覆盖与异步客户端,测试具备高可靠性与可维护性;借助Docker Compose与配置类,测试环境与生产环境保持一致,便于持续集成与部署。 ## 附录 - 建议在CI中增加: - 数据库迁移与初始化脚本的集成测试。 - Redis健康检查与连接超时重试策略验证。 - 前后端联调测试,确保API与前端交互稳定。