这不是 pytest 本身的问题,而是 Python 模块搜索路径(sys.path)未包含自定义 site-packages 目录;pytest 继承 Python 默认行为,不自动扫描非标准路径,需通过 PYTHONPATH、.pth 文件或 conftest.py 动态添加路径解决。

直接说结论:这不是 pytest 本身的问题,而是 Python 模块搜索路径(sys.path)没把你的自定义 site-packages 目录包含进去——pytest 不会自动扫描非标准位置的包。
为什么 pytest 找不到你装在自定义 site-packages 里的模块
Python 启动时只加载几个固定路径到 sys.path,比如系统级 /usr/local/lib/python3.x/site-packages、虚拟环境下的 .venv/lib/python3.x/site-packages,以及当前工作目录。如果你手动把包解压/拷贝到另一个路径(例如 /opt/my-packages),哪怕它结构完全符合 site-packages 规范,Python 默认也不会看它一眼。
pytest 作为普通 Python 程序,完全继承这个行为。它不会额外扫描路径,也不会读取你本地的 pip config 或环境变量来推导“可能还有别的包在哪”。
- 常见现象:
ModuleNotFoundError: No module named 'mylib',但ls /opt/my-packages/mylib确实存在 - 验证方式:在 Python 交互式环境中执行
import sys; print('\n'.join(sys.path)),确认你的自定义路径是否在列表里 - 注意:即使你用
pip install -e /path/to/mylib,也只会在该路径下生成.pth文件并写入对应site-packages,不会影响其他路径
让 pytest 看到自定义 site-packages 的三种可靠方式
优先级从高到低,按实际场景选一种即可:
立即学习“Python免费学习笔记(深入)”;
-
改
PYTHONPATH(最轻量,适合 CI/临时调试):
运行 pytest 前导出环境变量:export PYTHONPATH="/opt/my-packages:$PYTHONPATH",然后执行python -m pytest。注意:必须用python -m pytest,而非直接调用pytest命令,否则 shell 的PYTHONPATH可能不生效 -
加 .pth 文件(一劳永逸,推荐用于开发机):
找到你当前 Python 实际使用的site-packages目录(用python -c "import site; print(site.getsitepackages())"查),在其中新建一个文本文件,比如叫my-custom-paths.pth,内容就一行:/opt/my-packages。Python 启动时会自动读取所有.pth文件并追加路径 -
在 conftest.py 里动态插入(仅限项目内测试,避免污染全局):
在项目根目录或tests/下的conftest.py开头加上:import sys<br>from pathlib import Path<br>custom_site = Path("/opt/my-packages")<br>if str(custom_site) not in sys.path:<br> sys.path.insert(0, str(custom_site))这样每次 pytest 加载测试前都会自动补上路径
容易被忽略的坑:.pth 文件和符号链接
如果你的自定义 site-packages 是个软链接(例如 /opt/my-packages → /home/user/dev/packages),要注意:.pth 文件里必须写**真实路径**,不能写符号链接路径。Python 解析 .pth 时不做路径展开,写错会导致静默失败。
另外,.pth 文件只对当前 Python 解释器生效。如果你有多个 Python 版本(比如 python3.11 和 python3.13),得分别在它们各自的 site-packages 里放一份 .pth 文件。
最后提醒一句:自定义 site-packages 虽然灵活,但绕过了 pip 的依赖管理和版本控制,长期维护容易出问题。真要复用代码,优先考虑 pip install -e 或发布到私有 PyPI。


















