python - 将 pytest 与 src 层一起使用

标签 python pytest python-packaging

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

会将liblib2 模块添加到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 developpip install --editable .),同时你还在开发它。这样,您的包 my_package 就会正确地集成到 Python 的站点包结构中,而无需摆弄 PYTHONPATH

关于python - 将 pytest 与 src 层一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50155464/

相关文章:

python - 将一个图像粘贴到另一个图像上

python - QStyledItemDelegate 水平截断文本并且不添加水平滚动条

python - 如何将现有的 git 存储库(没有 eclipse 项目)添加到 eclipse 中?

nose - pytest 的规范插件?

pytest - 使用 pytest 运行相关测试

python - 如何在 django TestCase 中使用 pytest 固定装置

python - 将别名添加到 setup() 内的 console_scripts

python - 我的 RST 自述文件在 PyPi 上的格式不正确

python - 将 numba 函数拆分为项目中的单独模块以进行打包

python - 无法安装reportlab mac OS X 10.9.2 + python2.7