
OGX 集成测试指南基于记录-回放机制的跨 Provider 端到端测试体系【免费下载链接】ogxOpen GenAI Stack项目地址: https://gitcode.com/GitHub_Trending/ll/ogxOGXOpen GenAI Stack提供了一套完整的集成测试体系覆盖从 Chat Completions、Embeddings、Vision 到 Agents、Responses API、Vector IO、Telemetry 等全部 API 表面并基于自研的「记录-回放」record-replay机制让测试无需真实调用付费 API 也能稳定、可重复地在本地与 CI 中运行。本文以 tests/integration/README.md 为骨架结合仓库内conftest.py、suites.py、api_recorder.py、integration-tests.sh等源码系统讲解集成测试的启动方式、配置项、录制模式、录音管理与测试编写方法帮助你在一小时内上手并扩展 OGX 的端到端测试。集成测试验证的是「跨多个 Provider 的完整工作流」例如本地 Ollama 上的推理 → 服务器响应 → 客户端消费回放数据。与单元测试不同集成测试需要真实的模型后端本地推理引擎或云端 APIOGX 用「录制一次、处处回放」的方式解耦了这种依赖。各 Provider 的目标模型清单与 CI 车道CI lanes见 TARGET_MODELS.md该文件由scripts/generate_target_models_docs.py自动生成。快速开始在仓库根目录执行以下命令即可运行全部集成测试默认使用已有录音回放不产生任何真实 API 调用# Run all integration tests with existing recordings uv run --group dev \ pytest -sv tests/integration/ --stack-configstarter这里--stack-configstarter表示以库内联library client方式构建 Stack测试进程内部直接组装starter配置对应的各 Provider无需启动独立服务器。-sv用于输出每个测试的进度详情。Provider 依赖检查不同 Stack 配置依赖不同的 Provider 包例如 Ollama Provider 需要ollama包vLLM Provider 需要vllm相关依赖。scripts/integration-tests.sh会在运行测试前做一次「Provider 依赖预检」执行与 CI 完全相同的依赖安装命令ogx stack list-deps config | xargs -L1 uv pip install并解析uv pip list中已安装的包名做比对。若缺少依赖脚本会提前失败并给出精确的安装命令追加--install-deps参数则会自动安装缺失依赖后再运行测试。从 scripts/integration-tests.sh 的实现可以看到check_provider_dependencies函数会跳过--*标志及其取值、剥离[...]extras、版本号与环境标记后提取包名与已安装列表做大小写归一化比对。对docker:*与http://*配置会跳过预检依赖已打入镜像或由远端提供。配置选项集成测试基于 pytest 的addoption机制扩展了大量自定义命令行参数完整清单可通过以下命令查看关注输出中Custom options:一节cd tests/integration # this will show a long list of options, look for Custom options: pytest --help--stack-config以五种方式指向一个 Stack--stack-config是集成测试的核心参数它的取值决定测试连接「哪种形态」的 OGX Stack。根据 conftest.py 中的定义共有以下形式取值形式说明server:config自动启动一个使用给定配置的服务器如server:starter。若端口空闲则自动拉起服务若已有服务在运行则直接复用实现「一步到位」的测试server:config:port同上但指定自定义端口如server:starter:8322一个 URL指向一个已运行的 OGX 发行版distribution服务器发行版名称或config.yaml路径如starter或以库内联方式加载指定配置文件apiprovider逗号分隔列表动态组合 API 与 Provider如inferenceollama,responsesbuiltin最适合只测单一 API 表面在 conftest 的pytest_sessionstart钩子中系统会根据--stack-config是否以server:、docker:、http开头设置OGX_TEST_STACK_CONFIG_TYPE环境变量为server或library_client——这个标记直接影响录制系统在服务器模式下通过 HTTP 头传递测试上下文的行为见下文「Recording System Internals」。--env注入 Provider 所需环境变量pytest ... --env KEYvalue这是一个通用工具选项用于设置各 Provider 所需的环境变量如OLLAMA_URL、OPENAI_API_KEY。在pytest_configure钩子中所有--env值都会被split(, 1)解析后写入os.environ。模型相关参数以下参数控制测试使用的模型每个参数都支持逗号分隔的列表系统会自动生成多个参数组合笛卡尔积来展开测试--text-model文本模型列表--vision-model视觉模型列表--embedding-model嵌入模型列表--judge-model评测judge模型列表--embedding-dimension嵌入模型输出维度默认768--rerank-model重排模型列表conftest 中新增rerank_model_idfixture这些选项在 conftest.py 中注册并在pytest_generate_tests中通过itertools.product生成所有组合测试 ID 采用txt3B:embNomic-v1.5这类简短格式由get_short_id将模型名映射为短标识。注意如果没有指定任何模型测试会被跳过——这是 fixture 在参数为None时的预期行为。Suites 与 Setups按需收窄测试范围--suite单套命名测试集--suite用于收窄测试收集范围避免每次全量运行。套件定义集中在 suites.py可用套件包括base收集大多数测试排除 responses 目录默认 setup 为ollamaresponses仅收集tests/integration/responses下的测试需要强工具调用能力的模型vision仅收集tests/integration/inference/test_vision_inference.pymessages/messages-openai/v1/messages翻译路径测试后者使用 gpt 强制走 Anthropic→OpenAI 翻译代码路径而非原生透传interactionsGoogle Gemini 交互测试bedrock/bedrock-responses基于预录制响应的 AWS Bedrock 测试CI 中不进行实时 API 调用gpt-reasoning/ollama-reasoning/vllm-reasoning推理reasoning能力专项roots 精确到文件::测试函数base-vllm-subset仅 inference 目录 vllm从实现上看pytest_ignore_collect会跳过所选套件 roots 之外的路径以加速收集对于 roots 含::test_function的套件pytest_collection_modifyitems会进一步精确过滤到指定测试函数。base套件的 roots 通过目录 glob 动态生成排除__pycache__、fixtures、test_cases、recordings、responses、messages、interactions。--setup全局配置预设--setup是与任何套件都可搭配的「全局配置」用于预填模型与环境变量默认值显式 CLI 参数始终优先于 setup 默认值。在pytest_configure中setup 的env先写入环境变量不覆盖已存在的值随后defaults只填充尚未显式给定的 CLI 选项。核心 setup 包括Setup用途默认文本模型ollama本地 Ollama轻量模型设OLLAMA_URLollama/llama3.2:3b-instruct-fp16ollama-vision本地 Ollama 视觉模型ollama/llama3.2-vision:11bollama-postgres服务器模式 Postgres 持久化POSTGRES_HOST/PORT/DB/USER/PASSWORDollama/llama3.2:3b-instruct-fp16ollama-reasoningdeepseek-r1 推理模型ollama/deepseek-r1:1.5bvllmvLLM 高效本地推理设VLLM_URLvllm/Qwen/Qwen3-0.6Bvllm-gpu-gpt-ossGPU vLLM gpt-oss:20b 推理模型vllm/gpt-oss:20bgptOpenAI GPT 高质量响应gpt-4oopenai/gpt-4ogpt-reasoningOpenAI o4-mini 推理openai/o4-miniclaudeAnthropic Claudeanthropic/claude-3-5-haiku-20241022azureAzure 托管的 GPTazure/gpt-4obedrockAWS Bedrock 的 GPT-OSSbedrock/openai.gpt-oss-20b-1:0watsonxIBM watsonxwatsonx/meta-llama/llama-3-3-70b-instructvertexaiGoogle Vertex AI Geminivertexai/publishers/google/models/gemini-2.0-flash此外还有tgi、together、cerebras、databricks、fireworks、anthropic、llama-api、gemini、groq、llama-cpp-server、vllm-qwen3next等更多命名 setup完整定义见 suites.py。各 setup 对应的模型矩阵含视觉/嵌入模型可在 TARGET_MODELS.md 查阅。组合示例# Run conversations tests with GPT for high-quality responses pytest -s -v tests/integration/conversations --stack-configserver:starter --setupgpt # Fast responses run with a strong tool-calling model pytest -s -v tests/integration --stack-configserver:starter --suiteresponses --setupgpt # Fast single-file vision run with Ollama defaults pytest -s -v tests/integration --stack-configserver:starter --suitevision --setupollama # Base suite with VLLM for performance pytest -s -v tests/integration --stack-configserver:starter --suitebase --setupvllm # Override a default from setup pytest -s -v tests/integration --stack-configserver:starter \ --suiteresponses --setupgpt --embedding-modeltext-embedding-3-small注意--suitevision --setupollama示例中setup 显式指定时不会自动应用套件的默认 setupvision 的默认 setup 实为ollama-vision因此需要自行给出含视觉模型的配置。常见运行场景场景一针对服务器测试server 模式自动拉起starter配置的服务器并运行全部推理测试OLLAMA_URLhttp://localhost:11434 \ pytest -s -v tests/integration/inference \ --stack-configserver:starter \ --text-modelollama/llama3.2:3b-instruct-fp16 \ --embedding-modelnomic-embed-text-v1.5指定自定义端口服务器将被启动在 8322OLLAMA_URLhttp://localhost:11434 \ pytest -s -v tests/integration/inference/ \ --stack-configserver:starter:8322 \ --text-modelollama/llama3.2:3b-instruct-fp16 \ --embedding-modelnomic-embed-text-v1.5从 scripts/integration-tests.sh 可以看到server:模式下脚本会从 8321 起寻找空闲端口、以nohup ogx stack run config --insecure后台启动服务器轮询/v1/health与 IPv6 回环健康检查确认就绪并通过trap stop_server EXIT ERR INT TERM保证测试结束后清理进程。场景二库内联客户端library client库内联模式在进程内构造 Stack而不是连接服务器。对于迭代开发非常有用——无需反复启停服务器。只需把server:starter换成starterpytest -s -v tests/integration/inference --stack-configstarter --text-model... --embedding-model...conftest 中对该模式的说明是服务器模式下运行的测试集是库内联模式的超集部分用例依赖服务器端行为因此重新录制录音时必须使用服务器模式见下文。场景三ad-hoc 动态发行版有时你想「现场拼一个」发行版用来测试单个 Provider、单个 API 或少量 Provider 组合。此时用逗号分隔的apiprovider列表即可例如inferenceremote::ollama,responsesinline::builtinpytest -s -v tests/integration/inference/ \ --stack-configinferenceremote::ollama,responsesinline::builtin \ --text-model$TEXT_MODELS \ --vision-model$VISION_MODELS \ --embedding-model$EMBEDDING_MODELS再如单独运行 Vector IO 嵌入测试动态组合sentence-transformers推理与sqlite-vec向量库pytest -s -v tests/integration/vector_io/ \ --stack-configinferenceinline::sentence-transformers,vector_ioinline::sqlite-vec \ --embedding-modelnomic-embed-text-v1.5这类动态配置在 conftest 中通过run_config_from_dynamic_config_spec解析并支持自动推断默认嵌入模型例如检测到 sentence-transformers 时自动填入sentence-transformers/nomic-ai/nomic-embed-text-v1.5。录制模式四种运行方式OGX 集成测试支持四种由环境变量/CLI 控制的录制模式枚举定义于 api_recorder.pyCLI 选项为--inference-modeREPLAY 模式默认使用缓存的响应回放不发起任何 API 调用。录制缺失时测试直接失败这是 CI 中确定性最高的模式pytest tests/integration/RECORD-IF-MISSING 模式新增测试时推荐仅在不存在录音时才发起真实调用并记录已有录音则回放。这是迭代开发的推荐模式兼顾速度与补录能力pytest tests/integration/inference/test_new_feature.py --inference-moderecord-if-missingRECORD 模式强制录制所有 API 交互并覆盖已有录音。会重录一切谨慎使用pytest tests/integration/inference/test_new_feature.py --inference-moderecordLIVE 模式所有测试走真实 API 调用不记录pytest tests/integration/ --inference-modelive--inference-mode的取值限定为record/replay/live/record-if-missingconftest 的choices校验最终写入OGX_TEST_INFERENCE_MODE环境变量。默认录制目录为tests/integration/recordings可用OGX_TEST_RECORDING_DIR覆盖。从源码看实际的录制存储位于各测试目录下的recordings/子目录见ResponseStorage._get_test_dir的路径解析逻辑同时保留tests/integration/common/recordings作为会话级session-level录音的回退目录。录音管理查看录音录音以 JSON 文件 SQLite 索引的形式存储# See whats recorded sqlite3 recordings/index.sqlite SELECT endpoint, model, timestamp FROM recordings; # Inspect specific response cat recordings/responses/abc123.json | jq .自动化重录推荐当你提交包含新增或修改测试的 PR 时录音工作流会自动完成以下步骤检测缺失的测试录音使用 ollama 录制无需任何 API Key将录音提交回你的 PR出于安全考虑该工作流分两步执行Step 1以只读权限运行测试将录音作为 CI 产物artifacts上传Step 2仅以写权限运行可信的基础仓库代码将产物中的录音提交回 PR对 PR 作者而言直接开 PR 即可无需其他操作同仓库与 fork PR 均支持fork 需开启 Allow edits from maintainers。录音提交后会自动以回放模式再次触发测试验证新录音可正常回放。对维护者而言——需要 API Key 的 Providergpt、azure、bedrock的录制方式通过 GitHub UI进入Actions→Integration Tests (Record)点击Run workflow输入 PR 编号与 Providergpt,azure通过 GitHub CLI# Record for a specific PR with multiple providers gh workflow run record-integration-tests.yml \ -f pr_number1234 \ -f providersgpt,azure # Just gpt gh workflow run record-integration-tests.yml \ -f pr_number1234 \ -f providersgpt # Record specific subdirectories or patterns gh workflow run record-integration-tests.yml \ -f pr_number1234 \ -f subdirsagents,inference gh workflow run record-integration-tests.yml \ -f pr_number1234 \ -f patterntest_streaming可用 Provider 及其凭据要求Provider凭据要求ollama无需 API KeyPR 上自动运行gptOpenAI需要OPENAI_API_KEYsecretazureAzure OpenAI需要AZURE_API_KEY、AZURE_API_BASEsecretsbedrockAWS Bedrock需要AWS_BEARER_TOKEN_BEDROCKsecretwatsonxIBM watsonx需要WATSONX_API_KEY、WATSONX_BASE_URL、WATSONX_PROJECT_IDsecrets注意vllm目前尚未加入该录制工作流不在 Provider 矩阵中。新增 Provider 到录制工作流的步骤在.github/workflows/record-integration-tests.yml的provider矩阵中添加新条目- setup: your-provider suite: responses在Run and record tests步骤中添加该 Provider 的 API Key 环境变量YOUR_PROVIDER_API_KEY: ${{ matrix.provider.setup your-provider secrets.YOUR_PROVIDER_API_KEY || }}在仓库设置中添加对应的 GitHub secret本地重录# Re-record specific tests pytest -s -v --stack-configserver:starter tests/integration/inference/test_modified.py --inference-moderecord重要重录时必须使用指向服务器的 Stack即server:starter。原因在于服务器模式下运行的测试集合是库内联模式的超集——若用库内联模式重录部分仅在服务器端出现的请求将无法被覆盖。编写集成测试基本测试模式集成测试的 fixturesogx_client、text_model_id等由 conftest 注入测试只需关注结构而非 AI 输出质量def test_basic_chat_completion(ogx_client, text_model_id): response ogx_client.chat.completions.create( modeltext_model_id, messages[{role: user, content: Hello}], ) # Test structure, not AI output quality assert response.choices[0].message is not None assert isinstance(response.choices[0].message.content, str) assert len(response.choices[0].message.content) 0Provider 特定测试对于某些模型才支持的能力如带task_type的非对称嵌入应显式跳过不支持的模型def test_asymmetric_embeddings(ogx_client, embedding_model_id): if embedding_model_id not in MODELS_SUPPORTING_TASK_TYPE: pytest.skip(fModel {embedding_model_id} doesnt support task types) query_response ogx_client.inference.embeddings( model_idembedding_model_id, contents[What is machine learning?], task_typequery, ) assert query_response.embeddings is not None可参考的实际用例遍布各子目录例如 test_openai_completion.py、test_vision_inference.py、test_basic_responses.py 等。TypeScript 客户端回放Python 测试通过后TypeScript SDK 测试可与 Python 测试并行运行仅限server:config模式。通过TS_CLIENT_PATH指向ogx-client-typescript的版本或路径来启用# Use published npm package (responses suite) TS_CLIENT_PATH^0.3.2 scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt # Use local checkout from ~/.cache (recommended for development) git clone https://github.com/ogx-ai/ogx-client-typescript.git ~/.cache/ogx-client-typescript TS_CLIENT_PATH~/.cache/ogx-client-typescript scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt # Run base suite with TypeScript tests TS_CLIENT_PATH~/.cache/ogx-client-typescript scripts/integration-tests.sh --stack-config server:ci-tests --suite base --setup ollamaTypeScript 测试在 Python 测试全部通过后立即执行复用同一套回放 fixtures。Python 套件/setup 与 TypeScript 测试文件之间的映射定义在 tests/integration/client-typescript/suites.json。若未设置TS_CLIENT_PATHTypeScript 测试会被整体跳过。从 scripts/integration-tests.sh 可以看到脚本会区分目录路径与 npm 版本号目录路径会先执行npm installnpm run build构建本地客户端npm 版本则直接安装ogx-clientversion。目录结构integration/ admin/ # Admin API tests agents/ # Agent orchestration tests batches/ # Batch processing tests client-typescript/ # TypeScript SDK replay tests common/ # Shared test utilities and recording storage conversations/ # Conversation persistence tests datasets/ # Dataset management tests eval/ # Evaluation tests files/ # File management tests fixtures/ # Test fixtures and data inference/ # Inference API tests (chat completion, embeddings, vision) inspect/ # Inspect API tests post_training/ # Post-training tests providers/ # Provider-specific tests recordings/ # Cached API responses for replay mode responses/ # OpenAI Responses API tests scoring/ # Scoring tests telemetry/ # Telemetry tests test_cases/ # Shared test case definitions tool_runtime/ # Tool runtime tests tools/ # Tool integration tests vector_io/ # Vector I/O tests conftest.py # Main conftest (client setup, recording mode, fixtures) suites.py # Suite/setup definitions ci_matrix.json # CI test matrix configuration实际仓库中除上述目录外还包含interactions/、messages/、models/、openresponses/等目录README 列举的datasets/、eval/、post_training/、scoring/、tools/在演进中已归并入其他目录或迁移。conftest.py承担客户端初始化、录制模式读取与 fixture 生成三大职责suites.py是套件/setup 的单一事实来源ci_matrix.json 定义 CI 车道矩阵——默认车道共 16 条含baseollama、responsesgpt、responsesazure等另有gpu-vllm车道与每周日cron1 0 * * 0的定时车道。Recording System Internals记录-回放系统的实现细节记录/回放系统的核心实现位于 src/ogx/testing/api_recorder.py关键设计如下请求哈希Request hashing每个 API 调用通过哈希其参数方法名、模型、消息等匹配录音即使测试执行顺序发生变化也能正确回放。哈希计算见normalize_inference_request对请求体做递归归一化浮点四舍五入到 5 位、字符串内长小数四舍五入、规范化 file_search 元数据中的 score/document_id/attributes 等易变字段、剔除 Bedrock 端点的stream_options与根层的project_id并将当前测试 ID 混入哈希以保证测试间隔离——相同请求在不同测试中哈希不同。例外是模型列表端点/v1/models、/api/tags它们属于会话级共享基础设施哈希不包含 test_id。确定性 IDDeterministic IDs回放期间资源 ID文件、向量存储等通过计数器确定性地生成前缀见_ID_KIND_PREFIXESfile-、vs_、batch_、call_每个测试基于其 nodeid 的 SHA256 派生一个初始计数器保证同一测试每次运行产生完全相同的 ID从而让测试结果可复现。存储格式Storage format录音以 JSON 文件形式存储在 Provider 相关目录中同时使用 SQLite 索引将请求哈希映射到响应文件。录音文件包含test_id、request、response与id_normalization_mapping元数据响应体通过__type__/__data__携带 Pydantic 类型信息回放时用model_validate/model_construct反序列化还原对象。流式响应Streaming流式响应被录制成完整的 chunk 序列回放时逐 chunk 重新输出忠实还原流式行为。此外_normalize_response会把响应 ID 替换为rec-hash前12位、时间戳归零、Ollama 时长字段归零从而显著减少录音文件在 git diff 中的噪音。工具调用与重排请求工具调用如 Tavily 搜索通过normalize_tool_request哈希并走同样的录制逻辑HTTP 层重排rerank请求则通过 patchaiohttp.ClientSession.post在aiohttp层捕获仅拦截含/rerank的 URL保证客户端后处理如max_num_results应用在回放时仍能正常执行。服务器模式下的测试上下文传递在服务器模式下测试 ID 通过X-OGX-Provider-DataHTTP 头从客户端注入到服务器端patch_httpx_for_test_id利用 Stainless 客户端与 OpenAI 客户端的_prepare_request钩子实现使录制系统在跨进程场景下依然能按测试隔离录音。conftest 中还包含若干对测试行为有影响的细节pytest_sessionstart会为未设置SQLITE_STORE_DIR的会话创建临时目录作为存储根pytest_runtest_teardown支持通过OGX_TEST_INTERVAL_SECONDS为 inference/agents/responses 测试间插入间隔用于压测或节流场景autouse fixture_track_test_context将每个测试的 nodeid 写入 contextvar供录制系统定位录音子目录。CI 矩阵与 Responses 覆盖率ci_matrix.json 中的默认车道包含responsesgpt覆盖率 100%、responsesazure82%、responseswatsonx45%、responsesvertexai51%、bedrock-responsesbedrock20%等组合。Responses 功能点总计 137 个各 Provider 的实测覆盖情况汇总于 TARGET_MODELS.mdOpenAI 137/137100%、Azure 112/13782%、Vertex AI 70/13751%、WatsonX 62/13745%、Bedrock 27/13720%、Ollama 与 vLLM 各 3/1372%。这些数据源自回放录音与docs/docs/api-openai/provider_matrix.md同源是衡量各 Provider Responses API 对齐程度的重要参考。结语OGX 的集成测试体系以「录制-回放」为核心将昂贵的、不稳定的真实模型调用转化为廉价、确定性的本地回放同时通过--stack-config的五种形态、Suites/Setups 的组合编排、TypeScript 客户端的并行回放以及 CI 自动补录工作流覆盖了从本地迭代到多 Provider 云端矩阵的完整测试生命周期。无论你是为新增 Provider 编写测试、在本地复现 CI 失败还是维护多 Provider 的 Responses 兼容性这套体系都能让你以最小的外部依赖获得最大化的端到端信心。【免费下载链接】ogxOpen GenAI Stack项目地址: https://gitcode.com/GitHub_Trending/ll/ogx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考