如何解决Python项目与pytest中的导入兼容性问题
如何解决Python项目与pytest中的导入兼容性问题
问题描述
我完全按照pytest的最佳实践搭建了项目,采用了「测试代码与应用代码分离」的结构,项目布局如下:
. ├── pyproject.toml ├── src │ └── basic_package │ ├── bar.py │ ├── __init__.py │ └── main.py └── tests └── test_app.py
在main.py里我这样导入bar.py的内容:
from bar import baz def main() -> str: return baz()
而test_app.py里的导入是:
from basic_package.main import main def test_foo(): assert main() == 'qux'
直接运行项目时一切正常,但执行pytest时却报错:
ModuleNotFoundError: No module named 'bar'
如果把main.py里的导入改成相对导入:
from .bar import baz
pytest能正常运行了,但直接运行主程序又会报同样的模块找不到错误。我是从项目根目录运行pytest的,请问该怎么解决这个问题?
解决方案
这种问题本质是Python在不同运行场景下的模块查找路径差异导致的,下面给你几个实用的解决办法:
1. 使用绝对导入(最推荐)
把main.py里的导入语句改成基于包名的绝对导入,这样不管是运行主程序还是pytest,都能精准定位到模块:
from basic_package.bar import baz def main() -> str: return baz()
绝对导入是Python官方推荐的导入方式,能避免很多路径相关的坑,而且兼容性最好。
2. 配置pytest的Python路径
如果你不想修改代码,可以在pyproject.toml中添加pytest的配置,让它自动把源码目录加入模块查找路径:
[tool.pytest.ini_options] pythonpath = ["src"]
配置完成后,从项目根目录运行pytest时,它会自动识别src下的basic_package,这样原来的from bar import baz就能正常工作,同时主程序的运行也不受影响。
3. 将项目安装为可编辑模式
用pip把你的项目安装成可编辑模式,这样Python会把你的源码目录加入全局模块查找路径,无论在哪里运行都能正确导入:
pip install -e .
这个方法适合需要频繁修改代码的开发场景,安装后不管是运行主程序还是执行测试,都不需要调整导入语句。
备注:内容来源于stack exchange,提问作者Psionman
相关产品推荐
相关产品推荐

