Создать декоратор, совместимый с pytest.mark.parametrize - PullRequest
2 голосов
/ 18 июня 2019

Я хочу создать декоратор для моего теста, написанного с помощью pytest.Моя проблема, при вызове декоратора, pytest вызывает исключение, что декоратор не имеет параметров "test_params".

Пример декоратора:

def decorator_example(fn):

    def create(*args, **kwargs):
        # any code here
        return fn(*args, **kwargs)

return create

Пример теста:

@pytest.mark.parametrize(
    "test_params",
    [
        pytest.param("own_parameters")
    ])
@decorator_example
def test_1(self, fixture1, fixture2, test_params):
    pass

И обнаруженное исключение:

ValueError: <function create at address> uses no argument 'test_params'

Как создать декоратор, которыйбудет совместим с параметризованным тестом pytest?

1 Ответ

1 голос
/ 18 июня 2019

Это потому, что decorator_example заменяет функцию test_1 на функцию-оболочку create, которая имеет совершенно другую сигнатуру, нарушая самоанализ pytest (например, проверка того, имеет ли create аргумент test_params, завершается неудачей, посколькудоступны только *args и **kwargs).Вам необходимо использовать functools.wraps, чтобы имитировать подпись упакованной функции:

import functools


def decorator_example(fn):

    @functools.wraps(fn)    
    def create(*args, **kwargs):
        # any code here
        return fn(*args, **kwargs)

    return create

Совместимость с Python 2.7

Вы можете использовать decorator пакет.Установите его с помощью обычного

$ pip install decorator

. Пример выше:

import decorator


def decorator_example(fn):
    def create(fn, *args, **kwargs):
        return fn(*args, **kwargs)
    return decorator.decorator(create, fn)

или с использованием six:

import six


def decorator_example(fn):

    @six.wraps(fn)    
    def create(*args, **kwargs):
        # any code here
        return fn(*args, **kwargs)

    return create
...