首页/新闻资讯/正文详情

Read the Docs 开发者测试指南:Tox 测试套件、Pytest Marks 与 CI 流水线深度解析

发布时间:2026/9/26 10:23:22 来源:云帆数科 栏目:资讯中心
Read the Docs 开发者测试指南:Tox 测试套件、Pytest Marks 与 CI 流水线深度解析
后端文档【免费下载链接】readthedocs.orgThe source code that powers readthedocs.org项目地址https://gitcode.com/gh_mirrors/re/readthedocs.org点击查看免费下载导读Read the Docs 是一个面向文档托管场景的多实例 Django 项目代码库被部署为 Main仪表盘、Build构建、Serve/Proxito文档服务三个相互独立的实例。本文基于仓库官方开发文档系统讲解如何借助 Tox 运行核心测试、搜索测试与 Proxito 测试解释 pytest mark 如何按实例与依赖切分测试集并深入剖析.circleci/config.yml中的并行 CI 流水线、调试日志配置与 embed API 多 Sphinx 版本测试矩阵帮助贡献者快速定位、运行和调试与自身改动相关的测试。一、测试与代码风格贡献前的必备检查在向 Read the Docs 提交代码之前贡献者必须确保两件事同时通过测试套件补丁能通过完整的自动化测试代码风格代码通过 lintinglint 检查套件。整个测试与 linting 流程由Tox驱动。Tox 是唯一需要手动安装的依赖其余所有依赖Django、pytest、Elasticsearch 客户端、Sphinx 等都会由 Tox 自动安装到各环境专属的 virtualenv 路径中互不干扰。安装方式pip install tox如需加速 virtualenv 创建与依赖解析官方文档推荐同时安装tox-uv基于 uv 的 Tox 后端在 CI 与本地均可使用pip install tox tox-uv从仓库根目录的 tox.ini 可以看到Tox 声明了minversion2.9.0、skipsdist True不构建 sdist直接基于源码目录运行默认环境列表为py314, lint, docs。二、运行测试从单环境到全量2.1 按环境拆分测试测试套件被拆分到与 CI 流水线一一对应的多个 tox 环境中可按需只跑一个环境tox -e py314 # 核心测试不含 search、proxito、embed_api tox -e search # 搜索测试需要 Elasticsearch 实例 tox -e proxito # Proxito文档服务实例测试一次性运行全部测试套件tox -e py314,search,proxito2.2 运行测试子集使用 pytest 的-k参数按关键字筛选例如只跑名称含test_celery的用例tox -e py314 -- -k test_celery2.3 各环境的底层命令打开 tox.ini 可以看到各环境真实的 pytest 命令与 marker 过滤逻辑默认py314环境pytest ... -m not search and not proxito and not embed_api即只跑不带这三个 marker 的“主实例”用例search环境连跑两条命令——先用默认测试设置--dsreadthedocs.settings.test跑-m search and not proxito再用 Proxito 测试设置--dsreadthedocs.settings.proxito.test跑-m search and proxito因为部分用例同时带search与proxito两个 marker例如 test_proxied_api.py 中pytest.mark.proxito与pytest.mark.search叠用并启用--reuse-db复用数据库proxito环境使用--dsreadthedocs.settings.proxito.test跑-m proxito and not search。所有环境统一通过setenv注入DJANGO_SETTINGS_MODULEreadthedocs.settings.test作为默认并设置PYTHONPATH、LANGen_US.UTF-8、DJANGO_SETTINGS_SKIP_LOCALTrue等环境变量依赖统一来自-r requirements/testing.txt另附readthedocsext-theme的主题包。三、Tox 环境清单Tox 配置了以下环境可以针对单个环境限制测试范围环境用途py314核心测试——排除 search、proxito、embed API 三个 marker无需 Elasticsearchsearch搜索测试——需要 Elasticsearch 实例CI 中以 sidecar 容器方式提供proxitoProxito 测试——使用readthedocs.settings.proxito.test设置pre-commit通过 pre-commit 执行 linting 与格式化检查pre-commit run --all-files --show-diff-on-failuremigrations检查是否存在缺失的 Django migrationmanage.py makemigrations --check --dry-rundocs用 Sphinx 构建用户文档PROJECTuserdocs-dev用 Sphinx 构建开发者文档PROJECTdev此外 tox.ini 还定义了若干辅助环境eslint运行 JavaScript 代码检查器npm run lint需要先执行npm installcoverage生成覆盖率报告coverage html会把带注解的 HTML 报告输出到htmlcov/index.htmlvale用 Vale 检查docs/user/文档的写作风格问题deps中引入docutils以确保rst2html可用。四、调试日志失败后无需重跑即可定位测试失败报告默认只包含WARNING 及以上级别的日志记录这是刻意设计——避免失败信息被readthedocslogger 的大量DEBUG/INFO输出淹没。但这个阈值只影响终端报告完整的DEBUG输出始终会被写入logs/debug.logtail -n 200 logs/debug.log测试失败后直接查看该文件即可无需带额外参数重跑。4.1 debug.log 的底层实现日志文件句柄配置在 readthedocs/settings/base.pyLOGS_ROOT os.path.join(SITE_ROOT, logs)即仓库根目录下logs/base.pydebughandler 使用RotatingFileHandlerlevel 为DEBUG输出到logs/debug.log格式化器为 structlog 的key_value渲染键值对顺序为timestamp, level, event, loggerreadthedocslogger 的 level 固定为DEBUG且propagateFalse同时挂在debug与console两个 handler 上根 logger 的 level 为INFO子 logger 可通过自身 handler 过滤级别。4.2 在失败报告中内联 DEBUG 日志若希望在失败报告里直接看到 debug 记录可以在命令行覆盖日志级别tox -e py312 -- --log-levelDEBUG -k test_something注当前仓库的默认测试解释器为 Python 3.14命令中的环境名可按实际 Python 版本替换为py314。4.3 WARNING 阈值的两处设定测试报告的 WARNING 阈值设置在两处pytest.inilog_level WARNING控制 pytest 在失败时捕获并展示的日志级别同时addopts --strict-markers要求所有使用中的 marker 必须在markers中显式注册search、serve、proxito、embed_api、sphinx否则会报错readthedocs/settings/test.pyDjango 测试设置的console日志 handler 被固定为WARNING级别logging[handlers][console][level] WARNING并让disable_existing_loggers False允许 Sphinx 等工具创建自己的 loggerDEBUG 级别记录仍写入 debug.log handler 供事后分析。五、Pytest marks按部署实例切分测试5.1 三实例架构与测试策略Read the Docs 的代码库被部署为三个实例各自拥有独立的 Django settingsMain仪表盘dashboard所在实例Build负责执行文档构建Serve/Proxito负责对外提供文档页面服务。为了让测试尽可能贴近真实运行环境真实 settings项目采用pytest marks 独立 tox 环境的组合策略让每个实例的代码用其对应的 settings 模块来测试。5.2 当前注册的 marks在 pytest.ini 中注册的 marker 如下Marker含义search需要 Elasticsearch 的测试proxito针对 serve/proxito 实例的测试embed_api针对 embed API 的测试serve服务端相关测试sphinx涉及 Sphinx 构建的测试不带任何 marker 的测试默认属于Main 主实例。5.3 源码中的实际用法在 readthedocs/search/tests/test_api.py 等搜索测试中通过pytest.mark.search标记依赖 ES 的用例在 readthedocs/proxito/tests/base.py 中BaseDocServing(TestCase)基类整体标记pytest.mark.proxito其setUp会重建 build-media 存储、创建项目/子项目/翻译项目/别名项目及两个自定义 Domaindocs1.example.com、docs2.example.com供文档托管类测试复用embed API v3 测试位于 readthedocs/embed/v3/tests/其conftest.py提供remove_sphinx_build_outputfixture 清理构建产物。5.4 搜索测试的基础设施搜索测试通过 readthedocs/search/tests/conftest.py 中的 fixture 准备数据es_indexfixture 调用search_index --delete与search_index --create管理命令重建索引all_projectsfixture 会开启settings.ELASTICSEARCH_DSL_AUTOSYNC True批量创建 Project/Version/HTMLFile 并通过PageDocument().update()写入索引同时用mock_processed_json以get_processed_json的 mock 提供预处理的 HTML JSON 数据最后对项目列表shuffle以模拟真实搜索场景的无序性。对应地测试设置 readthedocs/settings/test.py 会把所有 ES 索引名加上test_前缀避免污染开发索引生产环境的 ES 配置hosts、project_index/page_index的分片与副本数、ES_TASK_CHUNK_SIZE 500见 readthedocs/settings/base.py。5.5 测试设置要点readthedocs/settings/test.py 中CommunityTestSettings还有若干对测试至关重要的配置使用 SQLite 作为默认与telemetry双数据库dev.db与telemetry.dev.db避免外部数据库依赖CELERY_TASK_ALWAYS_EAGER TrueCelery 任务同步执行便于断言任务结果缓存改用内存LocMemCacheAUTH_PASSWORD_VALIDATORS []关闭密码强度校验以加速测试PASSWORD_HASHERS优先使用快速哈希MD5PasswordHasher加速用户创建BUILD_TIME_LIMIT 600、BUILD_MEMORY_LIMIT 200m跳过 Docker 资源自动探测内置一个随机的 RSA 私钥与GITHUB_APP_WEBHOOK_SECRET secret用于 GitHub App 相关测试。Proxito 测试设置 readthedocs/settings/proxito/test.py 在继承上述测试设置的基础上将PUBLIC_DOMAIN覆盖为dev.readthedocs.io并把 build-media 存储替换为readthedocs.proxito.tests.storage.BuildMediaStorageTest。六、Continuous IntegrationCircle CI 并行流水线CI 在 Circle CI 上每次 push 都会运行测试被拆分为并行任务。工作流定义在 .circleci/config.yml整体分三个阶段6.1 三个阶段的任务编排Stage 1并行轻量checks、tests、tests-proxitoStage 2并行重量等待 Stage 1 通过后启动tests-search需要 ES在基础测试通过后才启动避免在坏构建上白启动 ES 容器、tests-embedapi覆盖 6 个 Sphinx 版本Stage 3coverage-report汇总三个测试任务的覆盖率文件并上传 Codecov。tests-search依赖tests与tests-proxito通过tests-embedapi同样依赖二者。配置文件头部注释明确给出了 marker 覆盖矩阵——每个测试只在一个任务中执行CI 任务pytest 过滤tests-m not search and not proxito and not embed_apitests-search-m search and not proxito-m search and proxitoproxito settingstests-proxito-m proxito and not searchtests-embedapi-m embed_api多 Sphinx 版本通过 tox.embedapi.ini6.2 基础设施与缓存策略各任务基于cimg/python:3.14Docker 镜像tests-search额外挂载docker.elastic.co/elasticsearch/elasticsearch:9.3.1作为 sidecarsingle-node 模式ES_JAVA_OPTS-Xms750m -Xmx750m缓存策略setup-checkout命令把requirements/*.txt拼接并附上readthedocs/ext-theme的 HEAD commit 生成校验和作为缓存 keyrestore_cache/save_cache使用精确 checksum keykey 不可变requirements 变化即触发全新安装并写入新缓存缓存~/.local/lib与.tox路径需要全局失效时提升 key 中的v2版本号skip-if-docs-only命令对比origin/main的 merge base 计算改动文件若全部落在docs/下则通过circleci-agent step halt跳过测试仅对面向 main 的 PR 生效每个测试任务运行tox后将覆盖率文件复制为唯一名称如.coverage.tests因为 tox 不会把COVERAGE_FILE传递进测试环境coverage-report任务用coverage combine .coverage.*合并后生成 XML 报告并上传 Codecov。6.3 checks 任务checks任务缓存common/pre-commit-config.yaml、Python 版本与 requirements 拼接的 key依次运行tox -e pre-commitlinting与tox -e migrationsmigration 检查并缓存~/.cache/pre-commit。6.4 embed API 的 Sphinx 版本矩阵tox.embedapi.ini 定义了 embed API 的多版本测试矩阵envlist sphinx-{45,53,62,74,82,latest}即 Sphinx 4.5、5.3、6.2、7.4、8.2 与最新版。该文件有几个值得注意的细节仅兼容 tox 3文件头注明“Currently tox 3 is required, breaks with tox 4”requires tox4因此 CI 的tests-embedapi任务单独安装tox4并显式检查tox --version且无法使用 tox-uv依赖注入通过自定义install_command先从requirements/testing.txt中过滤掉 Sphinxgrep -v Sphinx生成临时 requirements再安装各环境deps中指定的 Sphinx 版本如Sphinx~4.5.0、Sphinx~6.2.0 sphinxcontrib-bibtex~2.0确保测试环境与生产依赖隔离运行命令为pytest -m embed_api --nomigrationssetenv固定VIRTUALENV_SETUPTOOLS75.8.0。七、本地工作流建议综合官方文档与仓库配置推荐贡献者的本地测试工作流如下安装 Tox可搭配 tox-uv 加速pip install tox tox-uv针对改动范围选择最小测试集主实例代码跑tox -e py314 -- -k 关键词Proxito 相关改动跑tox -e proxito涉及搜索的改动需先启动 Elasticsearch 再跑tox -e search提交前运行 lint 与 migration 检查tox -e pre-commit与tox -e migrations测试失败时优先查看logs/debug.log的完整 DEBUG 输出必要时用--log-levelDEBUG内联调试如需验证文档与 embed API可分别运行tox -e docs、tox -e docs-dev以及tox -c tox.embedapi.ini。八、延伸阅读tox.iniTox 环境与 pytest 命令的完整定义pytest.inipytest 配置、log_level 与 marker 注册readthedocs/settings/test.py测试专用 Django settingsreadthedocs/settings/proxito/test.pyProxito 测试 settingsreadthedocs/settings/base.py日志 handler 与 Elasticsearch 基础配置.circleci/config.ymlCI 流水线与缓存策略tox.embedapi.iniembed API 多 Sphinx 版本矩阵readthedocs/conftest.py全局 fixtureapi_client、自动清理缓存的clear_cachereadthedocs/search/tests/conftest.py搜索测试的 ES 索引与数据 fixturereadthedocs/proxito/tests/base.pyProxito 测试基类与 fixture 数据赞分享后端文档【免费下载链接】readthedocs.orgThe source code that powers readthedocs.org项目地址https://gitcode.com/gh_mirrors/re/readthedocs.org点击查看免费下载相关推荐nats.go 开发与测试实战指南双模块构建、ntf-server 测试架构与 CI 流水线深度解析nats.go 开发与测试实战指南双模块构建、ntf server 测试架构与 CI 流水线深度解析 本指南以仓库根目录的 CLAUDE.md https:/消息队列通信OpenMed 测试套件深度指南基于 pytest 的离线优先单元测试与集成测试实践OpenMed 测试套件深度指南基于 pytest 的离线优先单元测试与集成测试实践 本指南以 OpenMed 仓库的 tests/README.md htt人工智能NLP医疗健康数据脱敏本地部署大模型AI 应用MCP 服务联邦学习Nomad 单元测试编写规范与 CI 流水线深度解析Nomad 单元测试编写规范与 CI 流水线深度解析 导读 本文基于 contributing/testing.md https://link.gitcode.任务调度云原生运维后端上一篇MoeKoe Music终极体验指南5个理由让你告别传统音乐播放器下一篇GetQzonehistory5分钟找回你消失的QQ空间记忆让青春永不褪色创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Vue2与Vue3核心区别全解析:从响应式原理到迁移实战
Vue2与Vue3核心区别全解析:从响应式原理到迁移实战

