Python pytest'的路径问题;导入错误:没有名为yadayada';
我使用easy_install在mac上安装pytest,并开始为具有如下文件结构的项目编写测试:Python pytest'的路径问题;导入错误:没有名为yadayada';,python,unit-testing,pytest,Python,Unit Testing,Pytest,我使用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),每当它从我的应用程序路径第一次导入内容时,它就会发出吠声。比如说从应用程序导
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),每当它从我的应用程序路径第一次导入内容时,它就会发出吠声。比如说从应用程序导入一些应用程序中的定义
我是否需要编辑路径才能在这些系统上运行py.test?有人经历过吗 是,如果将
cd
转到tests目录,则源文件夹不在Python的路径中
from app import *
您有两种选择:
import sys, os
myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + '/../')
PYTHONPATH=../
运行测试我也有同样的问题。我通过向我的
tests
目录中添加一个空的\uuu init\uuuu.py
文件来修复它。您可以在项目根目录中使用PYTHONPATH运行
PYTHONPATH=. py.test
或者使用pip安装作为可编辑导入
pip install -e . # install package using setup.py in editable mode
我不确定py.test为什么不在PYTHONPATH本身中添加当前目录,但这里有一个解决方法(从存储库的根目录执行):
它之所以有效,是因为Python为您在PYTHONPATH中添加了当前目录。我创建这个目录是为了回答您的问题和我自己的困惑。我希望有帮助。请注意py.test命令行和tox.ini中的PYTHONPATH 具体地说:您必须告诉py.test和tox在哪里可以找到您包含的模块 使用py.test,您可以执行以下操作:
PYTHONPATH=. py.test
对于tox,将此添加到tox.ini中:
[testenv]
deps= -r{toxinidir}/requirements.txt
commands=py.test
setenv =
PYTHONPATH = {toxinidir}
我开始感到奇怪
ConftestImportFailure:ImportError('No module named…
errors,当我意外地将\uuu init\uuuuuuy.py
文件添加到我的src目录(该目录不应该是Python包,只是所有源代码的容器)。(你甚至可以说微不足道)。我没有安装pytest
模块。因此,一个简单的apt安装python-pytest
为我修复了它
“pytest”将作为测试依赖项列在setup.py中。请确保您也安装了测试要求。将
pytest
本身作为一个模块运行,其中包含:
python-m pytest测试
conftest
解决方案
入侵最小的解决方案是在repo/
目录中添加一个名为conftest.py
的空文件:
$ touch repo/conftest.py
就这样。无需编写自定义代码来破坏sys.path
,也无需记住拖动PYTHONPATH
,或将\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuupy.py
放在它不属于的目录中(不过,使用s中建议的python-m pytest
是一个很好的解决方案!)
项目目录:
repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
└── test_app.py
解释
pytest
在测试集合上查找conftest
模块以收集自定义挂钩和固定装置,为了从中导入自定义对象,pytest
将conftest.py
的父目录添加到sys.path
(在本例中为repo
目录)
其他项目结构
如果您有其他项目结构,请将conftest.py
放在包根目录中(包含包但本身不是包的目录,不包含\uuuuuuuuu.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
dir中):
请注意,将src
添加到PYTHONPATH
会降低src
布局的意义和好处!您最终将测试存储库中的代码,而不是安装的软件包。如果需要,可能根本不需要src
目录
从这里到哪里去
当然,conftest
模块不仅仅是帮助源代码发现的一些文件;它是pytest
框架的所有特定于项目的增强和测试套件定制的地方。pytest
有很多关于conftest
模块的信息,从
另外,还有一个关于
conftest
模块的极好问题:对我来说,问题是Django生成的tests.py
和tests
目录。删除tests.py
解决了这个问题。我错误地使用了相对导入。在OP示例中,test\u app.py应该导入funct离子使用例如
from repo.app import *
然而uuu init uuuuy.py文件分散在文件结构中,这不起作用,除非文件和测试文件位于同一目录中,否则会产生类似的导入错误
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_indicative.py:
- 在整个项目结构中放置_init__u;.py文件:
我也有类似的问题。
pytest
无法识别安装在我工作环境中的模块
我还通过将
pytest
安装到相同的环境中解决了这个问题。我通过删除源代码的父文件夹中的顶级\uuuu init\uuuuuuuuuuy.py
修复了它。很多时候,由于无法导入模块,测试被中断。经过研究,我发现系统正在查看wr中的文件通过将包含模块的文件复制到所述的同一文件夹中,我们可以轻松地克服这个问题,以便正确地
microbit/
microbit/activity_indicator/activity_indicator.py
microbit/tests/test_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
from setuptools import setup, find_packages
setup(name="PACKAGENAME", packages=find_packages())
pip install -e .
__init__.py
import os
import sys
sys.path.insert(0,os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/code/")
package/
package/
__init__.py
module.py
tests/
module_test.py
setup.py
import setuptools
setuptools.setup(name='package', # Change to your package name
packages=setuptools.find_packages())
PYTHONPATH=${PYTHONPATH}:${PWD}/src:${PWD}/test