После некоторых тестов я пришел к чему-то работающему. Вероятно, это не лучший способ сделать это, но я думаю, что это вполне удовлетворительно.
Весь код ниже был добавлен в модуль conftest.py
, кроме двух тестов.
Сначала определите словарь, содержащий данные опций:
options = {
'port': {'action': 'store', 'help': 'TCP port', 'type': int},
'ip': {'action': 'store', 'help': 'IP address', 'type': str},
}
Мы могли бы обойтись без help
и type
, но это будет иметь определенную утилиту позже.
Затем вы можете использовать это options
для создания опций pytest:
def pytest_addoption(parser):
for option, config in options.items():
parser.addoption(f'--{option}', **config)
На этом этапе pytest --help
дает следующее (обратите внимание на использование данных help
, которое обеспечивает удобный документ):
usage: pytest [options] [file_or_dir] [file_or_dir] [...]
...
custom options:
--port=PORT TCP port
--ip=IP IP address
Наконец, мы должны определить приборы. Я сделал это, предоставив функцию make_fixture
, которая используется в цикле при чтении conftest.py
для динамического создания осветителей и добавления их в глобальную область видимости модуля:
def make_fixture(option, config):
func = lambda request: request.config.getoption(option)
func.__doc__ = config['help']
globals()[option] = pytest.fixture()(func)
for option, config in options.items():
make_fixture(option, config)
Опять же, данные «справки» используются для построения строки документации для созданных приборов и их документирования. Таким образом, вызов pytest --fixtures
печатает это:
...
---- fixtures defined from conftest ----
ip
IP address
port
TCP port
Вызов pytest --port 80 --ip 127.0.0.1
, с помощью двух следующих очень простых тестов, кажется, подтверждает трюк (Здесь данные type
показывают его полезность, он заставил pytest преобразовать порт в int
вместо строки) :
def test_ip(ip):
assert ip == '127.0.0.1'
def test_ip_port(ip, port):
assert ip == '127.0.0.1'
assert port == 80
(Очень интересный вопрос, хотелось бы увидеть больше такого)