1. 从一次真实迁移说起:为什么我要把 Vue2 和 Vue3 的区别彻底捋一遍去年接手了一个后台管理项目,代码是 2020 年用 Vue2 Element UI 写的,业务逻辑堆了三年,组件两百多个。产品那边要求加一套数据看板,需要用到组合式… · 2026/9/26 10:23:16

2026 AI供应链安全深度剖析:从模型投毒到MCP后门,用TaoToken统一Key通道构建AI-BOM与情报联动体系
2026 AI供应链安全深度剖析:从模型投毒到MCP后门,用TaoToken统一Key通道构建AI-BOM与情报联动体系

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:23:16

Swift IDE 有哪些?用 TaoToken 统一 Key 打通 Xcode 与 VSCode 配置
Swift IDE 有哪些?用 TaoToken 统一 Key 打通 Xcode 与 VSCode 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:23:16

Claude Code模板化实战:六段式配方让AI编程助手从裸奔到高效协作
Claude Code模板化实战:六段式配方让AI编程助手从裸奔到高效协作

很多人拿到Claude Code之后的第一反应是直接在终端里敲需求、看它跑,跑完再把结果贴回对话里继续聊。这种“裸奔式”用法不是不行,但如果你认真用了两周以上就会发现:同样的错误反复犯、项目规范和上下文每次都要重新叮嘱、一个稍复杂的任务要… · 2026/9/26 10:59:01

