#python #testing #pytest
#python #тестирование #pytest
Вопрос:
У меня есть код pytest в У меня есть setup_module, в котором я выполняю некоторую обработку кода, которая изменяет список списков с именем testdata, который объявлен глобально. Мне нужно динамически передавать этот список списков в мой тестовый пример на основе того, что я получаю от setup_module.
testdata = [['servername_1', 'servermac_1', 'vlans'],['servername_2', 'servermac_2', 'vlans']]
def setup_module(module):
#global testdata
#do some steps
#based on if the server has issues or server mac is different,
# return testdata which may or may not remove one or both list from test data(modified testdata)
def teardown_module(module):
#close ssh connection
@pytest.mark.parametrize('servername, servermac, vlan', testdata)
def test_function(servername, servermac, vlans):
for vlans in vlans:
do ssh to servername:
#do things
В любом случае для динамической параметризации тестовых данных в test_function.
Я пробовал :
a) С текущим кодом, даже если setup_module удаляет один список из тестовых данных, поскольку мой тестовый пример параметризуется с помощью testdata глобально, который имеет два списка, тестовые примеры выполняются дважды для одного списка в testdata. Я читал из других вопросов, что это невозможно в соответствии со структурой pytest.
б) Если я попробую приспособление, выполнив что-то вроде :
testdata = [['servername_1', 'servermac_1', 'vlans'],['servername_2', 'servermac_2', 'vlans']]
@pytest.fixture
def setup():
#do some steps
#based on if the server has issues or server mac is different,
# return testdata which may or may not remove one or both list from test data
def teardown_module(module):
#close ssh connection
def test_function(setup):
testdata = setup
for test in testdata:
servername = test[0]
servermac = test[1]
vlans = test[2]
for vlans in vlans:
do ssh to servername:
#do things
При такой структуре кода pytest не учитывает, что это было два набора тестовых примеров, а только один набор случаев. Кроме того, я не могу использовать assert здесь, поскольку, если что-то не удается для 1-го имени сервера, и если я утверждаю, что оно равно false, код вообще не будет выполняться для 2-го имени сервера.
Может кто-нибудь, пожалуйста, подсказать, делаю ли я здесь что-то не так. Приносим извинения, если не следовали рекомендациям по вопросам, поскольку здесь впервые задается вопрос.
Комментарии:
1. Известна ли необходимая информация во
setup_module
время загрузки или только позже? В первом случае вы могли бы просто вызвать функцию в своем модуле напрямую.2. Set up имеет множество вызовов API, которые запускаются после запуска запуска. Я попытался вызвать setup_module или другую функцию, но у меня это не сработало. Он идентифицировал 3 тестовых примера вместо 2.
3. Я добавил ответ для этого случая, пожалуйста, проверьте, работает ли он для вас.
4. Спасибо за ответ. Я попробовал код, который вы мне дали. Это работает для меня, но отчасти частично. Причина, по которой я говорю это, заключается в том, что она предоставляет мне тестовые функции, как вы предложили, но когда я изменил свою переменную testdata в параметре setup_testdata(), это изменение не было отражено в параметризации. Он принимал только значение переменной testdata, объявленное глобально. Кроме того, если в setup_testdata(), если я изменяю тестовые данные, удаляя vlan и какой-либо другой параметр, он все равно показывает vlan, что означает, что изменения не отражаются в параметризации. Я делаю что-то не так, ожидая этого
5. Извините, мой плохой — вы правы, это не работает, потому
setup_testdata
что вызывается слишком поздно. Обновит ответ…
Ответ №1:
Если вы не знаете тестовые наборы во время загрузки, вы можете параметризовать свою функцию во pytest_generate_tests
время выполнения. Чтобы иметь возможность устанавливать тестовые данные до этого, вы должны использовать перехват инициализации, который выполняется раньше pytest_generate_tests
, например pytest_configure
(который должен быть помещен в a conftest.py
). Вот возможная реализация:
conftest.py
def pytest_configure(config):
# save the testdata in the config, so you can access it from the hook
config.testdata = calculate_testdata()
test.py
def teardown_module(module):
# close ssh connection
@pytest.hookimpl
def pytest_generate_tests(metafunc):
if all([name in metafunc.fixturenames
for name in ("servername", "servermac", "vlans")]):
metafunc.parametrize(("servername", "servermac", "vlans"),
metafunc.config.testdata)
def test_function(servername, servermac, vlans):
...
В случае вашего примера testdata это приведет к созданию тестовых функций:
test.py::test_function[servername_1-servermac_1-vlans]
test.py::test_function[servername_2-servermac_2-vlans]