我使用easy_install在mac上安装pytest,并开始为具有如下文件结构的项目编写测试:
repo/
repo/app.py
repo/settings.py
repo/models.py
repo/tests/
repo/tests/test_app.py
在repo目录中运行py.test
,一切都按照您的预期行事
但是当我在linux或windows上尝试相同的东西时(两者都有pytest 2.2.3),每当它从我的应用程序路径首次导入某些内容时就会咆哮。比如说from app import some_def_in_app
我是否需要编辑我的PATH才能在这些系统上运行py.test?有没有人经历过这个?
答案 0 :(得分:194)
我不确定为什么py.test不会在PYTHONPATH本身中添加当前目录,但这是一种解决方法(从存储库的根目录执行):
python -m pytest tests/
这很有效,因为Python会为你添加PYTHONPATH中的当前目录。
答案 1 :(得分:92)
我遇到了同样的问题。我通过在__init__.py
目录中添加一个空的tests
文件来修复它。
答案 2 :(得分:68)
是的,如果您cd
到tests目录,则源文件夹不在Python的路径中。
您有两个选择:
手动将路径添加到测试文件中,如下所示:
import sys, os
myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + '/../')
使用env var PYTHONPATH=../
运行测试。
答案 3 :(得分:59)
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
添加{的父目录{1}} conftest.py
。
如果您有其他项目结构,请将sys.path
放在包根目录(包含包但不是包本身的那个)中,不包含{{1} }}),例如:
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
分散了遍布their docs的pytest
个模块的大量信息。以conftest.py
: local per-directory plugins
此外,SO在pytest
模块上有一个很好的问题:In py.test, what is the use of conftest.py files?
答案 4 :(得分:35)
您可以在项目根
中使用PYTHONPATH运行PYTHONPATH=. py.test
或使用pip install作为可编辑导入
pip install -e . # install package using setup.py in editable mode
答案 5 :(得分:28)
将pytest
本身作为模块运行:
python -m pytest tests
答案 6 :(得分:18)
我创建这个作为你的问题的答案和我自己的困惑。我希望它有所帮助。请注意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 :(得分:15)
我在Flask中遇到了同样的问题。
添加时:
__init__.py
到测试文件夹,问题消失了:)
应用程序可能无法将文件夹测试识别为模块
答案 8 :(得分:7)
当我不小心将ConftestImportFailure: ImportError('No module named ...
文件添加到我的src目录(不应该是Python包,只是所有源的容器)时,我开始收到奇怪的__init__.py
错误。
答案 9 :(得分:4)
在遵循Flask教程时,我遇到了同样的问题,并且在官方Pytest docs上找到了答案。 与我(我认为还有许多其他人)用于做事的方式相比,有一点转变。
您必须至少使用以下两行在项目的根目录中创建一个setup.py
文件:
from setuptools import setup, find_packages
setup(name="PACKAGENAME", packages=find_packages())
其中PACKAGENAME是您应用的名称。然后,您必须使用pip安装它:
pip install -e .
-e
标志告诉pip以可编辑或“开发”模式安装软件包。因此,下次您运行pytest
时,它将在标准PYTHONPATH
中找到您的应用。
答案 10 :(得分:3)
我因为更简单的事情而得到这个错误(你甚至可以说是微不足道的)。我没有安装pytest
模块。所以一个简单的apt install python-pytest
为我修复了它。
'pytest'将在setup.py中列为测试依赖项。确保您也安装了测试要求。
答案 11 :(得分:1)
我有一个类似的问题。 GeneModel
无法识别我在工作环境中安装的模块。
我也通过在同一环境中安装MATCH (model:GeneModel)
WITH model
MATCH (range:GenomicRange)
WHERE range.chromosome = model.chromosome AND range.posStart >= model.geneStart AND range.posStart <= model.geneEnd
CREATE (range)-[:RANGE_WITHIN]->(model)
来解决此问题。
答案 12 :(得分:1)
根据a post on Medium by Dirk Avery(并得到我的个人经验的支持),如果您在项目中使用虚拟环境,则无法在系统范围内安装pytest;您必须将其安装在虚拟环境中并使用该安装。
特别是,如果在两个地方都安装了该命令,则仅运行pytest
命令将无法使用,因为它将使用系统安装程序。正如其他答案所述,一个简单的解决方案是运行python -m pytest
而不是pytest
;之所以有效,是因为它使用了环境版本的pytest。另外,您也可以卸载系统的pytest版本;重新激活虚拟环境后,pytest
命令应该起作用。
答案 13 :(得分:1)
我通过删除源文件父文件夹中的顶级__init__.py
来解决此问题。
答案 14 :(得分:1)
由于我错误地使用了相对导入,因此出现了此错误。在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,我需要:
from microbit.activity_indicator.activity_indicator import *
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
答案 15 :(得分:1)
对我来说,问题是tests.py
由Django连同tests
目录一起生成。删除tests.py
解决了这个问题。
答案 16 :(得分:0)
经常由于无法导入模块而导致测试中断。研究后,我发现系统在错误的位置查看文件,我们可以通过复制包含以下内容的文件轻松解决问题:模块,与指定的文件夹相同,以便正确导入。另一个解决方案建议是更改导入的声明,并向MutPy显示单元的正确路径。但是,由于多个单元可以具有此依赖性,这意味着我们还需要在其声明中提交更改,因此,我们宁愿将单元简单地移动到文件夹中。
答案 17 :(得分:0)
Luiz Lezcano Arialdi指出,正确的解决方案是将软件包安装为可编辑的软件包。
由于我使用的是pipenv,因此我想逐步向他的答案中添加如何将当前路径安装为可食用的pipenv,从而允许在无需任何处理代码或松散文件的情况下运行pytest。< / p>
您将需要具有以下最小文件夹结构(documentation):
package/
package/
__init__.py
module.py
tests/
module_test.py
setup.py
setup.py大多数具有以下最小代码(documentation):
import setuptools
setuptools.setup(name='package', # Change to your package name
packages=setuptools.find_packages())
然后,您只需要运行pipenv install --dev -e .
,pipenv会将当前路径安装为可编辑程序包(--dev标志是可选的)(documentation)。
现在您应该可以毫无问题地运行pytest
。
答案 18 :(得分:0)
我们通过添加以下环境变量解决了该问题。
lastlogout
答案 19 :(得分:0)
此外,如果您在虚拟环境中运行pytest
,请确保在虚拟环境中安装了pytest
模块。激活您的虚拟环境并运行pip install pytest
。
答案 20 :(得分:0)
有点遗憾,这是python中的一个问题......但只需添加这个环境变量是IMO最舒适的方式:
export PYTHONPATH=$PYTHONPATH:.
您可以使用 direnv
来自动执行此操作:)
答案 21 :(得分:-1)
我的解决方案:
在conftest.py
目录中创建test
文件,其中包含:
import os
import sys
sys.path.insert(0,os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/code/")
这会将感兴趣的文件夹添加到python路径,而无需修改每个测试文件,设置环境变量或弄乱绝对/相对路径。