[py-dev] parametrized resources (Re: Generic funcarg hook)

Michael Foord fuzzyman at voidspace.org.uk
Fri Aug 13 16:28:54 CEST 2010


On 10/08/2010 11:10, holger krekel wrote:
> Hi Floris, all,
>
> On Tue, Aug 10, 2010 at 11:01 +0200, holger krekel wrote:
>    
>> FYI, i am considering introducing a slightly higher level
>> mechanism on top of funcargs, dealing with (parametrizable)
>> resources.  Something like:
>>
>> @py.test.mark.resourcefactory(scope="session", argnames=['foo', 'bar'])
>> def myfactory(request):
>>      if request.argname == "foo":
>>          ...
>>      elif request.argname == "bar":
>>          ...
>>
>> The request object would be what pytest_funcarg__NAME get but
>> this would allow free naming and have a single factory become
>> responsible for multiple funcargs and allow to declare scope
>> reather than having to invoke request.cached_setup().  Instead
>> of the latter, one could write "request.addfinalizer()" which
>> would default to the declared scope.
>>      
> just to be clear, the test function would look like:
>
>      def test_function(foo):
>          ... foo is initialized per-session, created per the factory above
>
>      def test_function2(foo, bar):
>          ... foo and bare are created by two invocations to the factory above
>
> Moreover, regarding the "parametrized resources" aspect,
> there would be a new decorator:
>
>      @py.test.mark.parametrize(foo=iterable)
>      def test_function(foo):
>          ... invoked for multiple foo instances
>
> The idea is to be able to avoid pytest_generate_tests functions
> in a number of cases.
>
>    

Hey all,

For unittest(2) there is an implementation of parametrized tests that 
already exists as a plugin.

     
http://hg.python.org/unittest2/file/tip/unittest2/plugins/moduleloading.py

The decorator form is basically identical to the suggested form above:

     from unittest2.plugins.moduleloading import params

     @params(iterable)
     def test_function(arg1, arg2, arg3):
         ...

test_function will be expanded into one test per member in iterable at 
test load time.

This is all experimental, i.e. we don't know yet if any of this will 
come into core unittest or live as a plugin forever. The plugin also 
supports test generators, but unlike test generators in nose these are 
expanded at test *load* time rather than test execution time. They are 
supported at the moment because a lot of the people really like the 
generator syntax for creating tests.

     from unittest2.plugins.moduleloading import testGenerator

     @ testGenerator
     def test_function():
         for value in range(5):
             yield other_function, (value,)

All the best,

Michael


> Both the current funcarg-mechanism and the generate-tests mechanism
> would continue to exist but be considered "lower level", i.e. upcoming
> examples on the web page would use the new more declarative approach,
> requiring less API knowledge and naming freedom to use them.
>
> any comments and particularly real use cases very welcome!
>
> best,
> holger
>
>    
>> Happy about any thoughts on this but mainly i mention this
>> consideration here in case it would fit with your use case.
>>
>> best,
>> holger
>>
>>
>> On Sat, Aug 07, 2010 at 10:52 +0100, Floris Bruynooghe wrote:
>>      
>>> Hi
>>>
>>> I was talking to ronny on IRC about wanting a generic funcarg hook and
>>> he asked me to post my use case here as you are still thinking about
>>> the API for it.  Since there is no generic funcarg hook now this is
>>> how I currently create the tests:
>>>
>>>
>>> def pytest_funcarg__tdata(request):
>>>      fname = os.path.join(DATADIR, requst.function.__name__+'.ext')
>>>      with file(fname) as fd:
>>>          obj = fd.read()
>>>      return obj
>>>
>>> def test_spam(tdata):
>>>      assert func_under_test(tdata) == 'foo'
>>>
>>> def test_eggs(tdata):
>>>      assert func_under_test(tdata) == 'bar'
>>>
>>>
>>> Before I started writing it this way I was looking for a generic
>>> funcarg hook since I think this would have been clearer if I could
>>> have used "spam" and "eggs" as funcargs and still create the object
>>> for them from one function rather then having to spell it out for each
>>> one.  So I'm hoping that in a future version you might add an API to
>>> do allow something like this.
>>>
>>> -- 
>>> Debian GNU/Linux -- The Power of Freedom
>>> www.debian.org | www.gnu.org | www.kernel.org
>>> _______________________________________________
>>> py-dev mailing list
>>> py-dev at codespeak.net
>>> http://codespeak.net/mailman/listinfo/py-dev
>>>
>>>        
>> -- 
>> _______________________________________________
>> py-dev mailing list
>> py-dev at codespeak.net
>> http://codespeak.net/mailman/listinfo/py-dev
>>
>>      
>    


-- 
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog

READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pytest-dev/attachments/20100813/fbd4f08e/attachment.html>


More information about the Pytest-dev mailing list