Pytest с использованием параметризованного прибора VS. pytest.mark.parametrize - PullRequest
1 голос
/ 24 февраля 2020

Я пишу некоторые модульные тесты с использованием Pytest и наткнулся на два способа параметризации входных данных теста. Один использует параметризованные приборы, а другой - метод pytest.mark.parametrize.

У меня есть два примера:

# method 1
def tokens():
    yield from ["+", "*", "?"]

@pytest.mark.parametrize("token", tokens())
def test_stuff(token):
    assert stuff

и

# method 2
@pytest.fixture(params=["+", "*", "?"])
def token(request):
    return request.param

def test_stuff(token):
    assert stuff

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

Метод 1

Преимущества

  • Поддержка нескольких параметров
  • Поддержка отложенной оценки

Недостатки

  • Больше шаблонного кода при использовании для нескольких методов тестирования
  • требует явного сопоставления параметров для каждого используемого метода, даже если параметры имеют одно и то же имя

метод 2

Преимущества

  • Меньше кода котельной пластины

Недостатки

  • Допускается только один параметр чтобы перейти к модульному тесту

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

1 Ответ

1 голос
/ 10 марта 2020

Как pk786 упоминает в своем комментарии, вы должны использовать прибор "... если у вас есть что-то для настройки и разрыва для теста или использовать один и тот же набор данных для нескольких тестов, тогда используйте прибор ".

Например, вы можете загрузить несколько наборов данных, с которыми вы тестируете, в разных тестовых функциях. Использование прибора позволяет вам загружать эти наборы данных только один раз и совместно использовать их в тестовых функциях. Вы можете использовать params аргумент @pytest.fixture для загрузки и кэширования каждого набора данных. Затем тестовые функции, использующие эти приборы, будут работать с каждым загруженным набором данных. В коде это может выглядеть примерно так:

import json

import pytest


test_files = ["test_file1.json", "test_file2.json"]


@pytest.fixture(params=test_files)
def example_data(request):
    with open(request.param, "r") as f:
        data = json.load(f)
    return data


def test_function1(example_data):
    # run test with example data.
    # this test will be run once for each file in the list `test_files` above.
    ...


def test_function2(example_data):
    # run a different test with example data.
    # this test will be run once for each file in the list `test_files` above.
    # this test takes advantage of automatic caching mechanisms of fixtures...
    # ...so that data is not loaded again.
    ...   

В качестве альтернативы, как pk786 заявляет: «Если вы используете набор данных только один раз, то @ pytest.mark.parametrize должен будьте подходом ».

Это утверждение относится к примеру, который вы предоставили, поскольку вы не выполняете никаких настроек в приборе, которые вы хотите использовать в тесте. В этом случае, даже если вы используете «токены» в нескольких тестах, я бы подумал о том, чтобы украсить каждую функцию @pytest.mark.parameterize, так как я считаю, что этот подход более явно выражает ваши намерения и его будет легче понять всем, кто читает ваш код. Это будет выглядеть так:

...

def tokens():
    yield from ["+", "*", "?"]


@pytest.mark.parametrize("token", tokens())
def test_stuff(token):
    assert stuff


@pytest.mark.parametrize("token", tokens())
def test_other_stuff("token", tokens())
    assert other_stuff
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...