【DeepAgents 从入门到精通】核心架构深入:Middleware 与 AgentMiddleware 配置骨架
【DeepAgents 从入门到精通】核心架构深入:Middleware 与 AgentMiddleware 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:58:54

2K图像生成加速:LoRA与频谱注意力优化实践
2K图像生成加速:LoRA与频谱注意力优化实践

Qwen Image 2.1出来的时候,我第一反应是终于有人把2K出图当成默认需求来做了,而不是让用户先出一张小图再自行放大。但真正跑起来之后才发现,原生2K分辨率意味着注意力计算的复杂度几乎是指数级往上走,等图时间轻松突破一分钟。等… · 2026/9/26 10:58:47

从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略(TaoToken 统一 Key 配置篇)
从 LangChain 到 OpenClaw:AI Agent 工程化的五层拼图与生产落地全攻略(TaoToken 统一 Key 配置篇)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:58:41

Codex App 接上微信后,我把 Bug 排查搬进了厕所:TaoToken 统一 Key 配置实战
Codex App 接上微信后,我把 Bug 排查搬进了厕所:TaoToken 统一 Key 配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:58:41

OpenClaw进阶实战(二十九):企业微信自建应用接入TaoToken——会话存档与敏感词监控配置落地
OpenClaw进阶实战(二十九):企业微信自建应用接入TaoToken——会话存档与敏感词监控配置落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 10:58:41

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码