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

Elizabeth Lin elin at splunk.com
Fri Apr 5 10:08:26 PDT 2013


Hi Holger,

Thanks for responding! Comments inline below.

On 4/4/13 11:14 PM, "holger krekel" <holger at merlinux.eu> wrote:

>Hi Elizabeth,
>
>And sorry for taking a while but i am still not sure i fully understand.
>I am pretty sure we can find a solution but i'd like to find one that
>fits the problem :)
>
>Could you clarify your problem purely from the test function side?
>Particularly, if you have this test:
>
>    @params([
>        ['color', 'type'],
>        { 'argvalues': [ 'blue', 'cat'] },
>        { 'argvalues': ['pink', 'dog'] }
>    ])
>    def test_example(myfixture, color, type):
>        # this is the new test we want to add
>        assert 0
>
>do i understand it right that ``myfixture`` should be indirectly
>created by using ["std", "pro"] as respective parameters because
>there is a @params decorator? And that for

Yes, myfixture should be indirectly created when we call
metafunc.parametrize to pass in ["std", "pro"] as parameters, but only for
specific tests - in this case the tests generated should be:
- std, blue, cat
- std, pink, dog
- pro, blue, cat
- pro, pink dog

>
>    def test_something(myfixture):
>        # existing test which only uses std fixture
>        assert 0
>
>you only want ``myfixture`` created with the "std" parameter?

Yes, that's correct.  So only test should be
- std

>
>And that for:
>
>    @params([
>        {'arg1': 1, 'arg2': 2},
>        {'arg1': 3, 'arg2': 5}
>    ])
>    def test_old_style(arg1, arg2):
>        # existing tests which don't use fixtures
>        assert 0
>
>you don't want any "myfixture" created at all?

Also correct.  Generated tests should be
- 1, 2
- 3, 5

Cheers,
Liz

>
>
>cheers,
>holger
>
>
>
>On Thu, Apr 04, 2013 at 22:51 +0000, Elizabeth Lin wrote:
>
>> 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
>> 
>> 
>> 
>> 
>> _______________________________________________
>> testing-in-python mailing list
>> testing-in-python at lists.idyll.org
>> http://lists.idyll.org/listinfo/testing-in-python
>> 




More information about the testing-in-python mailing list