pytest无法导入模块,而python可以

时间:2017-01-19 17:51:18

标签: python import pytest

我正在使用Python开发一个包。我用virtualenv。我在virtualenv的.pth路径中设置了模块根目录的路径,这样我就可以在开发代码的同时导入包的模块并进行测试(问题1:这是一个好方法吗?)。这很好用(这是一个例子,这是我想要的行为):

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python
Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from rc import ns
>>> exit()
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python tests/test_ns.py 
issued command: echo hello
command output: hello

但是,如果我尝试使用PyTest,我会收到一些导入错误消息:

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ pytest
=========================================== test session starts ============================================
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/zz/Desktop/GitFolders/rc, inifile: 
collected 0 items / 1 errors 

================================================== ERRORS ==================================================
________________________________ ERROR collecting tests/test_ns.py ________________________________
ImportError while importing test module '/home/zz/Desktop/GitFolders/rc/tests/test_ns.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ns.py:2: in <module>
    from rc import ns
E   ImportError: cannot import name ns
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================= 1 error in 0.09 seconds ==========================================
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ which pytest
/home/zz/Desktop/VirtualEnvs/VEnvTestRc/bin/pytest

我有点疑惑,看起来这表示导入错误,但Python做得很好所以为什么PyTest特别存在问题?对原因/补救措施的任何建议(问题2)?我用谷歌搜索并堆叠溢出了PyTest的'ImportError:无法导入'错误,但我得到的命中与丢失的python路径有关,并对此进行了补救,这似乎不是问题。有什么建议吗?

36 个答案:

答案 0 :(得分:60)

找到答案:

如果您打算使用pytest,请勿将__init__.py文件放在包含TESTS的文件夹中。我有一个这样的文件,删除它解决了问题。

这实际上埋没在对PATH issue with pytest 'ImportError: No module named YadaYadaYada'的第二个答案的评论中,所以我没有看到它,希望它在这里获得更多的可见性。

答案 1 :(得分:30)

