Более чистый способ сделать параметризацию креплений Pytest на основе ключа командной строки?
Технически я уже решил проблему, над которой работал, но не могу не чувствовать, что мое решение ужасно:
У меня есть пакет pytest, который я могу запустить в двух режимах: локальный режим (для разработки тестов; все просто запускается на моем устройстве dev через Chrome) и режим регрессионного тестирования Seriousface (для CI; пакет запускается на миллионах браузеров). и ОС). У меня есть флаг командной строки для переключения между двумя режимами, --test-local
, Если это там, я бегу в локальном режиме. Если его там нет, я бегу в режиме серьезного лица. Вот как я это делаю:
# contents of conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption("--test-local", action="store_true", default=False, help="run locally instead of in seriousface mode")
def pytest_generate_tests(metafunc):
if "dummy" in metafunc.fixturenames:
if metafunc.config.getoption("--test-local"):
driverParams = [(True, None)]
else:
driverParams = [(False, "seriousface setting 1"), (False, "seriousface setting 2")]
metafunc.parameterize("dummy", driverParams)
@pytest.fixture(scope="function")
def driver(dummy):
_driver = makeDriverStuff(dummy[0], dummy[1])
yield _driver
_driver.cleanup()
@pytest.fixture
def dummy():
pass
Проблема в том, что dummy
крепость отвратительна Я пытался pytest_generate_tests
параметризовать driver
приспособление напрямую, но в итоге оно заменяет приспособление, а не просто подает в него вещи, так что cleanup()
никогда не вызывается, когда тест заканчивается. Использование пустышки позволяет мне заменить пустышку моим кортежем параметров, чтобы он передавался в driver()
,
Но, повторюсь, то, что у меня работает, это просто похоже на вздор.
1 ответ
Вы можете попробовать другой подход: вместо того, чтобы динамически выбирать набор параметров для теста, объявите ВСЕ наборы параметров для него, но отмените несоответствующие наборы во время запуска.
# r.py
import pytest
real = pytest.mark.real
mock = pytest.mark.mock
@pytest.mark.parametrize('a, b', [
real((True, 'serious 1')),
real((True, 'serious 2')),
mock((False, 'fancy mock')),
(None, 'always unmarked!'),
])
def test_me(a, b):
print([a, b])
Затем запустите его следующим образом:
pytest -ra -v -s r.py -m real # strictly marked sets
pytest -ra -v -s r.py -m mock # strictly marked sets
pytest -ra -v -s r.py -m 'not real' # incl. non-marked sets
pytest -ra -v -s r.py -m 'not mock' # incl. non-marked sets
Также, skipif
метки могут использоваться для выбранного набора параметров (отличается от отмены выбора). Они изначально поддерживаются Pytest. Но синтаксис довольно уродливый. Подробнее смотрите в разделе " Пропустить /xfail с параметризацией ".
Официальное руководство также содержит точно такой же случай, как и в вашем вопросе, в пользовательском маркере и параметре командной строки для управления запусками теста. Тем не менее, это также не так элегантно, как -m
Отмена выбора теста и больше подходит для сложных условий выполнения, а не для априорной структуры тестов.