使用 pytest 的 Python 项目的正确文件夹结构是什么?
What is the correct folder structure to use for a Python project using pytest?
我尝试使用文件夹结构组织我的 Python 项目。当我需要进行测试时,我使用类似下面的东西。
.
|-- src
| |-- b.py
| `-- main.py
`-- tests
`-- test_main.py
这种方法只有一个大问题。 Pytest 不会 运行 如果 main.py
正在导入 b.py
.
到目前为止,我已尝试将空的 __init__.py
文件单独或放在一起 src
和 tests
文件夹中,但其中任何一个似乎都有效。
在我看来,这是一个非常标准的项目,但我一直无法在网上找到解决方案。我应该使用不同的文件夹结构吗?有什么推荐的方法可以将 pytest 用于此类项目吗?
这是文件的内容:
# b.py
def triplicate(x):
return x * 3
# main.py
from b import triplicate
def duplicate(x):
return x * 2
# test_main.py
from src.main import duplicate
def test_duplicate():
assert duplicate(2) == 4
这是我在 运行ning pytest:
时得到的错误
==================================================================================================== ERRORS ====================================================================================================
_____________________________________________________________________________________ ERROR collecting tests/test_main.py ______________________________________________________________________________________
ImportError while importing test module 'C:\Users\edwar\test_pytest\tests\test_main.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
c:\python39\lib\importlib\__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests\test_main.py:1: in <module>
from src.main import duplicate
src\main.py:1: in <module>
from b import triplicate
E ModuleNotFoundError: No module named 'b'
=========================================================================================== short test summary info ============================================================================================
ERROR tests/test_main.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=============================================================================================== 1 error in 0.15s ===============================================================================================
您可以将源文件放在根目录下,并调整导入路径:
main.py
# main.py
from Whosebug.b import triplicate
def duplicate(x):
return x * 2
b.py
# b.py
def triplicate(x):
return x * 3
test_main.py
# test_main.py
from Whosebug.main import duplicate
def test_duplicate():
assert duplicate(2) == 4
然后从根目录运行pytest .
Whosebug
:
collected 1 item
tests\test_main.py . [100%]
====================================================================================== 1 passed in 0.03s =======================================================================================
或者,如果您希望保留 src
文件夹,您的导入将是这样的:
from Whosebug.src.b import triplicate
Python 使用 'environment variable' PYTHONPATH
来寻找从中导入代码的来源。默认情况下,你执行python程序的目录是自动包含的,但是你想在测试时包含这样的东西:
PYTHONPATH=$PYTHONPATH,../src python test_main.py
这是您从源目录执行测试的情况。像 IntelliJ (PyCharm) 这样的工具可以让您将其作为一个值添加到您的测试调用中。或者,您可以使用 export PYTHONPATH=...
。 (请注意,这是针对 *nix 环境的,您在 windows 上的使用情况可能会有所不同。)
结果是 PYTHONPATH
中的每个目录都将被加载,并且 Python 将尝试将其用作您尝试导入的模块的 'root'。您的基本目录结构是最惯用的。
- 有关正确配置
PYTHONPATH
的更多信息,请参阅 this answer。
- 有关
PYTHONPATH
如何修改和使用的更多信息,请参见 this doc 'under the hood'。
- 有关在 运行
pytest
测试时包含 src
目录的选项,请参阅 this answer。
- 请参阅 this blog post 关于使用
autoenv
(一个 Python 库)启用 .env
文件的使用来为您管理此文件(至少在 virtualenv
设置 - 通常是个好主意)。
setup.py
也是包含许多模块的惯用方法,并且可以为您正在处理的情况提供更方便的路径。
我尝试使用文件夹结构组织我的 Python 项目。当我需要进行测试时,我使用类似下面的东西。
.
|-- src
| |-- b.py
| `-- main.py
`-- tests
`-- test_main.py
这种方法只有一个大问题。 Pytest 不会 运行 如果 main.py
正在导入 b.py
.
到目前为止,我已尝试将空的 __init__.py
文件单独或放在一起 src
和 tests
文件夹中,但其中任何一个似乎都有效。
在我看来,这是一个非常标准的项目,但我一直无法在网上找到解决方案。我应该使用不同的文件夹结构吗?有什么推荐的方法可以将 pytest 用于此类项目吗?
这是文件的内容:
# b.py
def triplicate(x):
return x * 3
# main.py
from b import triplicate
def duplicate(x):
return x * 2
# test_main.py
from src.main import duplicate
def test_duplicate():
assert duplicate(2) == 4
这是我在 运行ning pytest:
时得到的错误==================================================================================================== ERRORS ====================================================================================================
_____________________________________________________________________________________ ERROR collecting tests/test_main.py ______________________________________________________________________________________
ImportError while importing test module 'C:\Users\edwar\test_pytest\tests\test_main.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
c:\python39\lib\importlib\__init__.py:127: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests\test_main.py:1: in <module>
from src.main import duplicate
src\main.py:1: in <module>
from b import triplicate
E ModuleNotFoundError: No module named 'b'
=========================================================================================== short test summary info ============================================================================================
ERROR tests/test_main.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=============================================================================================== 1 error in 0.15s ===============================================================================================
您可以将源文件放在根目录下,并调整导入路径:
main.py
# main.py
from Whosebug.b import triplicate
def duplicate(x):
return x * 2
b.py
# b.py
def triplicate(x):
return x * 3
test_main.py
# test_main.py
from Whosebug.main import duplicate
def test_duplicate():
assert duplicate(2) == 4
然后从根目录运行pytest .
Whosebug
:
collected 1 item
tests\test_main.py . [100%]
====================================================================================== 1 passed in 0.03s =======================================================================================
或者,如果您希望保留 src
文件夹,您的导入将是这样的:
from Whosebug.src.b import triplicate
Python 使用 'environment variable' PYTHONPATH
来寻找从中导入代码的来源。默认情况下,你执行python程序的目录是自动包含的,但是你想在测试时包含这样的东西:
PYTHONPATH=$PYTHONPATH,../src python test_main.py
这是您从源目录执行测试的情况。像 IntelliJ (PyCharm) 这样的工具可以让您将其作为一个值添加到您的测试调用中。或者,您可以使用 export PYTHONPATH=...
。 (请注意,这是针对 *nix 环境的,您在 windows 上的使用情况可能会有所不同。)
结果是 PYTHONPATH
中的每个目录都将被加载,并且 Python 将尝试将其用作您尝试导入的模块的 'root'。您的基本目录结构是最惯用的。
- 有关正确配置
PYTHONPATH
的更多信息,请参阅 this answer。 - 有关
PYTHONPATH
如何修改和使用的更多信息,请参见 this doc 'under the hood'。 - 有关在 运行
pytest
测试时包含src
目录的选项,请参阅 this answer。 - 请参阅 this blog post 关于使用
autoenv
(一个 Python 库)启用.env
文件的使用来为您管理此文件(至少在virtualenv
设置 - 通常是个好主意)。 setup.py
也是包含许多模块的惯用方法,并且可以为您正在处理的情况提供更方便的路径。