我不能说我理解为什么会这样,但我遇到了同样的问题,如果我运行@Override public void start(Stage primaryStage) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); final ScriptEngine engine = manager.getEngineByMimeType("application/javascript"); ComboBox<Object> comboBox = new ComboBox(); comboBox.setCellFactory(c -> new ListCell<Object>() { @Override protected void updateItem(Object item, boolean empty) { super.updateItem(item, empty); if (empty || item == null) { setText(""); } else { Bindings bindings = new SimpleBindings(); bindings.put("a", item); try { // use script engine to retrieve text setText(Objects.toString(engine.eval("a.name", bindings))); } catch (ScriptException ex) { setText("Error"); } } } }); comboBox.setButtonCell(comboBox.getCellFactory().call(null)); Bindings b = new SimpleBindings(); b.put("cmbCategory", comboBox); engine.eval("function CategoryItem(id, name) {this.id = id;this.name = name;}\n" +"var Platform = Java.type(\"javafx.application.Platform\")\n" + "var categories = [new CategoryItem(1, 'a'), new CategoryItem(2, 'b'), new CategoryItem(3,'c')]\n" + "for each (var category in categories) {cmbCategory.getItems().add(category);}", b); Scene scene = new Scene(new StackPane(comboBox)); primaryStage.setScene(scene); primaryStage.show(); } ,测试工作正常。

我在virtualenv中,全球都有pytest:

python -m pytest

答案 2 :(得分:9)

我遇到了同样的问题,但出于另一个原因而不是提到的那些:

我全局安装了py.test,而软件包安装在虚拟环境中。

解决方案是在虚拟环境中安装pytest。 (如果你的shell哈希可执行文件,就像Bash那样,使用hash -r,或者使用py.test的完整路径)

答案 3 :(得分:8)

我刚刚通过删除项目根目录中的__init__.py解决了这个问题:

.
├── __init__.py <--- removed
├── models
│   ├── __init__.py
│   ├── address.py
│   ├── appointment.py
│   └── client.py
├── requirements.txt
├── setup.cfg
├── tests
│   ├── __init__.py
│   ├── models
│   │   ├── __init__.py
│   │   ├── appointment_test.py
│   │   └── client_test.py
│   └── other_test.py
└── script.py

答案 4 :(得分:5)

如果您的tests.py文件和带有tests/__init__.py的测试文件夹,则会出现此问题。

在收集期间,pytest找到该文件夹​​,但是当它尝试从文件夹导入测试文件时,tests.py文件将导致导入问题。

要修复,只需删除tests.py文件并将所有测试放在tests/文件夹中。

对于您的具体情况,修复将是:

  • 删除文件/home/zz/Desktop/GitFolders/rc/tests.py
  • 确保/home/zz/Desktop/GitFolders/rc/tests/__init__.py存在

答案 5 :(得分:3)

请在此处查看:https://docs.pytest.org/en/documentation-restructure/background/pythonpath.html

我在使用 pytest 时遇到了问题(已使用 python -m pytest 解决);错误是

FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.9/site-packages/...

我发现问题在 __init__.pytests/ 中缺少 tests/subfolders

答案 6 :(得分:3)

在我的情况下,我正在容器中工作,不幸的是pytest倾向于使用python2.7而不是我选择的python3解释器。

在我看来,这可行:

python3 -m pytest

我的文件夹结构

/
app/
-module1.py
-module2.py
-tests/
--test_module1.py
--test_module2.py
requirements.txt
README.md

答案 7 :(得分:3)

在我的情况下,导致导入错误,因为包指向另一个包含同名的包/目录,其路径比我实际想要的文件夹高一级。 我想这也解释了为什么有些人需要删除_ init _.py而其他人需要添加回来。

我只是在print(the_root_package.__path__)控制台和import the_root_package脚本中放置pythonpytest之后)以比较差异

BOTTOM LINE:执行python时,导入的包可能与运行pytest时的包不同。

答案 8 :(得分:3)

只需在项目根目录中放置一个空的conftest.py文件,因为当pytest发现conftest.py时,它会修改sys.path以便可以从conftest模块中导入内容。 常规目录结构可以是:

Root
├── conftest.py
├── module1
│   ├── __init__.py
│   └── sample.py
└── tests
    └── test_sample.py

答案 9 :(得分:2)

[已解决] 在直接进入删除/添加__init__.py的解决方案之前,我们可能还想研究一下如何在您的类中完成导入。实际上,我迷失了一天,只是__init__.py在想这可能是问题所在:)但是,那确实很有用。

就我而言,这是将类从一个python类调用到另一个抛出ImportError的python类的错误方法。修复了类/模块的调用方式,它就像魅力一样工作。希望这对其他人也有帮助。

是的,对于类似的错误,根据代码的编写方式,我们可能有不同的解决方案。最好花更多时间进行自我调试。获得的教训:)编码愉快!

答案 10 :(得分:2)

我不同意这些帖子,即您必须删除任何__init__.py文件。您必须要做的是更改sys.path

运行一个实验,在正常运行代码时打印sys.path。 然后在通过pytest运行代码的同时打印sys.path。我认为您会发现这两个路径之间存在差异,因此pytest为何会中断。

要解决此问题,请将第一个实验的路径插入第二个实验的第0个索引。

'/usr/exampleUser/Documents/foo'成为实验1的print(sys.path)的第一个元素。

下面是应解决您问题的代码:

import sys sys.path[0] = '/usr/exampleUser/Documents/foo'

在您的实际导入语句之前,将此文件放在文件顶部。

来源:我本人正在处理,上述过程解决了该问题。

答案 11 :(得分:2)

将软件包安装到您的虚拟环境中 然后启动一个新shell并再次获取您的虚拟环境。

答案 12 :(得分:1)

我遇到了同样的问题,我在venv上安装了pytest,然后开始工作。

pip install pytest

所以我的理解是,当pytest从全局安装运行时,它无法选择流行的venv中安装的模块。

答案 13 :(得分:1)

如果它与最初在python 2.7中开发,现在迁移到python 3.x的python代码有关,则该问题可能与导入问题有关。

例如 从同一目录中的文件base导入对象时,它将在python 2.x中工作:

from base import MyClass

在python 3.x中,您应该用base完整路径或.base替换 不这样做将导致上述问题。 所以尝试:

from .base import MyClass

答案 14 :(得分:1)

我通过在环境变量中为运行测试的特定配置设置PYTHONPATH解决了我的问题。

在PyCharm上查看测试文件时:

  1. Ctrl + Shift + A
  2. 键入Edit Configurations
  3. 在环境>环境变量下设置PYTHONPATH

答案 15 :(得分:1)

我正在使用VSCode来获得它。我有一个conda环境。我认为VScode python扩展程序看不到我所做的更新。

python c:\Users\brig\.vscode\extensions\ms-python.python-2019.9.34911\pythonFiles\testing_tools\run_adapter.py discover pytest -- -s --cache-clear test
Test Discovery failed:

我必须运行pip install ./ --upgrade

答案 16 :(得分:1)

编辑您的conftest.py并添加以下代码行:

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(file), '..')))

如果尝试通过终端运行测试用例,请使用以下示例:

python -m pytest test_some_step_file_steps.py --html=HTML_step_file_output.html --self-contained-html

答案 17 :(得分:1)

这里是a medium article!描述问题!

问题在于您使用的是哪个 pytest 以及您对虚拟环境的使用。 如果你已经在系统范围内安装了 pytest,换句话说,在虚拟环境之外,pytest 有一个讨厌的习惯,就是只在你的虚拟环境之外寻找模块!如果您的项目使用的模块仅安装在您的虚拟环境中,并且您使用的是系统范围的 pytest,即使您已激活虚拟环境,它也不会找到该模块。1

