[TIP] pytest - parametrizing some arguments require parametrization at collection phase and some at setup time?

Elizabeth Lin elin at splunk.com
Thu Apr 4 15:51:15 PDT 2013


Hi, 

I have some tests which I'd like to parametrize using both more complex
fixtures as well as simple string arguments.  How are folks doing this
currently?  Or is this a use case that hasn't been seen before?  Using
metafunc.parametrize in a pytest_generate_test hook won't work for me
since I need the fixtures to have indirect=True to pass the argname as a
request.param, but the other arguments to have indirect=False.

For example, if I have a test fixture and test case which looks like the
following:
Any suggestions for how to accomplish this would be much appreciated!


def pytest_generate_tests(metafunc):
	if metafunc.function.__name__ == 'test_example':
        	argnames = []
        	argvalues = []
		parameters = getattr(metafunc.function, 'paramlist', ())
		for p in parameters:
			if type(p) == list:
				argnames = tuple(['myfixture'] + p)
			else:
				argvalues.append = tuple(['std'] + p['argvalues'])
				argvalues.append = tuple(['pro'] + p['argvalues'])
		# I want to do the following, but it won't work since some of the
		# args need indirect set to true
		# and some need indirect set to false.
		metafunc.parametrize(argnames, argvalues, indirect=True)
	elif 'myfixture' in metafunc.fixturenames:
		# we have existing tests which use the fixture, but only with std
		metafunc.parametrize("myfixture", "std")
	else:
		# we have existing tests which use older style parametrization,
		# non-fixture
		for p in getattr(metafunc.function, 'paramlist', ()):
			metafunc.addcall(funcargs=p)


def params(decolist):
	def wrapper(function):
		function.paramlist = decolist
		return function
	return wrapper

@pytest.fixture
def myfixture(request):
	if request.param == 'std':
		myfix = SomeObject()
	elif request.param == 'pro':
		myfix = SomeOtherObject()
	def fin():
		myfix.close()
	request.addfinalizer(fin)
	return myfix

@params([
    ['color', 'type'],
    { 'argvalues': [ 'blue', 'cat'] },
    { 'argvalues': ['pink', 'dog'] }
])
def test_example(myfixture, color, type):
    # this is the new test we want to add

def test_something(myfixture):
    # existing test which only uses std fixture

@params([
    {'arg1': 1, 'arg2': 2},
    {'arg1': 3, 'arg2': 5}
])
def test_old_style(arg1, arg2):
    # existing tests which don't use fixtures


Thanks for reading through this! I know it's rather long.

Cheers,
Liz






More information about the testing-in-python mailing list