Airweave 后端测试体系实战:E2E 冒烟测试的目录结构、环境配置与运行指南
2026/9/17 20:12:07 网站建设 项目流程

Airweave 后端测试体系实战:E2E 冒烟测试的目录结构、环境配置与运行指南

【免费下载链接】airweaveOpen-source context retrieval layer for AI agents项目地址: https://gitcode.com/GitHub_Trending/ai/airweave

Airweave 是一个开源的 AI Agent 上下文检索层(context retrieval layer),其后端由 FastAPI 提供服务,测试体系以端到端(E2E)冒烟测试为核心。本文基于 backend/tests/README.md 展开,结合 backend/tests/e2e 下的真实源码,完整讲解后端测试目录的规划方式、E2E 测试的环境搭建、.env.test配置项含义、pytest 运行参数与标记体系,以及共享 Fixture 和冒烟用例的实现细节。读完本文,你将能独立为本仓库配置并运行整套 E2E 冒烟测试,并能读懂其测试基础设施的设计思路。

一、测试目录结构总览

原文档给出了后端测试目录的整体规划:

tests/ ├── e2e/ │ ├── config.py # Test configuration │ ├── conftest.py # Pytest fixtures │ ├── requirements.txt # Dependencies │ └── smoke/ # E2E test files ├── unit/ # Unit tests (future) └── integration/ # Integration tests (future)

对照当前仓库实际内容(位于 backend/tests),该规划已基本落地:

  • backend/tests/e2e/config.py:基于 Pydantic Settings 的类型安全测试配置类TestSettings,统一管理全部环境变量;
  • backend/tests/e2e/conftest.py:提供异步 HTTP 客户端、测试 Collection、各数据源连接(Stripe / Todoist / Asana / Slack / Gmail 等)与 Auth Provider 等共享 Fixture;
  • backend/tests/e2e/requirements.txt:E2E 测试依赖清单;
  • backend/tests/e2e/smoke:33 个冒烟测试文件,覆盖集合管理、搜索(v1/v2/流式)、同步、限流、Webhook、OAuth 等核心链路;
  • backend/tests/e2e/pytest.ini:E2E 目录独立的 pytest 配置;
  • backend/tests/unitbackend/tests/integration:原文档标注为 "future",当前仓库已分别补充了单元测试与集成测试目录,前者覆盖 adapters / api / core / domains / platform / schemas / search 等模块,后者覆盖 api 与 storage 两条链路。

除 E2E 目录自身的 conftest 外,仓库根级 backend/conftest.py 会在导入任何airweave模块前通过os.environ.setdefault注入FIRST_SUPERUSERENCRYPTION_KEYSTATE_SECRETPOSTGRES_*AUTH_ENABLED=falseDENSE_EMBEDDER等测试环境变量,并注册pytest_asyncio插件与全套fake_*依赖注入 Fixture(如fake_sync_servicefake_billing_service),供单测与领域测试共用。

二、环境准备与依赖安装

原文档给出的 E2E 测试启动步骤为:

cd tests/e2e pip install -r requirements.txt # 创建 .env.test 并填入你的凭据 # 运行测试 pytest smoke/

依赖清单(backend/tests/e2e/requirements.txt)面向异步 E2E 场景做了针对性选型:

  • pytest >= 7.4.0:测试框架主体;
  • pytest-asyncio >= 0.24.0:异步测试支持,配合asyncio_mode = auto无需逐个标注装饰器;
  • pytest-xdist >= 3.3.0:并行分发,-n auto即可按 CPU 核数并行;
  • httpx >= 0.25.0:异步 HTTP 客户端,用于直接请求后端 API;
  • pydantic >= 2.0.0 / pydantic-settings >= 2.0.0TestSettings的配置解析底座;
  • python-dotenv >= 1.0.0:加载.env.test环境文件;
  • qdrant-client >= 1.13.3:本地向量库客户端,用于校验索引结果;
  • fastapi==0.104.1 / uvicorn[standard]==0.24.0:固定版本的本地服务栈;
  • pyngrok >= 5.1.0:本地隧道工具,用于暴露本机端点供外部验证(如 Webhook)。

三、环境变量配置:.env.test与 TestSettings

