pytest的问题'导入错误:没有名为YadaYadaYada的模块'

时间:2012-04-20 21:32:04

标签: 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),每当它从我的应用程序路径首次导入某些内容时就会咆哮。比如说from app import some_def_in_app

我是否需要编辑我的PATH才能在这些系统上运行py.test?有没有人经历过这个?

22 个答案:

答案 0 :(得分:194)

我不确定为什么py.test不会在PYTHONPATH本身中添加当前目录,但这是一种解决方法(从存储库的根目录执行):

python -m pytest tests/

这很有效,因为Python会为你添加PYTHONPATH中的当前目录。

答案 1 :(得分:92)

我遇到了同样的问题。我通过在__init__.py目录中添加一个空的tests文件来修复它。

答案 2 :(得分:68)

是的,如果您cd到tests目录,则源文件夹不在Python的路径中。

您有两个选择:

  1. 手动将路径添加到测试文件中,如下所示:

    import sys, os
    myPath = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, myPath + '/../')
    
  2. 使用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 docspytest个模块的大量信息。以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,我需要:

  • 使用正确的相对导入开始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

答案 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路径,而无需修改每个测试文件,设置环境变量或弄乱绝对/相对路径。