pytest默认递归扫描当前目录下所有.py文件,若未限定范围,会误入venv/、site-packages/等第三方库目录,可能因语法错误或importerror中断测试;最稳妥方案是通过pytest.ini的testpaths明确指定仅扫描tests/和src/等自有目录。

为什么pytest会扫描第三方库目录?
默认情况下,pytest 会递归扫描当前工作目录下的所有 .py 文件,只要路径没被显式排除,它就可能尝试导入或收集那些不属于你项目的第三方包(比如 venv/、.venv/、site-packages/ 下的文件)。这通常不会报错,但一旦某个第三方库里有语法错误、不兼容的 pytest fixture、或触发了 ImportError(例如依赖未安装),就会中断测试运行,甚至导致 pytest 直接崩溃。
用 pytest.ini 的 testpaths 和 python_files 限定范围
最稳妥的方式不是“忽略”,而是“只看该看的”。pytest.ini 中明确指定测试入口点,比靠排除更可靠:
[tool:pytest] testpaths = tests src python_files = test_*.py *_test.py python_classes = Test* python_functions = test_*
这样 pytest 就只在 tests/ 和 src/ 下找测试文件,根本不会进入 venv/ 或 site-packages/。注意:testpaths 是相对路径,必须存在且可读;如果项目结构是 src/mylib/ + tests/,就别写成 ./tests —— pytest 不解析 . 前缀。
用 --ignore 命令行参数临时跳过目录
适合调试或 CI 中快速绕过某个污染源,比如发现 venv/ 下某个坏包总触发 ImportError:
pytest --ignore=venv/pytest --ignore=.venv/ --ignore=env/- 多个
--ignore可叠加,但每个都必须是相对于当前工作目录的路径 - 不能写成
--ignore=venv/lib/python3.11/site-packages/—— 这路径太深,pytest在收集阶段还没走到那么细,忽略无效 - 这个参数不会影响
conftest.py的加载位置,只跳过文件发现
用 pyproject.toml 的 filterwarnings 配合 addopts 治标治本
有些第三方库会在导入时抛出 DeprecationWarning 或 UserWarning,虽然不中断执行,但刷屏干扰判断。这时真正要处理的不是“目录”,而是“警告来源”:
[tool.pytest.ini_options] addopts = [ "--ignore=venv/", "--ignore=.venv/", "--ignore=dist/", ] filterwarnings = [ "ignore:.*Deprecated.*:DeprecationWarning:requests", "ignore:.*unclosed.*:ResourceWarning:urllib3", ]
关键点:
-
filterwarnings的格式是"action:message:category:module:lineno",模块名要写对(比如requests,不是requests.packages.urllib3) -
addopts中的--ignore优先级高于命令行传入的其他参数 - 如果用了
pytest-xdist,--ignore依然生效,但警告过滤需确保每个 worker 都加载了配置
真正麻烦的是那些动态生成测试函数、又偷偷 import 第三方模块的插件(比如 pytest-asyncio 遇到坏的 aiohttp 版本),这时候光 ignore 目录没用,得查具体哪个 conftest.py 或 plugin 引入了问题模块 —— 那就不是配置能解决的了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