步骤如下:1

  1. 退出任何虚拟环境
  2. 使用 Pip 卸载 pytest
  3. 激活项目的虚拟环境
  4. 在虚拟环境中安装pytest
  5. pytest 现在将找到您的仅限虚拟环境的软件包!

答案 18 :(得分:1)

保留所有相同内容,只是在根文件夹中添加了一个空白测试文件。解决了

以下是调查结果,这个问题确实困扰了我一段时间。 我的文件夹结构是

mathapp/
    - server.py  
    - configuration.py 
    - __init__.py 
    - static/ 
       - home.html  
tests/            
    - functional 
       - test_errors.py 
    - unit  
       - test_add.py

和pytest会抱怨ModuleNotFoundError并给出提示-确保您的测试模块/软件包具有有效的Python名称。

我介绍了一个与mathsapp和tests目录相同级别的模拟测试文件。该文件不包含任何内容。现在pytest不会抱怨。

没有文件的结果

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 1 item / 1 error

=================================== ERRORS ====================================
_______________ ERROR collecting tests/functional/test_func.py ________________
ImportError while importing test module 'C:\mainak\workspace\0github\python-rest-app-cont\tests\functional\test_func.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests\functional\test_func.py:4: in <module>
    from mathapp.service import sum
E   ModuleNotFoundError: No module named 'mathapp'
=========================== short test summary info ===========================
ERROR tests/functional/test_func.py
!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
============================== 1 error in 0.24s ===============================

结果与文件

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 2 items

tests\functional\test_func.py .                                          [ 50%]
tests\unit\test_unit.py .                                                [100%]

============================== 2 passed in 0.11s ==============================

答案 19 :(得分:1)

Python的导入系统又获得了一次巨大的胜利。我认为,没有达成共识的原因是,有效的方法可能取决于您的环境以及在其上使用的工具。

我正在VS Code中使用它,它是在conda环境下Windows的Python 3.8中的测试浏览器中使用的。

我要工作的设置是:

class Foo
  attr_reader :key, :val

  def initialize(key, val)
    @key = key
    @val = val
  end

  def to_s
    "#{key}: #{val}"
  end
end

x = Foo.new('x', 1)
y = Foo.new('y', 2)

array = [x, y]

puts array.sort { |a, b| a.key <=> b.key }
puts array.sort { |a, b| b.key <=> a.key }
puts array.sort { |a, b| a.val <=> b.val }
puts array.sort { |a, b| b.val <=> a.val }

在此设置下,智能感知将起作用,测试发现也将起作用。

请注意,我最初按照建议here尝试了以下操作。

mypkg/
    __init__.py
    app.py
    view.py
tests/
    test_app.py
    test_view.py

我无法找到从VS Code上运行该文件的方法,因为src/ mypkg/ __init__.py app.py view.py tests/ test_app.py test_view.py 文件夹简直使导入系统望而却步。我可以想象有一种方法可以从命令行运行它。作为一种相对较新的Python编程转换,它带给我怀旧的使用COM的感觉,但乐趣却有所减少。

答案 20 :(得分:1)

我的2美分:如果您不使用虚拟环境,pytest可能会失败。有时它会起作用,有时则不会。

因此,解决方案是:

  • 通过pip卸载删除pytest
  • 创建虚拟货币
  • 激活您的虚拟视频
  • pip以可编辑的方式安装项目路径,因此pytest会将其视为模块(否则,pytest将找不到您的内部导入)。您将需要一个setup.py文件
  • 安装软件包,包括pytest
  • 最后,运行测试

使用Windows PowerShell的代码:

pip uninstall pytest
python.exe -m venv my_env
.\my_env\Scripts\activate
(my_env) pip install -e .
(my_env) pip install pytest pytest-html pandas numpy

然后终于

(my_env) pytest --html="my_testing_report.html"

setup.py的示例,用于pip install -e:

import setuptools

setuptools.setup(
    name='my_package',
    version='devel',
    author='erickfis',
    author_email='erickfis@gmail.com',
    description='My package',
    long_description='My gooood package',
    packages=setuptools.find_packages(),
    classifiers=[
        'Programming Language :: Python :: 3',
        'Operating System :: OS Independent',
    ],
    include_package_data=True
)

答案 21 :(得分:0)

就我而言,问题在于文件名和类名完全相同:分别为 FrameAnalyzer.pyFrameAnalyzer。将文件名更改为 frame_analyzer.py 后,一切正常。

答案 22 :(得分:0)

如果您从终端运行Pytest:

使用--import-mode=append命令行标志运行pytest。

如果您在PyCharm中运行Pytest:

