Почему возникает ошибка импорта в основном исходном файле только при запуске pytest?

#python #python-3.x #pytest #python-import

Вопрос:

Почему при запуске pytest возникает ошибка импорта? Я обычно могу получить доступ к основным файлам в pylib_example/ просто отлично.

 preetam@preddy-Desktop:~/Desktop/pylib_example$ tree
.
├── pylib_example
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-38.pyc
│   │   └── pyfile2.cpython-38.pyc
│   ├── pyfile1.py
│   └── pyfile2.py
├── setup.py
└── tests
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-38.pyc
    │   └── test_pyfile2.cpython-38-pytest-6.2.5.pyc
    └── test_pyfile2.py

4 directories, 10 files
 

pyfile1.py:

 import configparser

def file1_func1():
    return "File1 Func1"

def file1_func2():
    return "File2 func2"
 

pyfile2.py:

 import pyfile1

def file2_func1():
    print("{}".format(pyfile1.file1_func1()))
    return pyfile1.file1_func1()
 

test_pyfile2.py:

 from pylib_example import pyfile2
import pytest

def test_file2_func1():
    print("**********")
    assert pyfile2.file2_func1() == "File1 Func1"
 
 
preetam@preddy-Desktop:~/Desktop/pylib_example$ pytest
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
rootdir: /home/preetam/Desktop/pylib_example
plugins: cov-2.12.1
collected 0 items / 1 error                                                                                                                                                                                       

===================================================================================================== ERRORS ======================================================================================================
_____________________________________________________________________________________ ERROR collecting tests/test_pyfile2.py ______________________________________________________________________________________
ImportError while importing test module '/home/preetam/Desktop/pylib_example/tests/test_pyfile2.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_pyfile2.py:1: in <module>
    from pylib_example import pyfile2
pylib_example/pyfile2.py:1: in <module>
    import pyfile1
E   ModuleNotFoundError: No module named 'pyfile1'
============================================================================================= short test summary info =============================================================================================
ERROR tests/test_pyfile2.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================================================ 1 error in 0.05s =================================================================================================
 

Комментарии:

1. пробовать: PYTHONPATH=. pytest

2. Тот же результат, что и раньше

3. from . import pyfile1 вместо import pyfile1 . Последнее — это имя верхнего уровня.

Ответ №1:

когда мы запускаем любой скрипт, папка, содержащая скрипт, становится путем, и все импортируемые файлы должны соответствовать только этому пути.

Чтобы запустить любой скрипт из текущего каталога, нам нужно запустить

 python -m script.py
 

Решение: 1

Вот в этом случае. pytest запускается из корневого каталога, поэтому мы можем писать импорт следующим образом

tests/test_pyfile2.py

 from pylib_example import pyfile2
import pytest

def test_file2_func1():
    print("**********")
    assert pyfile2.file2_func1() == "File2 func2"
 

pylib_example/pyfile2.py

 from pylib_example import pyfile1

def file2_func1():
    print("{}".format(pyfile1.file1_func1()))
    return pyfile1.file1_func1()

 

pylib_example/pyfile1.py

 import configparser

def file1_func1():
    return "File1 Func1"

def file1_func1():
    return "File2 func2"

 

Решение: 2

Вы также можете добавить путь, чтобы упростить импорт, но это не очень хорошее решение.

tests/test_pyfile2.py

 import os
import sys

sys.path.insert(0, os.path.abspath("relative path to your pylib_example"))

import pyfile2
import pytest

def test_file2_func1():
    print("**********")
    assert pyfile2.file2_func1() == "File2 func2"

 

Примечание: Сохраните оставшийся файл таким же, как в вашем вопросе

Комментарии:

1. Решение имеет проблемы при локальном импорте в реальном случае использования. Однако он может работать при установке в пути к библиотеке python. ModuleNotFoundError: Нет модуля с именем «pylib_example»

2. Решение 2 вообще не сработало.

3. 1. Проверьте правку, чтобы указать правильный путь 2. каков ваш путь к python? Вы не используете какой-либо виртуальный env? Примечание: Я на самом деле протестировал их, запустив их на своей локальной машине, это работает для меня, если возможно, предоставьте более подробную информацию.

4. python -m script.py грубо говоря, это означает запуск файла script/py.py . Я не думаю, что это то, что вы хотели предложить.

5. Я предлагал это в общих чертах, вы правы, это не имеет никакого отношения к решению