[py-dev] optionally considering setup (needsdb usecase)

Floris Bruynooghe flub at devork.be
Mon Aug 6 22:55:28 CEST 2012


On 6 August 2012 08:50, holger krekel <holger at merlinux.eu> wrote:
> On Sun, Aug 05, 2012 at 17:14 +0200, Floris Bruynooghe wrote:
>> On 4 August 2012 14:13, holger krekel <holger at merlinux.eu> wrote:
>> > On Sat, Jun 30, 2012 at 12:26 +0100, Floris Bruynooghe wrote:
>> >> As an aside however, one of my usecases for merged request/item
>> >> objects was so I could put setup in a session-wide scoped funcarg but
>> >> also automatically request this funcarg based on a mark::
>> >>
>> >>    def pytest_runtest_setup(item):
>> >>        if 'needsdb' in item.keywords:  # or a more explicit API
>> >>           item.getresource('db')
>> >>
>> >> I understand that this will still be possible via::
>> >>
>> >>    def pytest_runtest_setup(item):
>> >>        if 'needsdb' in item.keywords:
>> >>            item.session.getresource('db')
>> >>
>> >> Or something similar to that.
>> >
>> > With the current @setup API this is not possible but it should be.  I'd like
>> > to understand the exact use case a bit.  What do you do with the "db"
>> > object here?  I guess you cause side effects because you would otherwise
>> > just request a funcarg in the tests, right?
>>
>> Actually there is no side effect here.  This was born out of Andreas
>> Pelme's desire to be able to mark tests with a marker while trying to
>> re-use the session-wide caching that funcargs gave us.  But the new
>> @setup already covers this case completely since it can handle the
>> caching just fine.  But I still think this is a nice use-case, since
>> it would allow being able to use the same setup and request it with
>> either a funcargs or a mark.
>
> But if you request it with a mark, we are talking about side effects, aren't we?
> (I'd define "side-effects" as something that doesn't inject a test
> dependency directly to a test).

Yes, I guess so.

>> > If so, then i can imagine the following solution:
>> >
>> >     @pytest.setup(enabled=myhelper)
>> >     def perform_side_effect_with(db):
>> >         ...
>> >
>> > The "enabled" helper would be called during collection so that
>> > pytest gets to know which tests will actually execute the setup
>> > function and its (potentially parametrized) required resources.
>> > It could look like this::
>> >
>> >     def myhelper(collectioncontext):
>> >         return "needsdb" in collectioncontext.markers:
>> >
>> > and collectioncontext also carries module/class/function (depending on
>> > the scope specified with the setup).  If the helper returns True then
>> > the setup is considered and thus receives the DB object.  Do you
>> > think this would solve your use case? (Collectioncontext would not
>> > have a addfinalizer() and might in the future offer more collection-specific
>> > things).
>>
>> This does sound like a very neat solution indeed, I think this would
>> be a good addition.
>
> OK, i'll see to implement it but i guess it wouldn't be too bad to do
> it after a pytest-2.3 release, unless there is a concrete need already.

This would still make the dual setup triggered by mark/resource easier
by e.g. (I'm just using some pseudo-api here):

@pytest.funcarg
def db():
     print 'setting up db'

def helper(collectioncontext):
    if 'needsdb' in collectioncontect.markers

@pytest.setup(enabled=helper)
def dbsetup(db):
    pass

Here the funcarg can do all the work.  But this is not a deal-breaker,
since you can also do this:

def setupdb():
    print 'idempotent db setup'

@pytest.funcarg():
def db():
    setupdb()

@pytest.setup
def marksetup(testcontext):
    if 'needsdb' in testcontext.markers:
        setupdb()

So leaving this till later is fine.

> Btw,  if you can find some time sometime to look at a) test
> pytest-django with pytest-trunk  b) port pytest-django to pytest-trunk
> features, that would be super-helpful.  My personal target for a release
> is end august but not before some more real-world beta usages have happened.

I'll try to have a go at this in the next week or two as I think it
would be very good exercise as well.


Regards,
Floris



More information about the Pytest-dev mailing list