“运行/调试配置:pytest”->“其他参数”->添加--import-mode=append


官方文档中的参数说明:https://docs.pytest.org/en/stable/pythonpath.html

答案 23 :(得分:0)

我最近遇到了类似的问题。它对我有用的方式是意识到“setup.py”是错误的

之前我删除了我之前的 src 文件夹,并添加了一个具有其他名称的新文件夹,但我没有更改 setup.py 上的任何内容(我猜是新手错误)。

所以将 setup.py 指向正确的包文件夹对我有用

from setuptools import find_packages, setup

setup(
    name="-> YOUR SERVICE NAME <-",
    extras_Require=dict(test=["pytest"]),
    packages=find_packages(where="->CORRECT FOLDER<-"),
    package_dir={"": "->CORRECT FOLDER<-"},
)

此外,不在测试文件夹和根文件夹中的 init.py

希望它对某人有帮助 =)

最好!

答案 24 :(得分:0)

另一种特殊情况:

我在使用毒药时遇到了问题。因此,我的程序运行良好,但是通过Tox进行的单元测试一直在抱怨。 安装软件包(程序需要)之后,您需要另外在tox.ini

中指定单元测试中使用的软件包。
copy.copy

答案 25 :(得分:0)

我有类似的问题,完全相同的错误,但原因不同。我运行的测试代码很好,但是对于旧版本的模块。在我的代码的先前版本中,存在一个类,而另一个类没有。更新我的代码后,我应该运行以下代码来安装它。

sudo pip install ./ --upgrade

安装运行pytest的更新模块后产生了正确的结果(因为我使用了正确的代码库)。

答案 26 :(得分:0)

这可以通过将相应的路径添加到系统的环境变量来解决。

由于你使用的是virtualenv,pytest可能不会读取虚拟机的环境变量。

我也遇到了这个问题并通过添加系统环境变量 (PATH) 的路径来解决

答案 27 :(得分:0)

我在那里找到答案:点击here

<块引用>

如果你有其他项目结构,将conftest.py放在包根目录下(包含包但不是包本身,所以不包含init.py)< /p>

答案 28 :(得分:0)

对于任何尝试了一切但仍然出错的人,我都有解决方法。

在安装pytest的文件夹中,转到 pytest-env 文件夹。

打开 pyvenv.cfg 文件。

在文件中,将 include-system-site-packages false 更改为 true

home = /usr/bin
include-system-site-packages = true
version = 3.6.6

希望它能奏效。别忘了投票。

答案 29 :(得分:0)

以上答案对我不起作用。我只是通过将未找到的模块的绝对路径附加到sys.path(您的测试模块)顶部的test_xxx.py来解决此问题,例如:

import sys
sys.path.append('path')

答案 30 :(得分:0)

我今天遇到此问题,并通过从项目目录的根目录调用python -m pytest解决了该问题。

从同一位置致电pytest仍然会引起问题。

我的项目目录的组织方式为:

api/
 - server/
  - tests/
      - test_routes.py
  - routes/
      - routes.py
 - app.py

模块routes在我的test_routes.py中被导入为:from server.routes.routes import Routes

希望有帮助!

答案 31 :(得分:0)

可能是Pytest没有将Python作为Python模块读取(可能是由于路径问题)。尝试更改pytest脚本的目录或将模块显式添加到PYTHONPATH。

或者可能是您的计算机上安装了两个版本的Python。检查你的Python源代码是否有pytest以及你运行的python shell。如果它们不同(即Python 2 vs 3),请使用source activate确保为运行模块的同一个python运行pytest。

答案 32 :(得分:0)

如果您的文件夹中需要一个 init .py文件,请复制该文件夹并删除其中的 init .py以运行您的本地测试项目。如果需要定期运行测试,请查看是否可以将 init .py移至单独的文件。

答案 33 :(得分:0)

有一个类似的问题,当我在测试目录下添加 init .py文件时,它起作用。

答案 34 :(得分:0)

如果您已经有.pyc文件,请尝试将其删除。

今天,我遇到了这个问题,这是发生了什么:

首先我在Mac中运行pytest(这将生成pyc文件) 然后我启动一个docker容器(操作系统是alpine),并安装了项目目录, 然后当我尝试在容器中运行pytest时,发生ImportError。 清除所有pyc文件后,再也没有错误。

希望这会有所帮助。

答案 35 :(得分:-1)

我已将所有测试放在一个tests文件夹中,并且遇到相同的错误。我通过在该文件夹中添加 init .py来解决此问题,

.
|-- Pipfile
|-- Pipfile.lock
|-- README.md
|-- api
|-- app.py
|-- config.py
|-- migrations
|-- pull_request_template.md
|-- settings.py
`-- tests
    |-- __init__.py <------
    |-- conftest.py
    `-- test_sample.py