关于python:与pytest的PATH问题’ImportError:没有名为YadaYadaYada的模块’

PATH issue with pytest 'ImportError: No module named YadaYadaYada'

我使用easy-install在Mac上安装pytest,并开始为具有如下文件结构的项目编写测试:

1
2
3
4
5
6
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

是否需要编辑路径以在这些系统上运行py.test?有人经历过吗?


我不知道为什么py.test不在pythonpath本身中添加当前目录,但这里有一个解决方法(从存储库的根目录执行):

1
python -m pytest tests/

它工作是因为python为您添加了pythonpath中的当前目录。


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


是的,如果您在测试目录中使用cd,那么源文件夹不在python的路径中。

您有两个选择:

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

    1
    2
    3
    import sys, os
    myPath = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, myPath + '/../')
  • 使用env var PYTHONPATH=../运行测试。


  • conftest解决方案

    微创解决方案是在repo/目录中添加一个名为conftest.py的空文件:

    1
    $ touch repo/conftest.py

    就这样。不需要编写用于管理sys.path的自定义代码,也不需要记住拖动PYTHONPATH或将__init__.py放入不属于它的目录中。

    之后的项目目录:

    1
    2
    3
    4
    5
    6
    7
    repo
    ├── conftest.py
    ├── app.py
    ├── settings.py
    ├── models.py
    └── tests
         └── test_app.py

    解释

    pytest在测试集合中查找conftest模块,以收集自定义挂钩和固定装置,为了从中导入自定义对象,pytestconftest.py的父目录添加到sys.path中。

    其他项目结构

    如果您有其他项目结构,请将conftest.py放在包根目录中(包含包但不是包本身,因此不包含__init__.py的目录),例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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目录中):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    repo
    ├── src
    │   ├── conftest.py
    │   ├── spam
    │   │   ├── __init__.py
    │   │   ├── bacon.py
    │   │   └── egg.py
    │   └── eggs
    │       ├── __init__.py
    │       └── sausage.py
    └── tests
         ├── test_bacon.py
         └── test_egg.py

    当心添加srcPYTHONPATH会降低src布局的意义和好处!最后,您将从存储库测试代码,而不是从已安装的包进行测试。如果你需要这样做,也许你根本不需要src目录。

    从这里到哪里

    当然,conftest模块不仅仅是一些帮助源代码发现的文件;它是pytest框架的所有特定于项目的增强和您的测试套件的定制发生的地方。pytest有很多关于分散在文档中的conftest模块的信息;从conftest.py开始:本地目录插件

    另外,在conftest模块上还有一个很好的问题:在py.test中,conftest.py文件的用途是什么?


    可以在项目根目录中使用pythonpath运行

    1
    PYTHONPATH=. py.test

    或者使用pip安装作为可编辑导入

    1
    pip install -e .   # install package using setup.py in editable mode


    以模块形式运行pytest,其中:埃多克斯1〔9〕


    我创建这个是为了回答你的问题和我自己的困惑。希望有帮助。注意py.test命令行和tox.ini中的pythonpath。

    https://github.com/jeffmacdonald/pytest_测试

    具体来说:你必须告诉py.test和tox在哪里找到你所包含的模块。

    使用py.test,可以执行以下操作:

    1
    PYTHONPATH=. py.test

    在tox.ini中加入这个:

    1
    2
    3
    4
    5
    [testenv]
    deps= -r{toxinidir}/requirements.txt
    commands=py.test
    setenv =
        PYTHONPATH = {toxinidir}


    当我意外地将__init__.py文件添加到src目录(不应该是python包,只是一个包含所有源代码的容器)时,我开始遇到奇怪的ConftestImportFailure: ImportError('No module named ...错误。


    我得到这个错误是因为一些更简单的事情(你甚至可以说是微不足道的)。我没有安装pytest模块。所以一个简单的apt install python-pytest为我修理了它。

    "py test"将作为测试依赖项列在setup.py中。确保您也安装了测试需求。


    我也有类似的问题。pytest无法识别安装在我工作环境中的模块。

    我还将pytest安装到相同的环境中,解决了这个问题。


    我在使用相对导入时出错。在OP示例中,test_app.py应使用例如

    1
    from repo.app import *

    然而,大量的init_uuuuuy文件分散在文件结构周围,这不起作用,并且会产生一种重要的错误,除非文件和测试文件在同一个目录中。

    1
    from app import *

    下面是一个例子,说明了我与我的一个项目之间的关系:

    以下是我的项目结构:

    1
    2
    3
    microbit/
    microbit/activity_indicator/activity_indicator.py
    microbit/tests/test_activity_indicator.py

    为了能够从test_activity_indicator.py访问activity_indicator.py,我需要:

    • 使用正确的相对导入启动test_activity_indicative.py:
    1
        from microbit.activity_indicator.activity_indicator import *

    • 在整个项目结构中放置uuu init_uuuu.py文件:
    1
    2
    3
    4
    5
    6
        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


    对我来说,问题是django生成的tests.pytests目录。删除tests.py解决了这个问题。