У меня возникли проблемы с фиксами 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 работала для менее опытных и нетехнических членов команды.
Итак, мои вопросы:
Дополнительный контекст:
Заранее спасибо за вашу помощь!
Я очень удивлен, что pytest вообще смог найти приспособление в fixtures/collections/conftest.py
. Согласно документации, тесты могут искать фикстуры только вверх до корня, но не «вниз». Таким образом, тест не должен был увидеть это приспособление collection
(он должен был выполнить поиск до корня, а затем снова вернуться вниз). docs.pytest.org/en/7.1.x/reference/… Я пытался воспроизвести вашу тестовую настройку, но pytest так и не смог найти приспособление, ни из CLI, ни через pycharm.
Вы упомянули очень интересную вещь. У меня нет ответа на этот вопрос, поскольку я работал с ним через терминал, и это сработало. Может быть, в этой ситуации помогло то, что я их явно импортировал? ИДК, во всяком случае я уже поменял структуру репо и теперь всё работает нормально
В конфигурации запуска попробуйте изменить рабочий каталог. По умолчанию это расположение тестового файла. Когда вы запускаете его из консоли, рабочий каталог является корнем вашего репозитория, поэтому он может находить необходимые фикстуры при поиске модулей.
Кроме того, вы можете попробовать переключить некоторые параметры, например Add content roots to PYTHONPATH
и Add source root to PYTHONPATH
.
По сути, если вы можете без проблем запустить его из консоли, это просто означает, что Pycharm испытывает проблемы с путями.
Прежде чем написать здесь, я пытался переключать и отключать их, но они, похоже, тоже не работают.
Удалось ли изменить рабочий каталог в конфигурации запуска?
нет, проблема осталась((
После нескольких часов отладки и звонков я нашел решение, ИДК, возможно, однажды оно кому-нибудь поможет. Прежде всего, помещать конкурсные файлы в отдельный каталог от 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
и решили мои проблемы.
Ваш вопрос хорошо написан, но похоже, что сообщество (включая меня) не знает решения вашей проблемы.