通常的 pytest 工作流程 - 无法 运行 在文件中进行测试
Usual pytest workflow - can't run tests in a file
我正在尝试设置一个项目(Python 3.4.4,pytest 3.3.1)以使用 pytest,但 pytest 无法 运行 在文件或目录中进行测试。我想我用错了 pytest,但不是正确的工作流程。
我试过的
根据 "Good Integration Practices" 中的建议,并且由于个人偏好将源代码和测试放在不同的文件夹中,我将我的项目设置如下:
parent_directory/
setup.py
src/
project_name/
__init__.py # empty
utils.py
tests/
__init__.py # empty
project_name/
__init__.py # empty
test_utils.py # has `import project_name.utils.py`
有了这个确切的设置,"Usage and Invocations" 说我应该能够 运行 测试
使用
python -m pytest
并且 pytest 会将当前目录添加到 sys.path
( 除了通过 python 调用还会将当前目录添加到 sys.path。").如果我尝试从 parent_directory/src
开始执行此操作,则不会收集任何测试 (collected 0 items
)。如果我从 parent_directory/
开始这样做,我会得到 ImportError: No module named 'project_name'
。
在 之后——(参见 "Test root path"),我发现添加(一个空的)conftest.py
到 src/
" 将让 pytest 在不指定 PYTHONPATH 的情况下识别您的应用程序模块”。
这样做之后,我可以去parent_directory/
并成功运行
pytest
和
pytest -k test_some_specific_test_function_name
请注意,我可以从 python -m pytest
切换到 pytest
,对此我很高兴。
但是,如果我尝试 运行 在特定文件(或目录)中进行测试,例如
pytest tests/project_name/test_utils.py
我,再一次得到ImportError: No module named 'project_name'
。这种行为让我很惊讶。
我检查过:
- pytest cannot find package when I put tests in a separate directory - 不同的目录结构
- PATH issue with pytest 'ImportError: No module named YadaYadaYada'(第一个建议是
sys.path
"hack",第二个是环境变量,如果同时处理多个项目,这是不切实际的——肯定有更好的方法)
- Py.test No module named * - 不同的目录结构
问题
什么是正确的工作流程,可以让我保留我的目录结构,同时最好从 parent_directory/
调用所有:
pytest
pytest -k test_some_specific_test_function_name
pytest tests/project_name/test_utils.py
无需一些手动 sys.path
黑客攻击。
我确定我遗漏了一些明显的东西。谢谢!
Pytest 将 添加当前目录到 sys.path
,但这并不一定意味着它使您的包可以从源代码树中导入。事实上,使用 src
和 test
布局的全部意义在于 防止 pytest 针对源代码树进行测试。
您可以通过 运行 一个 python 解释器从项目的顶级目录中自行检查并尝试导入包。它不会工作,除非它已经安装在您的工作环境中。
通过使用 src
和 test
布局,pytest 被迫针对已安装的软件包版本进行测试。请参阅 this great blog post 以这种方式构建项目的动机。这是关键段落:
You will be forced to test the installed code (e.g.: by installing in a virtualenv). This will ensure that the deployed code works (it's packaged correctly) - otherwise your tests will fail. Early. Before you can publish a broken distribution.
所以如果你想在你的项目中使用这种布局,你需要在测试之前安装你的包。这两种方法各有利弊,但 pytest 推荐它,我倾向于同意。
[更新]
作为方便本地测试的解决方法,您可以使用 setup.py develop
或 pip install -e .
在 development mode 中安装您的软件包。这使您的包看起来已安装在您的环境中,但源代码树中的任何更新都会立即反映在 "installed" 版本中。1
如果您选择采用这种方法,您应该确保您使用的是沙盒开发环境(例如 virtualenv
或 conda
),以免污染您的系统环境。
1 您应该知道,如果您的软件包提供 C/C++ 或 Cython 扩展,则需要手动重建它们。
我正在尝试设置一个项目(Python 3.4.4,pytest 3.3.1)以使用 pytest,但 pytest 无法 运行 在文件或目录中进行测试。我想我用错了 pytest,但不是正确的工作流程。
我试过的
根据 "Good Integration Practices" 中的建议,并且由于个人偏好将源代码和测试放在不同的文件夹中,我将我的项目设置如下:
parent_directory/
setup.py
src/
project_name/
__init__.py # empty
utils.py
tests/
__init__.py # empty
project_name/
__init__.py # empty
test_utils.py # has `import project_name.utils.py`
有了这个确切的设置,"Usage and Invocations" 说我应该能够 运行 测试 使用
python -m pytest
并且 pytest 会将当前目录添加到 sys.path
( 除了通过 python 调用还会将当前目录添加到 sys.path。").如果我尝试从 parent_directory/src
开始执行此操作,则不会收集任何测试 (collected 0 items
)。如果我从 parent_directory/
开始这样做,我会得到 ImportError: No module named 'project_name'
。
在 conftest.py
到 src/
" 将让 pytest 在不指定 PYTHONPATH 的情况下识别您的应用程序模块”。
这样做之后,我可以去parent_directory/
并成功运行
pytest
和
pytest -k test_some_specific_test_function_name
请注意,我可以从 python -m pytest
切换到 pytest
,对此我很高兴。
但是,如果我尝试 运行 在特定文件(或目录)中进行测试,例如
pytest tests/project_name/test_utils.py
我,再一次得到ImportError: No module named 'project_name'
。这种行为让我很惊讶。
我检查过:
- pytest cannot find package when I put tests in a separate directory - 不同的目录结构
- PATH issue with pytest 'ImportError: No module named YadaYadaYada'(第一个建议是
sys.path
"hack",第二个是环境变量,如果同时处理多个项目,这是不切实际的——肯定有更好的方法) - Py.test No module named * - 不同的目录结构
问题
什么是正确的工作流程,可以让我保留我的目录结构,同时最好从 parent_directory/
调用所有:
pytest
pytest -k test_some_specific_test_function_name
pytest tests/project_name/test_utils.py
无需一些手动 sys.path
黑客攻击。
我确定我遗漏了一些明显的东西。谢谢!
Pytest 将 添加当前目录到 sys.path
,但这并不一定意味着它使您的包可以从源代码树中导入。事实上,使用 src
和 test
布局的全部意义在于 防止 pytest 针对源代码树进行测试。
您可以通过 运行 一个 python 解释器从项目的顶级目录中自行检查并尝试导入包。它不会工作,除非它已经安装在您的工作环境中。
通过使用 src
和 test
布局,pytest 被迫针对已安装的软件包版本进行测试。请参阅 this great blog post 以这种方式构建项目的动机。这是关键段落:
You will be forced to test the installed code (e.g.: by installing in a virtualenv). This will ensure that the deployed code works (it's packaged correctly) - otherwise your tests will fail. Early. Before you can publish a broken distribution.
所以如果你想在你的项目中使用这种布局,你需要在测试之前安装你的包。这两种方法各有利弊,但 pytest 推荐它,我倾向于同意。
[更新]
作为方便本地测试的解决方法,您可以使用 setup.py develop
或 pip install -e .
在 development mode 中安装您的软件包。这使您的包看起来已安装在您的环境中,但源代码树中的任何更新都会立即反映在 "installed" 版本中。1
如果您选择采用这种方法,您应该确保您使用的是沙盒开发环境(例如 virtualenv
或 conda
),以免污染您的系统环境。
1 您应该知道,如果您的软件包提供 C/C++ 或 Cython 扩展,则需要手动重建它们。