E2E 测试通过.env.test文件注入全部敏感配置。仓库提供了可直接拷贝的模板 backend/tests/e2e/env.test.example,其字段名必须与 config.py 中TestSettings的定义严格一致(模板注释中明确说明 "names must match TestSettings in config.py")。

TestSettings继承pydantic_settings.BaseSettingsmodel_config指定env_file=".env.test"extra="ignore"(多余变量忽略而不报错),并定义了如下配置组:

配置项默认值说明
TEST_ENVlocal测试目标环境,枚举local/dev/prod
AIRWEAVE_API_KEYdev/prod 环境的 API Key
TEST_STRIPE_API_KEY必填Stripe API Key,校验必须以sk_开头且长度 ≥ 10
OPENAI_API_KEYOpenAI Key(embedding,可选)
TEST_NOTION_TOKEN必填Notion OAuth Token(token 注入场景)
TEST_GOOGLE_CLIENT_ID/TEST_GOOGLE_CLIENT_SECRET必填Google OAuth(BYOC 场景)
TEST_PIPEDREAM_*(5 项)必填Pipedream 的 project / account / external user / client 凭据
TEST_TRELLO_CONSUMER_KEY/_SECRET必填Trello OAuth1 凭据
TEST_AUTH_PROVIDER_NAMEcomposio校验必须等于composio
TEST_COMPOSIO_API_KEY必填Composio API Key
TEST_COMPOSIO_*_AUTH_CONFIG_ID/_ACCOUNT_ID各数据源(Asana / Slack / Gmail / Todoist / Notion / Google Drive)在 Composio 侧的认证配置
SKIP_STARTUPfalsetrue时跳过start.sh与容器健康检查
STRICT_MODEfalsetrue时要求所有可选环境变量必须存在
DEFAULT_TIMEOUT30API 请求默认超时(秒)
SYNC_TIMEOUT60同步操作超时(秒)
MAX_WORKERS4测试最大并行 worker 数

其中两个字段通过@field_validator做了运行时校验:TEST_STRIPE_API_KEY必须以sk_开头且长度不小于 10;TEST_AUTH_PROVIDER_NAME若传入非composio值会直接抛出ValueError(config.py),从配置层杜绝了错误的环境组合。

TestSettings还暴露了几个派生属性,测试代码通过这些属性间接访问环境:

  • api_url:按TEST_ENV映射 API 地址——localhttp://localhost:8001devhttps://api.dev-airweave.comprodhttps://api.airweave.ai(config.py);
  • requires_api_key:仅当TEST_ENVdev/prod时为真;
  • api_headers:始终携带Content-Type: application/jsonaccept: application/json,在 dev/prod 环境下自动追加x-api-key头;
  • qdrant_url:仅本地环境返回http://localhost:6333
  • test_env/test_notion_token/default_timeout/sync_timeout等小写别名属性,用于向后兼容。

文件末尾的settings = TestSettings()创建了全局单例,conftest 与各测试模块均直接导入该实例。

四、运行 E2E 冒烟测试

原文档与 backend/tests/e2e/README.md 共同给出了完整的运行方式:

# 全部冒烟测试 pytest smoke/ # 只跑单个文件 pytest smoke/test_sources.py # 常用选项 pytest smoke/ -v # 详细输出 pytest smoke/ -n auto # 按 CPU 核数并行(pytest-xdist) pytest smoke/ -x # 首个失败即停止 pytest smoke/ -m "not slow" # 跳过慢速测试

backend/tests/e2e/pytest.ini 为 E2E 目录预置了默认行为:

  • 发现规则testpaths = .python_files = test_*.pypython_classes = Test*python_functions = test_*
  • 异步配置(关键)asyncio_mode = autoasyncio_default_fixture_loop_scope = function,文件注释强调这组配置对防止事件循环问题至关重要;
  • addopts-v--tb=short--strict-markers--maxfail=5--color=yes--durations=10——即失败最多容忍 5 个、并输出耗时 Top10,便于定位慢用例;
  • 并行执行:注释说明使用pytest -n autopytest -n 4搭配 pytest-xdist。

仓库根级 backend/pytest.ini 则限定testpaths = tests、设置pythonpath = .(保证airweave包可导入)、asyncio_mode = auto,并注册了integration/rate_limit/api_rate_limit标记,与 E2E 目录的标记体系互补。

