Как создать параметризованное приспособление, которое зависит от значения другого параметризованного приспособления?Python

Программы на Python
Ответить
Anonymous
 Как создать параметризованное приспособление, которое зависит от значения другого параметризованного приспособления?

Сообщение Anonymous »

Пример:

Код: Выделить всё

from pytest import fixture, skip

@fixture(params=['a', 'b'])
def f1(request):
yield request.param

params = [('a', 1), ('a', 2), ('b', 10), ('b', 20)]
@fixture(params=params, ids=[str(x) for x in params])
def f2(f1, request):
if request.param[0] == f1:
yield request.param[1]
else:
skip('invalid')

def test_foo(f1, f2):
return
Это «базовый» светильник f1. А затем "сложенный" прибор f2, который должен выдавать значения (1, 2) для f1='a' и значения (10, 20) для f1='b'
, дает:

Код: Выделить всё

a.py::test_foo[a-('a', 1)] PASSED
a.py::test_foo[a-('a', 2)] PASSED
a.py::test_foo[a-('b', 10)] SKIPPED
a.py::test_foo[a-('b', 20)] SKIPPED
a.py::test_foo[b-('a', 1)] SKIPPED
a.py::test_foo[b-('a', 2)] SKIPPED
a.py::test_foo[b-('b', 10)] PASSED
a.py::test_foo[b-('b', 20)] PASSED
это близко к тому, чего я хочу достичь, за исключением того, что я хотел бы улучшить это, чтобы
  • пропущенные варианты вообще не отображались как тестовый пример
  • параметризованный идентификатор тестового набора отображается без повторения фикстуры f1. В идеале, как , например a-2, b-10 и т. д.
  • в идеале определяется более разумным способом, без повторений
Альтернатива 1: параметризация обходного пути
Существует своего рода обходной путь с использованием параметризации:

Код: Выделить всё

@pytest.mark.parametrize(params=('f1,f2', (('a', 1), ('b', 10))))
def test_foo():
return
Однако на самом деле это не решение, поскольку оно работает только для относительно простых и изолированных установок. Он выходит из строя, когда базовое приспособление f1 используется во многих тестовых случаях, и есть дополнительные приспособления f1_n, которые складываются поверх f1 только так:

Код: Выделить всё

@fixture
def f1_1(f1):
return
На этом этапе использование обходного пути параметризации приводит к дублированию и ухудшает возможность повторного использования других составных приборов.
Альтернатива 2: pytest_generate_tests
https://docs.pytest.org/en/latest/parametrize.html

Код: Выделить всё

f2_vals = {'a': (1,2), 'b': (10,20)}

def pytest_generate_tests(metafunc):
if "f2" in metafunc.fixturenames:
assert "f1" in metafunc.fixturenames
metafunc.parametrize("f2", f2_vals[get_f1_val()])
Но я не понимаю, как реализовать get_f1_val, и мало верю в этот подход, поскольку кажется, что pytest работает поэтапно, где он сначала собирает тестовые примеры, а затем выполняет их.
Альтернатива 3: игнорировать / удалять тестовые примеры
На данный момент запрос функции на https://github.com/pytest-dev/pytest/issues/3730, но решает только часть удаления недопустимых комбинаций тестовых наборов из результатов тестового сеанса.

Подробнее здесь: https://stackoverflow.com/questions/630 ... ther-param
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»