OpenSRE 测试体系指南:目录规范、快速命令与端到端命名约定
2026/9/15 17:30:14 网站建设 项目流程

OpenSRE 测试体系指南:目录规范、快速命令与端到端命名约定

【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre

本文以仓库 tests/README.md 为核心骨架,结合 Makefile、pytest 配置与测试源码,系统讲解 OpenSRE 开源项目(Build your own AI SRE agents)的测试组织方式。你将掌握三套开箱即用的测试命令(覆盖、集成校验、全量回归)、tests/目录的分层约定、tests/e2e/与遥测的命名规则,以及如何快速定位某个领域(clitoolsintegrationscore等)对应的测试代码。

快速上手:三条核心命令

原文档给出了三组最常用的命令,它们分别对应「本地首跑」「集成改动后」「CI 回归」三种场景。

目标命令何时使用
运行默认单元测试套件并带覆盖率make test-cov本地第一件事;无需任何真实基础设施
校验所有集成配置与客户端make verify-integrations新增或修改集成之后
运行默认 pytest 全量收集(tests/e2e被 pytest 配置排除)make test-full本地或 CI 的宽泛回归

make test-cov:并行覆盖率跑分

在 Makefile 中,test-cov的实现是:

test-cov: $(PYTHON) -m pytest -n auto -v $(addprefix --cov=,$(PYTHON_SOURCE_PATHS)) --cov-report=term-missing

其中PYTHON_SOURCE_PATHS := bootstrap config core gateway integrations infrastructure surfaces tools(Makefile),即覆盖统计只针对这些产品源码目录,不把测试自身算进分母。-n auto借助 pytest-xdist 按 CPU 核数并行,--cov-report=term-missing会在终端列出未覆盖行号,方便逐行补测。

PYTHON变量的解析顺序(Makefile)值得注意:优先使用.venv/bin/python,其次.venv/Scripts/python.exe(Windows),最后回退到python3/python,保证在没有虚拟环境时命令依然可用。

make verify-integrations:集成配置与连通性校验

verify-integrations: uv run opensre integrations verify $(if $(SERVICE),$(SERVICE),) $(if $(SLACK_TEST),--send-slack-test,)

该命令实际调用 CLI 的opensre integrations verify(可传SERVICE限定单个集成,传SLACK_TEST=1触发 Slack 测试消息)。它对应 integrations/verify.py 等实现,会读取本地 store 与.env中的凭据逐项验证连通性。仓库还提供了更轻量的冒烟变体:

verify-integrations-smoke: $(PYTHON) -m pytest -q \ tests/integrations/test_verification_registry.py \ tests/integrations/test_registry.py

它只跑注册表/目录的契约测试,作为 CI 冒烟闸门,不触碰真实服务。

make test-full:全量回归

test-full: $(PYTHON) -m pytest -v

pytest 的testpaths(pytest.ini)为testsgateway/testscore/agent_harness/prompts/skills三处;其中norecursedirs = tests/e2e .git ...(pytest.ini)明确把tests/e2e排除出默认收集,这正是原文档标注「tests/e2eexcluded by pytest configuration」的出处——端到端用例需要显式 opt-in,避免本地/CI 因缺少真实服务凭据而失败。

pytest.ini中还有几项对理解全量回归至关重要的全局配置:

  • import 模式--import-mode=importlib,解决两个测试文件同名(如test_enums)导致的 "import file mismatch";
  • 插件加载-p tests.harness_providers_plugin -p tests.colocated_skill_tests_plugin,前者为每个测试树装配工具/集成端口,后者保证位于core/agent_harness/prompts/skills下的技能测试不被重复执行;
  • 超时兜底timeout = 600(pytest.ini),把可能挂死的测试从「烧光整个 30 分钟 CI 任务」降级为「快速失败并输出全线程栈」,便于诊断死锁;
  • 标记定义integration(可能发 API 调用)、live_llm(需要真实 LLM 凭据与网络)、e2e(需要真实基础设施或外部凭据,离线 CI 中跳过)、live_install(命中真实安装源,opt-in 或 e2e 路径使用),见 pytest.ini。

目录布局:测试必须按领域归置

原文档的核心约定是:测试要放在领域目录下,而不是散落在tests/根目录

