pytest导入相邻目录模块报ModuleNotFoundError如何解决
Python测试文件导入src目录下模块报错解决
你的现有项目目录结构:
├── src │ └── app.py ├── tests │ └── unit_tests │ ├── __init__.py │ ├── conftest.py │ └── test_app.py
之前尝试的导入方式失效原因
- 往
sys.path追加'../../src/app.py'的写法错误:Python模块搜索路径只识别目录,不识别单个.py文件;同时相对路径是基于你执行命令时的工作目录解析,和test_app.py本身的存储位置无关,只要你切换执行命令的目录,路径解析结果就会出错。 from ...src.app import function的相对导入写法不符合规则:多前缀点号的相对导入只能在同一个包内部使用,要求导入方和被导入方都属于带__init__.py的包层级,你的src目录目前没有包标识文件,且和tests目录平级、不属于同一个包范围,这种写法本身就无法生效。from app import function直接导入找不到模块:这个写法要求app.py所在的src目录已经被加入Python的模块搜索路径,默认配置下搜索路径不包含src目录,自然触发ModuleNotFoundError。
可用解决方法
方法1:pytest配置方案(最推荐,写测试零额外代码)
pytest原生支持自定义模块搜索路径,你只需要在项目根目录(即src、tests所在的最外层目录)新建pytest.ini文件,写入以下配置:
[pytest] pythonpath = src testpaths = tests
配置完成后,始终在项目根目录执行pytest命令运行测试即可,test_app.py里直接写from app import 你需要引入的函数/类就能正常导入,不需要手动修改sys.path,也不需要调整目录结构。
方法2:测试文件内追加绝对路径(适合不想加额外配置的场景)
不要写相对路径,通过当前文件的位置拼接出src的绝对路径,加到sys.path里即可。把下面的代码写在test_app.py的最顶部,所有业务导入语句之前:
import sys from pathlib import Path # 路径层级计算:当前文件 -> unit_tests目录 -> tests目录 -> 项目根目录 -> 拼接src路径 sys.path.append(str(Path(__file__).parent.parent.parent / "src")) # 后续直接正常导入即可 from app import function
这种写法不依赖执行命令时的工作目录,不管你从哪个位置跑测试,路径解析都是正确的。
方法3:正规包安装方案(适合长期维护的项目)
给src目录添加空的__init__.py文件把它标记为Python包,然后在项目根目录新建pyproject.toml配置文件,写入最小化打包配置:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "your-project" version = "0.0.1" packages = ["src"]
写完之后在项目根目录执行pip install -e .做可编辑模式安装,安装完成后不管是测试文件还是其他业务脚本,在任意位置都可以直接通过from app import xxx导入src下的模块,不需要额外改路径。
内容的提问来源于stack exchange,提问作者DSteman
相关产品推荐
相关产品推荐

