根据setup_module或其他函数的输出动态参数化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中动态参数化testdata。

我试过:

a( 对于当前的代码,即使setup_module从测试数据中删除了一个列表,由于我的测试用例是用testdata全局参数化的,它有两个列表,所以测试用例在testdata中为一个列表运行两次。我从其他问题中了解到,根据pytest结构,这是不可能的。

b( 如果我尝试这样的固定装置:

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,因为如果第一个servername出现故障,并且我将其断言为false,那么代码就根本不会为第二个servername运行。

如果我在这里做错了什么,有人能告诉我吗。由于第一次在这里发布问题,如果没有遵守问题指南,请道歉。

如果您在加载时不知道测试用例,则可以在运行时在pytest_generate_tests中参数化您的函数。为了能够在此之前设置测试数据,您必须使用在pytest_generate_tests之前执行的初始化挂钩,如pytest_configure(必须放入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()

测试.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):
...

在您的示例测试数据的情况下,这将生成测试函数:

test.py::test_function[servername_1-servermac_1-vlans] 
test.py::test_function[servername_2-servermac_2-vlans] 

最新更新