五、测试标记(Markers)与智能调度

E2E 冒烟测试通过自定义标记进行分类,标记定义同时存在于 pytest.ini 与 conftest.py 的pytest_configure钩子中(后者还注册了requires_composiolocal_onlycritical等补充标记):

标记语义
slow慢速测试,可用-m "not slow"剔除
requires_sync依赖已完成的同步数据
requires_temporal依赖 Temporal(仅本地)
critical必须通过的关键路径测试
requires_openai依赖 OpenAI API Key
requires_composio依赖 Composio Auth Provider
rate_limit消耗限流配额,最后执行
api_rate_limit消耗 API 限流配额,CI 中跳过
local_only需要本地环境(直接访问存储)

更值得关注的是pytest_collection_modifyitems钩子(conftest.py)实现的智能排序

  1. TEST_ENV != "local"时,自动为所有local_only用例追加 skip 标记,避免在远程环境误碰本地存储;
  2. rate_limit用例从整体集合中分离并重排到全部用例之后执行,保证配额类测试不会被并行 worker 干扰,其余用例保持原顺序。

同时 conftest 会打印重排统计信息(如Test order modified: N rate_limit tests will run last),便于在 CI 日志中确认调度结果。

六、共享 Fixture 体系:从 API 客户端到多档位数据源连接

backend/tests/e2e/conftest.py 是 E2E 测试的基础设施核心,按作用域与用途可分为几类:

6.1 客户端与资源基础

  • anyio_backend(session):固定返回asyncio,统一异步后端;
  • config(session):直接暴露settings单例;
  • api_client:基于httpx.AsyncClient,自动注入base_url=settings.api_urlapi_headerstimeout(默认 30s),并开启follow_redirects
  • collection(function):POST/collections/创建一个以时间戳命名的测试 Collection,测试结束后 DELETE 清理,属于"即建即销"模式;
  • module_api_client/module_collection:与上面等价但跨整个模块共享,减少重复创建开销。

6.2 真实第三方数据源连接

针对不同测试诉求,conftest 提供多档位的真实数据源连接 Fixture:

  • composio_auth_provider:通过 Composio 创建认证提供者。采用get-or-create + 最多 3 次重试策略(conftest.py):先 GET/auth-providers/connections/composio-test,404 后再 POST 创建;若因 pytest-xdist 多 worker 竞争触发UniqueViolation/duplicate key,则指数退避后重试 GET 复用其他 worker 已创建的实例,最后兜底再 GET 一次;
  • source_connection_fast:Todoist 快速连接,期望 30 秒内完成同步;
  • source_connection_medium:Asana 中等速度连接,期望 1~3 分钟完成同步;
  • source_connection_slack_federated:Slack联邦搜索连接(不落库同步,查询时实时检索 Slack API),缺少配置时pytest.skip优雅跳过;
  • source_connection_continuous_slow:Gmail 慢速连接,基于游标字段、同步至少 5 分钟;
  • timed_source_connection_fast/timed_source_connection_medium:仓库内置的TimedSource 模拟数据源,不依赖任何外部服务——fast 档 2 秒生成 20 个实体(用于验证同步完成后的状态),medium 档 30 秒生成 100 个实体(用于验证同步中途取消),适合无第三方凭据的 CI 环境;
  • module_source_connection_stripe:模块级 Stripe 连接,创建时sync_immediately: true立即同步,随后以 2 秒间隔轮询连接状态与sync.last_job最多 3 分钟等待同步完成,再通过搜索接口query: "customer OR invoice OR payment"最多 12 次重试验证数据真实可检索(同步完成 ≠ 已索引),最后才 yield 给测试使用;
  • pipedream_auth_provider/pipedream_rate_limit_auth_provider:分别用于常规测试与限流专项测试的 Pipedream 认证提供者,限流版使用独立的环境变量凭据避免配额互相挤占。

所有连接 Fixture 都遵循同一模式:测试结束后"best effort"清理(删除失败仅静默忽略),避免失败残留污染后续运行。

6.3 Webhook 接收端点

