Могут ли крючки pytest использовать приспособления?

#python #pytest

#python #pytest

Вопрос:

Я знаю, что приспособления могут использовать другие приспособления, но может ли крючок использовать приспособление? Я много искал в сети, но не смог получить никакой помощи. Может кто-нибудь, пожалуйста, указать, делаю ли я здесь какую-либо ошибку?

 #conftest.py

@pytest.fixture()
def json_loader(request):   
    """Loads the data from given JSON file"""
    def _loader(filename):
        import json
        with open(filename, 'r') as f:
            data = json.load(f)
        return data
    return _loader



def pytest_runtest_setup(item,json_loader): #hook fails to use json_loader
    data = json_loader("some_file.json") 
    print(data) 
    #do something useful here with data
  

При запуске я получаю следующую ошибку.

pluggy.manager.Ошибка PluginValidationError: плагин ‘C:some_pathconftest.py ‘ for hook ‘pytest_runtest_setup’ определение hookimpl: аргументы pytest_runtest_setup(item, json_loader) {‘json_loader’} объявлены в hookimpl, но не могут быть найдены в hookspec

Даже если я не передаю json_loader в качестве аргумента в pytest_runtest_setup(), я получаю сообщение об ошибке «Приспособление «json_loader» вызывается напрямую. Приспособления не предназначены для прямого вызова»

Ответ №1:

Кажется, единственный поддерживаемый в настоящее время способ динамического создания экземпляров приспособлений — это использование request приспособления, в частности getfixturevalue метода

Это недоступно до начала тестирования в перехватчике pytest, но вы можете выполнить то же самое, используя приспособление самостоятельно

Вот (надуманный) пример:

 import pytest

@pytest.fixture
def load_data():
    def f(fn):
        # This is a contrived example, in reality you'd load data
        return f'data from {fn}'
    return f


TEST_DATA = None


@pytest.fixture(autouse=True)
def set_global_loaded_test_data(request):
    global TEST_DATA
    data_loader = request.getfixturevalue('load_data')
    orig, TEST_DATA = TEST_DATA, data_loader(f'{request.node.name}.txt')
    yield   
    TEST_DATA = orig


def test_foo():
    assert TEST_DATA == 'data from test_foo.txt'
  

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

1. Итак, у нас нет способа, чтобы хуки напрямую использовали приспособления? Разве это не допустимый вариант использования крючка для использования приспособления? Я удивлен, что я не вижу никакой помощи по этому поводу в документах pytest или кто-либо упоминает об этом где-либо.

Ответ №2:

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

 #Conftest.py#

def pytest_runtest_makereport(item, call):
    if call.when == 'call':
        cif_fixture = item.funcargs["your_cool_fixture"]
        print(cif_fixture)

#test_file.py#
@pytest.fixture(scope="module")
def your_cool_fixture(request):
    return "Hi from fixture"


def test_firsttest(your_cool_fixture):
    print(your_cool_fixture)
  

Ответ №3:

Вы можете сделать что-то вроде этого:

 @pytest.fixture
def my_fixture():
    pass

@pytest.mark.hookwrapper
def my_hook(item):
    feature_request = item.funcargs["request"]
    my_fixt = feature_request.getfixturevalue("my_fixture")