pytest recommends包括一个额外的目录来分隔项目中的源代码:
my_package
├── src # <-- no __init__.py on this layer
│ └── my_package
│ ├── __init__.py
│ └── util_module
│ ├── __init__.py
│ └── utils.py
└── tests
├── __init__.py
└── test_util_module
├── __init__.py
└── test_utils.py
可悲的是,他们什么也没说[1]关于测试代码中的导入在这种情况下应该如何工作,这在我的 IDE 中工作得很好 this naive example [2],但会导致 pytest 出现以下错误:
~/my_package$ pytest
====================== test session starts ======================
platform linux -- Python 3.6.4, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/user/workspace/my_package, inifile:
collected 0 items / 1 errors
============================ ERRORS =============================
___ ERROR collecting tests/test_util_module/test_utils.py ___
ImportError while importing test module '/home/user/workspace/my_package/tests/test_util_module/test_utils.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_util_module/test_utils.py:1: in <module>
from test.test_module.some_file import starify
E ModuleNotFoundError: No module named 'my_package.util_module'
!!!! Interrupted: 1 errors during collection !!!!!
我可以通过将测试导入更改为来解决这个问题
from src.my_package.util_module.utils import starify
但是我的 IDE 提示 src
部分是多余的,所以我想把它去掉。
[1]:不再是这样了。从版本 3.7.3 开始,pytest 推荐可编辑安装,该安装也出现在@hoefling 在其 good practices 顶部的回答中。 .
[2]:设置为virtualenv env -p python3.6;源环境/bin/激活; pip 安装 pytest
最佳答案
pytest>=7
的推荐方法:使用 pythonpath
设置
最近,pytest
添加了一个新的核心插件,支持通过 pythonpath
configuration value 修改 sys.path
.因此,现在的解决方案要简单得多,不再需要任何解决方法:
pyproject.toml
示例:
[tool.pytest.ini_options]
pythonpath = [
"src"
]
pytest.ini
示例:
[pytest]
pythonpath = src
路径条目是相对于 rootdir 计算的,因此 src
条目将 path/to/project/src
目录添加到 sys.path
在这种情况下。
也允许多个路径条目:对于布局
repo/
├── src/
| └── lib.py
├── src2/
| └── lib2.py
└── tests
└── test_lib.py
配置
[tool.pytest.ini_options]
pythonpath = [
"src", "src2",
]
或
[pytest]
pythonpath = src src2
会将lib
和lib2
模块添加到sys.path
,所以
import lib
import lib2
都可以。
原始答案
调整 PYTHONPATH
(如评论中所建议)是解决导入问题的一种可能性。另一个是在 src
目录中添加一个空的 conftest.py
文件:
$ touch src/conftest.py
和pytest
会将src
添加到sys.path
。这是欺骗 pytest
将代码库添加到 sys.path
的简单方法。
但是,当您打算构建一个发行版时,通常会选择 src
布局,例如提供一个 setup.py
(在本例中)明确指定根包目录:
from setuptools import find_packages, setup
setup(
...
package_dir={'': 'src'},
packages=find_packages(where='src'),
...
)
并在开发模式下安装包(通过 python setup.py develop
或 pip install --editable .
),同时你还在开发它。这样,您的包 my_package
就会正确地集成到 Python 的站点包结构中,而无需摆弄 PYTHONPATH
。
关于python - 将 pytest 与 src 层一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50155464/