smoke/conftest.py 提供了webhook_receiverFixture:通过postb.in(免费 HTTP Request Bin,接受任意 POST 并返回 200)为每个用例创建独立 bin。其设计动机是:该 URL 既可从测试宿主机访问,也可从 Docker 容器内访问,从而绕开host.docker.internal/ ngrok / 防火墙等本地联调难题;每个测试独立 bin 则避免 pytest-xdist 并发时req/shift弹出式读取导致用例间"偷取"投递。Fixture 还会对新 bin 做一次 warm-up 请求(新建 bin 首次请求可能较慢)。

七、冒烟测试覆盖范围

backend/tests/e2e/smoke 目录下的用例覆盖了 Airweave 后端的主要业务面:

  • 集合与实体test_collections.pytest_collection_access_control.pytest_entity_definitions.py
  • 连接与认证test_source_connections_auth_provider.pytest_source_connections_direct_auth.pytest_source_connections_oauth.pytest_source_connections_template_configs.pytest_source_connections_token_injection.pytest_connect_sessions.pytest_special_tokens.py
  • 搜索test_search.pytest_search_filters.pytest_search_v2.pytest_search_v2_federated.pytest_search_v2_filters.pytest_search_v2_stream.pytest_federated_search.py
  • 同步与调度test_continuous_sync.pytest_running_and_cancelling_syncs.pytest_schedule_pause_unpause.pytest_schedules.pytest_sync_*(含在相关文件中)
  • 限流test_rate_limiting.pytest_source_rate_limiting.py
  • Webhook 与事件test_webhooks.pytest_pubsub.py
  • 清理与杂项test_cleanup.pytest_storage_backend.pytest_stub_file_types.pytest_exception_stub.pytest_organization_setup.pytest_sources.py

八、真实用例解剖:搜索与清理测试

以 test_search.py 为例,其核心用例test_search_with_all_defaults只传一个query字段调用统一的搜索端点POST /collections/{readable_collection_id}/search,通过断言completion字段间接验证defaults.yml中的默认行为(expand_query: truererank: truegenerate_answer: trueretrieval_strategy: hybridtemporal_relevance: 0.3limit: 1000)真正生效——即"测试即文档",默认配置的变动会被测试捕获。

test_cleanup.py 则系统验证资源删除语义:删除带数据与不带数据的 Source Connection / Collection、级联删除(先建 Collection 再建连接后删除 Collection)、删除后列表不再包含、按"先连接后集合"的顺序清理,以及对不存在的资源返回 404 的错误处理。其中test_delete_collection断言status_code in [200, 404],反映了级联删除实现下"幂等清理"的容忍策略。

九、常见问题与最佳实践

  • 依赖与后端未就绪:首次运行前需pip install -r requirements.txt,并确保本地后端(http://localhost:8001)与依赖服务(PostgreSQL、Qdrant、Temporal)已启动;SKIP_STARTUP=true可跳过启动脚本与容器健康检查,适用于手动已启动环境的场景。
  • 凭据缺失TestSettings中的TEST_STRIPE_API_KEYTEST_NOTION_TOKEN、Composio 系列为必填,缺失会导致启动即失败;部分可选 Composio 配置(如 Slack、Gmail)在 Fixture 内用pytest.skip/pytest.fail明确区分"跳过"与"失败"。
  • 并行竞争:多个 pytest-xdist worker 同时创建同名资源会触发唯一键冲突,conftest 中的 get-or-create 重试、独立 postb.in bin、独立测试 Collection 命名(时间戳 + uuid)共同降低了这类竞态;rate_limit用例被强制排到最后也避免了配额竞争。
  • 异步事件循环:E2E 目录的 pytest.ini 必须保留asyncio_mode = autoasyncio_default_fixture_loop_scope = function,否则异步 Fixture 与用例混跑会出现事件循环错位。

总而言之,Airweave 的后端测试体系以 backend/tests/README.md 为入口、以 backend/tests/e2e/config.py 的类型安全配置为底座、以 backend/tests/e2e/conftest.py 的多档位 Fixture 为骨架,配合标记调度与智能排序,构成了一套可本地调试、可并行、可上 CI 的真实环境冒烟测试方案——这也是理解 Airweave 后端各 API 与同步/搜索/限流机制最直接的入口。

【免费下载链接】airweaveOpen-source context retrieval layer for AI agents项目地址: https://gitcode.com/GitHub_Trending/ai/airweave

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询