Фикстуры Pytest не обнаружены при запуске тестов из PyCharm IDE

У меня возникли проблемы с фиксами pytest в моем проекте. У меня есть корневой conftest.py файл с некоторыми приспособлениями общего назначения и отдельные conftest.py файлы для конкретных тестов. Структура папок следующая:

product-testing/
├── conftest.py  # Root conftest.py
├── tests/
│   └── grpc_tests/
│       └── collections/
│           └── test_collections.py
└── fixtures/
    └── collections/
        └── conftest.py  # Used by test_collections.py specifically

Когда я пытаюсь запустить тесты из IDE (PyCharm) с помощью кнопки «Выполнить» рядом с функцией тестирования, pytest не может инициализировать фикстуры из корня conftest.py. Тестовый код выглядит примерно так:

import datetime
import allure
from faker import Faker
from fixtures.collections.conftest import collection

fake = Faker()

@allure.title("Get list of collections")
def test_get_collections_list(collection, postgres):
    with allure.step("Send request to get the collection"):
        response = collection.collection_list(
            limit=1,
            offset=0,
            # ...And the rest of the code
        )

вот конкурс от fixtures/collection/

import datetime
import pytest

from faker import Faker
from path.to.file import pim_collections_pb2

fake = Faker()


@pytest.fixture(scope = "session")
def collection(grpc_pages):
    def create_collection(collection_id=None, store_name=None, items_ids=None, **kwargs):
        default_params = {
            "id": collection_id,
            "store_name": store_name,
            "item_ids": items_ids,
            "is_active": True,
            "description_eng": fake.text(),
            # rest of the code

и это корневой conftest.py файл

import pytest
from faker import Faker

from pages.manager import DBManager, GrpcPages, RestPages

fake = Faker()


@pytest.fixture(scope = "session")
def grpc_pages():
    return GrpcPages()


@pytest.fixture(scope = "session")
def rest_pages():
    return RestPages()


@pytest.fixture(scope = "session")
def postgres():
    return DBManager()

#some other code

Я получаю сообщение об ошибке:

test setup failed
file .../tests/grpc_tests/collections/test_collections.py, line 9
    @allure.title("Create a multi-collection")
    def test_create_multicollection(collection, postgres):

file .../fixtures/collections/conftest.py, line 10
    @pytest.fixture(scope = "session")
    def collection(grpc_pages):
E       fixture 'grpc_pages' not found
>       available fixtures: *session*faker, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, collection, doctest_namespace, factoryboy_request, faker, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

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

Я попытался явно импортировать недостающие приборы прямо из корня conftest.py, чтобы решить проблему. Это работает для одиночных запусков тестов, но вызывает ошибки при запуске всех тестов с использованием команд CLI, таких как pytest ., со следующей ошибкой:

```
ImportError while importing test module '/path/to/test_collections.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
.../importlib/init.py:127: in import_module
    return bootstrap.gcd_import(name[level:], package, level)
tests/.../test_collections.py:6: in <module>
    from conftest import grpc_pages
E   ImportError: cannot import name 'grpc_pages' from 'conftest' (/path/to/fixtures/users/conftest.py)
```

Такое ощущение, что pytest пытается найти grpc_pages в изолированном conftest.py, а не в корневом файле.

Кроме того, запуск изолированных тестов с помощью такой команды, как

  • pytest -k "test_create_multicollection" ./tests/grpc_tests/collections/
  • pytest path/to/test_collections.py::test_create_multicollection

работает, когда импорт не является явным. Однако мне нужно, чтобы кнопка run в IDE работала для менее опытных и нетехнических членов команды.

Итак, мои вопросы:

  1. Кто-нибудь сталкивался с этой проблемой, когда PyCharm не может найти фикстуры из корневого файла conftest.py при запуске отдельных тестов, но pytest может при запуске из командной строки?
  2. Как я могу это исправить, чтобы кнопка запуска PyCharm и pytest командной строки работали согласованно?

Дополнительный контекст:

  • Версия Pytest: pytest 7.4.4.
  • Версия PyCharm: 2023.2.1.
  • Версия Python: 3.9.6

Заранее спасибо за вашу помощь!

Ваш вопрос хорошо написан, но похоже, что сообщество (включая меня) не знает решения вашей проблемы.

Luke L 19.07.2024 03:23

Я очень удивлен, что pytest вообще смог найти приспособление в fixtures/collections/conftest.py. Согласно документации, тесты могут искать фикстуры только вверх до корня, но не «вниз». Таким образом, тест не должен был увидеть это приспособление collection (он должен был выполнить поиск до корня, а затем снова вернуться вниз). docs.pytest.org/en/7.1.x/reference/… Я пытался воспроизвести вашу тестовую настройку, но pytest так и не смог найти приспособление, ни из CLI, ни через pycharm.

CoffeeBasedLifeform 24.07.2024 13:36

Вы упомянули очень интересную вещь. У меня нет ответа на этот вопрос, поскольку я работал с ним через терминал, и это сработало. Может быть, в этой ситуации помогло то, что я их явно импортировал? ИДК, во всяком случае я уже поменял структуру репо и теперь всё работает нормально

llRub3Nll 24.07.2024 15:09
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
3
140
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В конфигурации запуска попробуйте изменить рабочий каталог. По умолчанию это расположение тестового файла. Когда вы запускаете его из консоли, рабочий каталог является корнем вашего репозитория, поэтому он может находить необходимые фикстуры при поиске модулей.

Кроме того, вы можете попробовать переключить некоторые параметры, например Add content roots to PYTHONPATH и Add source root to PYTHONPATH.

По сути, если вы можете без проблем запустить его из консоли, это просто означает, что Pycharm испытывает проблемы с путями.

Прежде чем написать здесь, я пытался переключать и отключать их, но они, похоже, тоже не работают.

llRub3Nll 19.07.2024 09:38

Удалось ли изменить рабочий каталог в конфигурации запуска?

Muslimbek Abduganiev 19.07.2024 10:17

нет, проблема осталась((

llRub3Nll 19.07.2024 14:56
Ответ принят как подходящий

После нескольких часов отладки и звонков я нашел решение, ИДК, возможно, однажды оно кому-нибудь поможет. Прежде всего, помещать конкурсные файлы в отдельный каталог от pytest - не лучшая идея, pytest не видит файлы, поэтому файлы следует помещать в тот же каталог или хотя бы по пути к тестовому файлу. Поэтому я переместил файлы из папки «фикстуры» в папку «тесты».

product-testing/
├── conftest.py  # Root conftest.py
├── tests/
│   └── grpc_tests/
│       └── collections/
│           └── test_collections.py
│           └── conftest.py  # Used by test_collections.py specifically

Кроме того, я избавился от явного импорта всех файлов и функций конфликтов из файла, поскольку pytest должен обрабатывать их сам. Код такой.

import datetime
import allure
from faker import Faker
#from fixtures.collections.conftest import collection -> get rid of this file

fake = Faker()

@allure.title("Get list of collections")
def test_get_collections_list(collection, postgres):
    with allure.step("Send request to get the collection"):
        response = collection.collection_list(
            limit=1,
            offset=0,
            # ...And the rest of the code
        )

И последнее, но не менее важное: я изменил корневой каталог тестирования на корневую папку проекта, щелкнув правой кнопкой мыши папку проекта и выбрав Mark directory As > Test Source Root

Эти изменения были внесены на основе официальной документации pytest и решили мои проблемы.

Другие вопросы по теме