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?有人经历过吗?
#1 楼
是的,如果您将cd
转到tests目录,则源文件夹不在Python的路径中。 您有2种选择:
将路径手动添加到测试文件中,如下所示:
import sys, os
myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + '/../')
使用env var
PYTHONPATH=../
运行测试。评论
我什么时候到目录?我正在从根目录运行py.test。除非我弄错了,而且你的意思是pytest遍历我的文件夹
–马托·托德(MattoTodd)
2012年4月20日在21:46
如果是cd问题,我也不会在Mac上打吗?
–马托·托德(MattoTodd)
2012年4月20日在21:46
哦,我误读了,并认为它在tests目录中不起作用。建议1中的技巧仍然有效。我只使用Linux,所以无法解释其他操作系统上的行为。
–Not_a_Golfer
2012年4月20日在21:50
您所有的test.py文件上都有类似的导入内容吗?
–马托·托德(MattoTodd)
2012年4月20日在21:50
是的,但是我的目录结构通常略有不同-我通常将/ src和/ test保留在根目录下。
–Not_a_Golfer
2012年4月20日在21:51
#2 楼
我不确定为什么py.test不会在PYTHONPATH本身中添加当前目录,但是这是一种解决方法(将从存储库的根目录执行):python -m pytest tests/
之所以有效,是因为Python为您添加了当前目录在PYTHONPATH中。
评论
如果您具有用于运行应用程序的代码,而不是在执行命令的级别上,则需要将相对导入重写为绝对导入。例如:project / test / all-my-tests和project / src / app.py,由于这一更改,需要使用project / src中的__main__.py文件间接调用app.py,这样才能使用调用python -m src。据我所知,这很混乱。
–塞尔菲·卡尔斯塔尔(Zelphir Kaltstahl)
16-09-26在15:44
@Zelphir:建议使用绝对导入。 Habnabit's有一篇有关打包最佳实践的好文章:blog.habnab.it/blog/2013/07/21/python-packages-and-you,PEP8说:“切勿使用隐式相对导入,并且应在Python中将其删除3.”请参阅:python.org/dev/peps/pep-0008。
– Apteryx
16-11-04在20:23
@Apteryx您的意思是“绝对项目”对吗?因为像/ home / user / dev / projectxyz / src ...这样的东西真的很糟糕,在大多数情况下不能在其他计算机上运行。我想我的意思是,即使模块与文件运行在同一文件夹中,我也必须始终将整个项目根目录写入模块路径。我不知道这是最佳做法,因此,这是有用的信息,谢谢。我仍然同意pep8的大部分内容,尽管它仍然不完美。
–塞尔菲·卡尔斯塔尔(Zelphir Kaltstahl)
16年11月6日在19:44
@Zelphir,是的,这就是我的意思。我相信Python中的绝对导入一词总是指“绝对项目”。请参阅:python.org/dev/peps/pep-0328/#rationale-for-absolute-imports。实际上,我敢肯定,至少从默认的“导入”机制出发,您不能从随机的绝对路径位置导入。
– Apteryx
16年11月7日在18:37
我在测试中添加了__init__.py,从而解决了该问题。现在我可以使用pytest
– Kiran Kumar Kotari
18/12/26在6:08
#3 楼
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文件的用途是什么?评论
@ aaa90210尽管我无法重现您的问题(从根目录中的conftest进行导入可以在任何级别上进行),但是您绝对不应从conftest文件中进行导入,因为它是pytest的保留名称,强烈建议您不要这样做。这样,您就可以为将来的错误种植种子。创建另一个名为utils.py的模块,并将代码放置在此处以便在测试中重用。
– hoe
19年1月15日在22:09
竖起大拇指!这是唯一对我有效的解决方案。
– 130nrd
19年5月23日在5:58
应该绝对是公认的答案-谢谢!
–马丁·佩克(Martin Peck)
19年7月30日在20:48
从逻辑上讲,conftest.py不属于应用程序代码,并且imo将其放在src /下是不正确的。
–尼克·奥莱(Nik O'Lai)
4月27日14:01
这个答案应该是SO上的固定标头。非常感谢。
– Rigoberta Raviolini
5月1日8:00
#4 楼
我有同样的问题。我通过在我的__init__.py
目录中添加一个空的tests
文件来修复它。评论
请注意,py.test不建议这样做:避免在测试目录中使用“ __init__.py”文件。这样,您可以针对已安装的mypkg版本轻松进行测试,而与安装的软件包是否包含测试无关。 SRC:pytest.org/latest/goodpractises.html
– K.-Michael Aye
2014年5月30日21:52
我来这里遇到同样的问题,发现从测试目录中删除__init__.py对我来说解决了。
–́101
15-10-13在0:24
@mafro我没看到问题吗?测试不必是可导入的代码,它们由测试运行程序发现。只有要测试的代码应该是已安装的软件包/模块,而不是测试。
– K.-Michael Aye
15年11月3日,19:01
在test /的子目录中添加__init__.py可以绝对导入,以针对要安装的模块在该子目录中运行特定的测试。谢谢。
–布莱斯·昆塔(Bryce Guinta)
16年9月9日在22:01
你去了那里:doc.pytest.org/en/latest/goodpractices.html真的很容易用google找到。
– K.-Michael Aye
17年1月12日,0:56
#5 楼
使用以下模块将pytest
本身作为模块运行:python -m pytest tests
评论
这似乎是一个可行的解决方案,但是有人可以解释为什么吗?我宁愿解决根本原因,而不是只使用python -m pytest而不作任何其他解释,而不是“因为它起作用”
–珍妮·恩伯格
18年8月23日在8:30
例如,当项目层次结构为:package / src package / tests以及从src导入的测试时,就会发生这种情况。作为模块执行时,会将导入视为相对于执行位置而言是绝对导入。
–斯特凡诺·墨西拿(Stefano Messina)
18年8月23日在11:55
这个解决方案对我有帮助,谢谢!原因是由于Python版本中的冲突。 pytest测试适用于早期的python版本。在我的情况下,我的python版本是3.7.1,python -m pytest测试有效,但pytest测试无效。
–张如曦
19年1月4日在19:16
来自Pytest:“使用python -m pytest [...]而不是pytest运行pytest会产生几乎相同的行为,除了前一个调用会将当前目录添加到sys.path。”
–摩纳哥(Moad Ennagi)
19年9月4日在14:55
#6 楼
您可以在项目根目录中使用PYTHONPATH运行PYTHONPATH=. py.test
,或使用pip install作为可编辑导入
pip install -e . # install package using setup.py in editable mode
评论
对于不在src目录结构中的测试目录并从同时包含test和src目录的目录进行调用,这对我不起作用。
–塞尔菲·卡尔斯塔尔(Zelphir Kaltstahl)
16年3月13日在22:53
#7 楼
我创建此文件是为了回答您的问题和我自己的困惑。希望对您有所帮助。请注意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}
评论
您能为您链接的项目做一个简短的解释吗?
– J法比安·迈耶(J Fabian Meier)
16年7月15日在14:06
也许只是我一个人,但是该项目上的自述文件非常详细,我对stackoverflow的评论说明了为什么创建回购协议。
–杰夫·麦克唐纳(Jeff MacDonald)
16年7月15日在14:10
尽管这不是严格必要的,但通常的策略是将答案的主要内容包含在答案本身中,因为这样可以确保从现在起x年内(当链接的资源可能已久逝时)该答案是可以理解的。
– J法比安·迈耶(J Fabian Meier)
16年7月15日在14:13
:) 那好吧。多数民众赞成在互联网上。
–杰夫·麦克唐纳(Jeff MacDonald)
16年7月15日在14:41
#8 楼
我在Flask中遇到了同样的问题。当我添加以下内容时:
__init__.py
到测试文件夹中,问题消失了:)
应用程序可能无法将文件夹测试识别为模块
评论
感谢您的回答。这是解决这个问题的最简单方法
– bwangel
11月8日,3:21
#9 楼
当我不小心将ConftestImportFailure: ImportError('No module named ...
文件添加到我的src目录中时,我开始收到奇怪的__init__.py
错误(这不应该是Python包,而只是所有来源的容器)。#10 楼
我通过删除源代码的父文件夹中的顶级__init__.py
来修复它。评论
为我修复。有人可以解释吗?
–更高
19年8月14日在20:40
这里的权利也为我解决了。如果有人有的话,我一定很乐意看到对此的解释
– king_wayne
19年11月7日在21:20
我添加了init.py,但仍然遇到相同的问题,但是此解决方案也对我有用。
–阿比吉特
19年11月18日在12:41
#11 楼
在遵循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
中找到您的应用。#12 楼
我有一个类似的问题。pytest
无法识别我正在工作的环境中安装的模块。我也通过将
pytest
安装到同一环境中来解决了该问题。评论
尽管我是从venv内部使用pytest的,但我也在全局安装了它,这给了我这个错误。卸载全局版本并在venv内安装后,它可以正常工作。
– Markus Ressel
3月10日3:41
#13 楼
由于出现了一些更简单的事情(您甚至可以说微不足道),我遇到了此错误。我尚未安装pytest
模块。因此,一个简单的apt install python-pytest
为我修复了它。'pytest'将作为测试依赖项在setup.py中列出。确保同时安装测试要求。
#14 楼
对我而言,问题是Django连同tests.py
目录生成的tests
。删除tests.py
解决了该问题。#15 楼
我错误地使用了相对导入,因此出现了此错误。在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
#16 楼
根据Dirk Avery在Medium上发表的一篇文章(并得到我的个人经验的支持),如果您在项目中使用虚拟环境,则无法在系统范围内安装pytest;您必须将其安装在虚拟环境中并使用该安装。特别地,如果您在两个地方都安装了它,则仅运行
pytest
命令将不起作用,因为它将使用系统安装程序。正如其他答案所述,一个简单的解决方案是运行python -m pytest
而不是pytest
;之所以有效,是因为它使用了环境版本的pytest。另外,您也可以卸载系统的pytest版本;重新激活虚拟环境后,pytest
命令应该可以使用。评论
到目前为止,对我唯一有用的是python -m pytest tests /。
–尼克·奥莱(Nik O'Lai)
4月27日14:10
#17 楼
正如Luiz Lezcano Arialdi所指出的那样,正确的解决方案是将您的程序包安装为可编辑的程序包。由于我使用的是pipenv,所以我考虑逐步将如何安装当前路径添加到他的回答中作为可与Pipenv一起使用的东西,它允许运行pytest而不需要任何混乱的代码或宽松的文件。
您将需要具有以下最小的文件夹结构(文档):
package/
package/
__init__.py
module.py
tests/
module_test.py
setup.py
设置。 py的大多数代码如下(文档):
import setuptools
setuptools.setup(name='package', # Change to your package name
packages=setuptools.find_packages())
然后您只需要运行
pipenv install --dev -e .
,pipenv会将当前路径安装为可编辑包(--dev标志是可选的)(文档) 。现在您应该可以毫无问题地运行
pytest
。#18 楼
我们通过添加以下环境变量解决了该问题。PYTHONPATH=${PYTHONPATH}:${PWD}/src:${PWD}/test
#19 楼
另外,如果您在虚拟环境中运行pytest
,请确保在虚拟环境中安装了pytest
模块。激活您的虚拟环境并运行pip install pytest
。#20 楼
很多时候,由于无法导入模块而导致测试中断。经过研究,我发现系统在错误的位置查看文件,我们可以通过复制包含模块的文件轻松地解决该问题。与所述文件夹相同,以便正确导入。另一个解决方案建议是更改导入的声明,并向MutPy显示单元的正确路径。但是,由于多个单元可以具有此依赖性,这意味着我们还需要在其声明中提交更改,因此,我们希望将单元简单地移动到文件夹中。评论
还提供了OP的问题的其他答案,这些答案已在一段时间前发布。发布答案时,请确保添加新的解决方案或实质上更好的解释,尤其是在回答较旧的问题时。有时最好在特定答案上发表评论。
–help-info.de
19-10-5在17:16
除了来自@ help-info.de的评论外:这是回答问题的指南的链接:stackoverflow.com/help/how-to-answer
– NOD之手
19-10-5在17:30
#21 楼
我的解决方案:在
conftest.py
目录中创建test
文件,其中包含:import os
import sys
sys.path.insert(0,os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/code/")
这会将感兴趣的文件夹添加到python路径中,而无需修改每个测试文件,设置环境变量或弄乱绝对/相对路径。
评论
这是使用setuptools修复它的方法。请检查@hoefling答案,并考虑更改您接受的答案,如果SO允许的时间很长的话,那就更好了!