如何在任意目录运行pytest时正确导入项目模块?
解决pytest跨目录运行时的模块导入问题
问题场景
我正在给项目配置pytest,目录结构是这样的:
├── README.md ├── my_code │ ├── __init__.py │ ├── __main__.py │ └── target_file.py └── tests ├── __init__.py └── test_one.py
现在在test_one.py里用这段代码导入模块:
import sys import os sys.path.insert(0, "my_code")
在项目根目录跑pytest没问题,但进到tests目录里跑就报错,说找不到my_code模块——原因很明显,这种导入方式依赖当前工作目录,在tests目录下Python会去tests/my_code找,那肯定找不到啊。想问问怎么改导入方式,才能不管在哪个目录运行pytest,测试都能正常跑?
几个实用的解决办法
1. 基于测试文件位置动态定位项目根目录
这是最直接的修改方式,不用改项目结构,也不用额外配置。直接在测试文件里根据当前文件的位置,算出项目根目录,把它加到Python的搜索路径里:
import sys from pathlib import Path # 先拿到当前测试文件的路径,往上跳两级就是项目根目录(tests -> 根目录) project_root = Path(__file__).parent.parent sys.path.append(str(project_root)) # 现在就能正常导入了 from my_code.target_file import your_function_or_class
用pathlib比os.path更简洁,还能跨Windows、Linux、Mac这些不同系统,不会出路径分隔符的问题。
2. 把项目装成可编辑包(推荐长期项目用)
这是Python项目的标准做法,一劳永逸。步骤很简单:
- 首先在项目根目录创建一个
pyproject.toml文件,内容大概是这样:[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "my_code" version = "0.1.0" - 然后在项目根目录跑这条命令:
这个命令会把pip install -e .my_code安装成"可编辑"的包,相当于把你的项目目录链接到Python的site-packages里。之后不管你在哪个目录,都能直接像导入第三方包一样导入:
这种方式不仅解决了pytest的导入问题,像mypy、flake8这些代码检查工具也能正确识别你的模块,非常适合长期维护的项目。from my_code.target_file import *
3. 运行pytest时指定pythonpath参数
如果只是临时测试,不想改代码也不想装包,可以在跑pytest的时候加个--pythonpath参数,指定项目根目录:
- 在项目根目录跑:
pytest - 在tests目录跑:
这种方式比较灵活,但每次跑都要加参数,适合临时调试用。pytest --pythonpath ../
内容的提问来源于stack exchange,提问作者girbic
相关产品推荐
相关产品推荐

