pytest - минимальное сопровождение для параметризации результатов «таблицы умножения»

1

Я хочу параметризовать тест для 2 входных значений и одного выходного значения, которое можно сравнить с тестовой таблицей умножения. Чтобы добиться минимального обслуживания, я придумал что-то вроде этого:

results = [[ 4,  5,  6],
           [ 8, 10, 12],
           [12, 15, 18]]

@pytest.mark.parametrize("x, ix", [(1, 0), (2, 1), (3, 2)])
@pytest.mark.parametrize("y, iy", [(4, 0), (5, 1), (6, 2)])
def test_multiplication(x, ix, y, iy):
    assert x * y == results[ix][iy]

Теперь это не идеально, потому что если бы я хотел добавить новый x тогда мне нужно будет добавить значения len(y) + 1 + 1 которые представляют собой: 3 новых ожидаемых значения, дополнительное значение x и индекс. Идеал будет добавлять только 4 значения, т.е. без управляющей переменной для индекса. Мне также не нравится, как results отделяются от тестовой функции. Идеальным было бы:

@pytest.mark.parametrize("x", [1, 2, 3])
@pytest.mark.parametrize("y", [4, 5, 6])
@pytest.mark.result_matrix("result", [
    [ 4,  5,  6],
    [ 8, 10, 12],
    [12, 15, 18],
])
def test_multiplication(x, y, result):
    assert x * y == result

Я знаю, что я могу добавить поддержку для result_matrix маркера result_matrix. Но могу ли я достичь того же, используя существующие инструменты? Пожалуйста, примите во внимание решение, которое будет хорошо работать для потенциально бесконечного числа входных параметров.

  • 1
    Параметризировать с помощью одного маркера из трех кортежей?
  • 0
    @ev-br ev-br Тогда входные значения для x и y будут продублированы.
Показать ещё 1 комментарий
Теги:
combinations
parameters
pytest

1 ответ

0

Я сомневаюсь, что есть решение для действительно бесконечного числа параметров, но вы можете попробовать следующее:

1) так же, как предлагает @ev-br, предоставить все параметры функций в одном parametrize выражении, но вы должны подготовить их до этого в конструкторе для этих аргументов.

2) сделать то же самое for цикла за одно и то же аргументацию. Это менее фантастично, чем mark.parametrize, но часто более читаемым.

3) сделайте свою тестовую параметризацию или for цикл, чтобы принять список словарей с аргументами и результатом:

# code under test
def foo(x, y):
    return x * y

# need a constructor code for these test arguments and results
d0=dict(args=dict(x=2, y=3), result=6)
d1=dict(args=dict(x=5, y=10), result=50)
params = [d0, d1]

# test prototype - goes to pytest
for d in params:
    assert foo(**d['args']) == d['result'] 

Я думаю, что эта часть ближе всего к вашей концепции принятия большого количества аргументов.

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

  • 0
    Это решение и предложенные три кортежа требуют большего обслуживания из-за возможного дублирования значений для x и y но это делает тесты менее сложными, чем в моем примере с индексом. Я понимаю, что мое идеальное решение может быть не столь очевидным для понимания.
  • 0
    @JCode - тесты, как правило, показывают сложность базового кода (более сложный тестируемый код требует больших фиксаторов, управления ими и т. Д.). Трудно понять, как вы пропускаете x и y, если тестируемая функция нуждается в их запуске (возможно, есть возможность изменить ее тоже). Я думаю, что ваша проблема заключается в сборщике приборов, а не в лучшем способе передачи аргументов и результата к тесту.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню