pytest只识别[tool.pytest.ini_options]表名,写成[tool.pytest]等任意变体均静默忽略;pyproject.toml未被加载还可能因文件位置错误、toml语法非法或更高优先级配置文件(如pytest.ini)存在。

pytest 无法加载 pyproject.toml 配置,不是配置没写,而是它根本没被识别为 pytest 配置源——最常见原因是表名写错或结构不合法。
pyproject.toml 中 pytest 配置必须放在 [tool.pytest.ini_options]
pytest 当前(2026 年)只认 [tool.pytest.ini_options] 这个确切的 TOML 表名。
哪怕你写成 [tool.pytest]、[pytest] 或 [tool.pytest.options],它都会静默忽略,不报错也不生效。
-
✅ 正确写法:
[tool.pytest.ini_options] minversion = "6.0" addopts = ["-ra", "-q"] testpaths = ["tests", "integration"]
-
❌ 常见错误写法:
-
[tool.pytest](缺少ini_options) -
[pytest](缺tool.前缀) -
[tool.pytest.config](名字任意改就失效)
-
这个限制源于 pytest 的兼容层设计:它把 TOML 当作 .ini 的映射,所以必须走 ini_options 这条通道,而不是直接读 [tool.pytest]。
pyproject.toml 文件本身不被 pytest 读取的几种情况
即使表名对了,pytest 也可能跳过该文件:
- 当前工作目录下没有
pyproject.toml(比如你在tests/目录里直接运行pytest,但文件在上层) - 文件语法错误(例如 key 没加引号、数组缺逗号),导致 TOML 解析失败,
pytest会静默跳过整个文件 - 项目根目录存在
pytest.ini或setup.cfg,且它们的优先级更高(pytest.ini>pyproject.toml>setup.cfg),此时pyproject.toml配置不会被合并,而是被完全忽略
验证是否被加载:加一个明显错误的配置项,比如 unknown_option = true,如果运行 pytest --help 不报错,说明配置根本没进 pytest;如果报错“unrecognized arguments”,才说明它被读进去了。
addopts 参数值必须是数组或字符串,不能混用
addopts 在 [tool.pytest.ini_options] 中支持两种格式,但容易踩坑:
-
✅ 字符串(空格分隔,适用于简单场景):
addopts = "-ra -q --tb=short"
-
✅ 字符串数组(推荐,避免 shell 解析歧义):
addopts = ["-ra", "-q", "--tb=short"]
-
❌ 错误写法(混合或带换行):
-
addopts = "-ra\n-q"(TOML 不支持裸换行) -
addopts = ["-ra -q"](这会被当做一个参数传给 pytest,等价于pytest "-ra -q",而非pytest -ra -q)
-
如果你发现 --tb=short 没生效,或者 -q 被忽略,先检查 addopts 是不是被当成了单个字符串。
testpaths 不影响导入路径,只控制扫描范围
很多人以为设了 testpaths = ["tests"] 就能让 pytest 自动把 src/ 加进 Python path——其实不会。
-
testpaths只告诉 pytest “去哪些目录里找test_<em>.py</em>或_test.py文件” - 模块导入失败(
ModuleNotFoundError)仍需靠python -m pytest、src目录结构、或--import-mode=importlib解决
比如项目结构是:
project/
├── pyproject.toml
├── src/
│ └── mypkg/
│ ├── __init__.py
│ └── core.py
└── tests/
└── test_core.py
即使 testpaths = ["tests"],test_core.py 里写 from mypkg.core import foo 依然会失败,除非你:
- 在根目录运行
python -m pytest tests/(触发 PEP 517 导入模式) - 或在
pyproject.toml里加[[tool.pytest.ini_options]]→ 不行,得用addopts = ["--import-mode=importlib"]
真正容易被忽略的是:pytest 对 pyproject.toml 的解析非常“脆弱”——一个空格、一个引号、一个拼错的表名,都会让它彻底沉默,而你得不到任何提示。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











