问题:pytest的PATH问题“ ImportError:没有名为YadaYadaYada的模块”
我使用easy_install在Mac上安装pytest,并开始为文件结构像这样的项目编写测试:
repo/
repo/app.py
repo/settings.py
repo/models.py
repo/tests/
repo/tests/test_app.py
py.test
在repo目录中运行时,所有行为均符合您的预期
但是,当我在linux或Windows上尝试相同的操作时(两者上都装有pytest 2.2.3),只要它从我的应用程序路径中首次导入某些内容,它就会发出吠声。举例来说from app import some_def_in_app
我是否需要编辑PATH才能在这些系统上运行py.test?有人经历过吗?
回答 0
是的,如果您cd
转到tests目录,则源文件夹不在Python的路径中。
您有2个选择:
手动将路径添加到测试文件,如下所示:
import sys, os myPath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, myPath + '/../')
使用env var运行测试
PYTHONPATH=../
。
回答 1
我不确定为什么py.test不会在PYTHONPATH本身中添加当前目录,但这是一种解决方法(将从存储库的根目录执行):
python -m pytest tests/
之所以有效,是因为Python为您添加了当前目录到PYTHONPATH中。
回答 2
conftest
解
侵入性最低的解决方案是conftest.py
在repo/
目录中添加一个空文件:
$ touch repo/conftest.py
而已。无需编写自定义代码来处理,sys.path
也无需记住拖动PYTHONPATH
或放入__init__.py
不属于它的目录中。
之后的项目目录:
repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
└── test_app.py
说明
pytest
conftest
在测试集合中寻找模块以收集自定义的钩子和固定装置,然后为了从中导入自定义的对象,请将pytest
的父目录添加conftest.py
到中sys.path
(在本例中为repo
目录)。
其他项目结构
如果你有其他的项目结构,将conftest.py
包中的根目录(包含软件包,但不是包本身的人,所以并没有包含__init__.py
),例如:
repo
├── conftest.py
├── spam
│ ├── __init__.py
│ ├── bacon.py
│ └── egg.py
├── eggs
│ ├── __init__.py
│ └── sausage.py
└── tests
├── test_bacon.py
└── test_egg.py
src
布局
尽管此方法可用于src
布局(放置conftest.py
在src
目录中):
repo
├── src
│ ├── conftest.py
│ ├── spam
│ │ ├── __init__.py
│ │ ├── bacon.py
│ │ └── egg.py
│ └── eggs
│ ├── __init__.py
│ └── sausage.py
└── tests
├── test_bacon.py
└── test_egg.py
请注意,添加src
以PYTHONPATH
减轻src
布局的含义和好处!您将最终从存储库而不是已安装的软件包中测试代码。如果需要执行此操作,则可能根本不需要src
目录。
从这往哪儿走
当然,conftest
模块不仅仅是一些文件,可以帮助发现源代码。这是pytest
框架的所有特定于项目的增强和测试套件的自定义的地方。pytest
在conftest
整个文档中分散的模块上有很多信息; 开始于conftest.py
:本地按目录插件
同样,SO在conftest
模块上也有一个很好的问题:在py.test中,conftest.py文件的用途是什么?
回答 3
我有同样的问题。我通过__init__.py
在tests
目录中添加一个空文件来修复它。
回答 4
pytest
使用以下模块作为模块运行:
python -m pytest tests
回答 5
您可以在项目根目录中使用PYTHONPATH运行
PYTHONPATH=. py.test
或使用pip install作为可编辑导入
pip install -e . # install package using setup.py in editable mode
回答 6
我创建此文件是为了回答您的问题和我自己的困惑。希望对您有所帮助。注意py.test命令行和tox.ini中的PYTHONPATH。
https://github.com/jeffmacdonald/pytest_test
具体来说:您必须告诉py.test和tox在哪里可以找到要包含的模块。
使用py.test可以做到这一点:
PYTHONPATH=. py.test
并使用tox,将其添加到tox.ini中:
[testenv]
deps= -r{toxinidir}/requirements.txt
commands=py.test
setenv =
PYTHONPATH = {toxinidir}
回答 7
我在Flask中遇到了同样的问题。
当我添加时:
__init__.py
到测试文件夹,问题消失了:)
应用程序可能无法将文件夹测试识别为模块
回答 8
我通过删除__init__.py
源文件的父文件夹中的顶层来修复它。
回答 9
ConftestImportFailure: ImportError('No module named ...
当我不小心将__init__.py
文件添加到src目录中时,我开始出现奇怪的错误(这不应该是Python包,而只是所有来源的容器)。
回答 10
由于出现了一些更简单的事情(您甚至可以说微不足道),我遇到了此错误。我没有安装pytest
模块。因此apt install python-pytest
,为我修复了一个简单的问题。
“ pytest”将在setup.py中列为测试依赖项。确保同时安装测试要求。
回答 11
我有一个类似的问题。pytest
无法识别我在工作环境中安装的模块。
我也通过安装pytest
到同一环境中来解决它。
回答 12
对我来说,这个问题是tests.py
由Django和tests
目录生成的。删除tests.py
解决了问题。
回答 13
我错误地使用了相对导入,因此出现了此错误。在OP示例中,test_app.py应该使用例如
from repo.app import *
但是,__ init__.py文件通常分散在文件结构中,除非文件和测试文件位于同一目录中,否则这将无法正常工作,并会产生类似ImportError的错误。
from app import *
这是我与一个项目有关的示例:
这是我的项目结构:
microbit/
microbit/activity_indicator/activity_indicator.py
microbit/tests/test_activity_indicator.py
为了能够从test_activity_indicator.py访问activity_indicator.py,我需要:
- 使用正确的相对导入启动test_activity_indicatory.py:
from microbit.activity_indicator.activity_indicator import *
- 在整个项目结构中放置__init__.py文件:
microbit/
microbit/__init__.py
microbit/activity_indicator/__init__.py
microbit/activity_indicator/activity_indicator.py
microbit/tests/__init__.py
microbit/tests/test_activity_indicator.py
回答 14
通常,由于无法导入模块而导致测试中断。经过研究,我发现系统在错误的位置查看文件,我们可以通过在其中复制包含模块的文件来轻松解决问题。与所述文件夹相同,以便正确导入。另一个解决方案建议是更改导入的声明,并向MutPy显示单元的正确路径。但是,由于多个单元可以具有此依赖性,这意味着我们还需要在其声明中提交更改,因此,我们宁愿将单元简单地移动到文件夹中。
回答 15
根据Dirk Avery在Medium上发表的一篇文章(并得到我的个人经验的支持),如果您在项目中使用虚拟环境,则无法在系统范围内安装pytest;您必须将其安装在虚拟环境中并使用该安装。
特别是,如果在两个地方都安装了该pytest
命令,则仅运行该命令将不起作用,因为它将使用系统安装程序。正如其他答案所描述的,一个简单的解决方案是运行python -m pytest
而不是pytest
; 之所以有效,是因为它使用了环境版本的pytest。或者,您可以只卸载系统的pytest版本。重新激活虚拟环境后,该pytest
命令应起作用。
回答 16
在遵循Flask教程时,我遇到了同样的问题,我在Pytest官方文档中找到了答案。 这与我(以及我认为还有许多其他人)用于做事的方式有些不同。
您必须setup.py
至少使用以下两行在项目的根目录中创建一个文件:
from setuptools import setup, find_packages
setup(name="PACKAGENAME", packages=find_packages())
其中PACKAGENAME是您应用的名称。然后,您必须使用pip安装它:
pip install -e .
该-e
标志告诉pip以可编辑或“开发”模式安装软件包。因此,下次运行pytest
该程序时,它将在标准版本中找到您的应用程序PYTHONPATH
。
回答 17
我的解决方案:
conftest.py
在test
包含以下内容的目录中创建文件:
import os
import sys
sys.path.insert(0,os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/code/")
这会将感兴趣的文件夹添加到python路径,而无需修改每个测试文件,设置env变量或弄乱绝对/相对路径。