路径覆盖内容
tests/<domain>/产品模块的单元与集成测试(cli/tools/integrations/core/infrastructure/等)
tests/e2e/针对真实服务与基础设施的真实端到端场景,设计原则见 e2e/AGENTS.md
tests/github_ci/仓库卫生守卫(命名、导入边界、架构引用)
tests/conftest.py整棵测试树共享的 pytest fixtures

实际目录(tests/)与之一一对应:除conftest.py、两个插件文件和ci_sharding.py外,analytics/benchmarks/bootstrap/config/core/filestorage/infrastructure/integrations/interactive_shell/scheduler/tools/等均为领域目录,与源码顶层结构bootstrap/config/core/integrations/infrastructure/surfaces/一一镜像,方便「源码改动 → 就近找到测试」。

tests/github_ci/:仓库卫生守卫

这组测试守卫的是「仓库本身的健康」而非业务功能。以 tests/github_ci/test_naming_conventions.py 为例,它扫描README.mdpyproject.tomlMakefiletests/README.md.github/workflows/*.yml以及tests/e2e/下的所有.py文件,断言其中不再出现tests/test_case_test_case=test_case_test_orchestrator三个遗留 token——这是原文档「Legacy names」一节的落地守卫。同目录还包含 test_ci_sharding.py、test_external_code_boundaries.py、test_pr_pipeline_slo.py、test_pre_push_gate.py 等,分别守护分片、外部代码边界、PR 流水线 SLO 与 pre-push 闸门。

tests/conftest.py:整棵树共享的安全网

tests/conftest.py 的价值远超「加载 .env」:它通过若干 autouse fixture 把每个测试与开发者真实环境隔离开来:

  • _load_env读取项目根.envoverride=True),并统一关闭 Sentry(OPENSRE_SENTRY_DISABLED=1)与遥测(OPENSRE_NO_TELEMETRY=1),标记OPENSRE_INVESTIGATION_SOURCE=test
  • _restore_os_environ在每个测试后整体快照恢复os.environ——因为sync_provider_env等代码会os.environ.pop/update其他 provider 的 API key,泄漏会污染同 worker 上后续的live_llm测试;
  • _isolate_opensre_home_files把 wizard store(opensre.json)、LLM 认证元数据(llm-auth.json)、本地凭据与 memory 目录全部重定向到tmp_path,防止测试悄悄写坏开发者真实的~/.opensre(注释中记录了 #3721 回归案例);
  • _isolate_session_trace_store恢复进程级 session trace store,避免 xdist 下trace_spansidecar 泄漏进被断言的会话文件;
  • pytest_sessionfinish在「什么都没收集到」时强制返回NO_TESTS_COLLECTED,堵住 xdist 在-m把所有用例过滤掉时仍以 0 退出的漏洞。

E2E 目录与文件命名规则

原文档对端到端测试的命名有两条硬性规则:

  1. 目录格式tests/e2e/<scenario_name>/,其中<scenario_name>描述「系统 + 工作负载」,例如installquickstart
  2. 环境特定文件用显式文件名
    • test_local.py:本地环境;
    • test_<cloud>.py:云环境。

当前仓库的 tests/e2e/ 完全遵循这一约定,场景覆盖:deploy/(Docker 镜像构建与健康端点)、grafana_validation/(Grafana Cloud 查询)、incident_io/install/(真实安装器)、posthog/quickstart/tempo/trello/。环境维度的例子如 install/test_live_installers.py 与 install/test_live_installers_windows.py——前者用sys.platform == "win32"条件跳过(POSIX 安装器走install.sh,Windows 走install.ps1),后者单独覆盖 Windows 宿主。

e2e 场景的三个设计原则

e2e/AGENTS.md 明确了tests/e2e/的指导原则,可视为对命名规则的语义补充:

  1. 真实端到端,零 mock:必须打真实服务与真实基础设施(live installers、Grafana Cloud、PostHog、incident.io、Docker 构建),因为 mock 验证的是「人工载荷下的 agent」而非生产实际产生的东西;
  2. 关注点分离,业务逻辑纯净:测试驱动的工作负载代码必须与测试编排/可观测代码隔离,看起来像真实客户代码;
  3. 前置声明环境,缺凭据就响亮跳过:真实套件在开头声明所需凭据(参见 grafana_validation/env_requirements.py),缺失时带明确原因pytest.skip,让无密钥的 CI 保持绿色又不掩盖有密钥运行中的失败。

env_requirements.py展示了「门控 + 响亮跳过」的落地方式:require_grafana_cloud_env()收集GCLOUD_OTLP_ENDPOINTGCLOUD_OTLP_AUTH_HEADERGCLOUD_HOSTED_METRICS_ID/URLGCLOUD_HOSTED_LOGS_ID/URLGCLOUD_RW_API_KEY等 7 项,缺任一即以pytest.skip("Grafana Cloud telemetry not configured; missing env vars: ...")跳过;require_grafana_query_env()则按账号 id 归一化出GRAFANA_READ_TOKEN/GRAFANA_INSTANCE_URL(默认账号tracerbio)并逐项校验。

deploy/conftest.py是「环境门控」的另一个典型:RUN_DEPLOY_DOCKER_TESTS=1未设置或 Docker 不可用时直接 skip,启用后构建一个带随机 tag 的镜像,并在会话结束用docker image rm -f清理。

遥测命名规则:语义化 resource attributes

原文档规定:OTEL_RESOURCE_ATTRIBUTES的值必须使用语义目录名,禁止继续使用遗留的test_case_*;e2e 场景统一使用test_case=e2e_<scenario_name>

这条规则与命名守卫互相印证:tests/github_ci/test_naming_conventions.py 中的LEGACY_TOKENS = ("tests/test_case_", "test_case=test_case_", "test_orchestrator"),一旦在 README、pyproject、Makefile、工作流或 e2e 测试源码中出现即判定违规。也就是说,遥测命名不是「建议」,而是有 CI 测试强制的契约——新写的 e2e 场景必须形如test_case=e2e_installtest_case=e2e_quickstart,确保遥测面板上能按场景聚合出稳定的维度。

遗留命名与迁移

原文档明确指出:tests/下遗留的test_case_*路径命名已废弃,只使用tests/e2e/*。迁移路径即上文所述规则:任何历史遗留的场景(例如以test_orchestrator为文件名的编排测试)都应重命名为tests/e2e/<scenario_name>/下的环境特定文件,并把遥测标签切换为test_case=e2e_<scenario_name>。守卫测试的存在意味着迁移必须一次性完成,否则make test-full或 CI 会直接报红。

进阶:CI 分片与定时快照

虽然不在原文档正文,但 tests/ci_sharding.py 是理解tests/全量回归在 CI 中如何扩展的关键补充。它提供三个子命令:

  • select:按耗时快照(默认.github/ci/pytest-file-durations.json)把测试文件贪心分配到 N 个 shard 中「累计耗时最小」的一组,输出该 shard 的文件清单;
  • report:报告快照「新鲜度」(--max-age-days默认 14 天)与覆盖率(缺失文件占比--max-missing-percent默认 5%),超限时输出::warning供 CI 可视化;
  • merge:把各 worker 产出的定时片段(--ci-durations-output,见pytest_addoption)合并回总快照。

其核心算法assign_file_groups(tests/ci_sharding.py)对按耗时降序排列的文件做「放入当前最轻的组」的贪心分配,让每个 CI shard 的预估时长尽量均衡——这正是make test-full这类全量回归能保持稳定时长的底层机制。

小结

OpenSRE 的测试体系可以用「三条命令 + 一套约定 + 两类守卫」概括:make test-cov负责本地并行覆盖、make verify-integrations负责集成改动后的连通性校验、make test-full负责 CI 全量回归;测试必须按领域归置于 tests/ 下与源码镜像的目录;tests/github_ci/用真实测试强制命名与架构契约(包括test_case_*遗留命名的清除),tests/conftest.py则以 autouse fixtures 保证每个用例与开发者本机环境彻底隔离。掌握这些规则后,无论是为新增模块补测试、为集成改动跑校验,还是排查全量回归中的偶发失败,你都能快速定位对应的测试文件与运行入口。

【免费下载链接】opensreBuild your own AI SRE agents. The open source toolkit for the AI era.项目地址: https://gitcode.com/GitHub_Trending/op/opensre

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

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

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

立即咨询