[py-dev] RFC: V2 of the new resource setup/parametrization facilities

Floris Bruynooghe flub at devork.be
Sat Jun 30 13:26:05 CEST 2012

On Sat, Jun 30, 2012 at 08:08:41AM +0000, holger krekel wrote:
> On Sat, Jun 30, 2012 at 01:23 +0100, Floris Bruynooghe wrote:
> > On Fri, Jun 29, 2012 at 10:55:23AM +0000, holger krekel wrote:
> previously, the scope-mismatch could happen as well and go unnoticed::
>     def pytest_funcarg__Y(request):
>         return request.function.__name__
>     def pytest_funcarg__X(request):
>         def setup():
>             return request.getfuncargvalue("Y")
>         return request.cached_setup(setup, scope="session")
> The result will depend on which test function is first requested.
> In the future, we might want to try raise a ScopeMismatchError here
> as well.

Oh, never noticed this.  That's an improvement then.

> > The previous resource/funcarg split avoided this confusion.
> a) What about just naming it "cachescope"?

Maybe.  I wouldn't take my word for it that just "scope" is not
sufficient, see what other people say.  I'd probably get annoyed at
the extra typing for cachescope after a while, maybe even
@pytest.mark.factory(cache="session") is an option?  It would avoid
having two things called "scope".

> b) i moved register_factory/getresource to implementation details
>    not the least because Carl Meyer as a relatively recent pytest user
>    expressed his expectation of a consistent pytest_funcarg__ factory
>    story - and if we are going to anyway have to support the existing ones, 
>    i'd now like to focus on extending it and only go for a usage-level visible
>    paradigm change if it's really needed. Does this make general
>    sense to you?

Yes this does make sense, in general I do like this approach.

> > Lastly, when do scoped funcarg resources get invoked?  Only at the
> > time a test function requests it or always at the time when the scope
> > is entered?
> factories are invoked when a test function or one of its involved setup 
> methods needs it.  A scope is only "entered" if there is a test to be executed
> within it. Does this clarify?

It does.

> > > support for setup_session and setup_directory
> > > ------------------------------------------------------
> > [...]
> > >     # content of conftest.py
> > >     def setup_session(db):
> > >         ... use db resource or do some initial global init stuff
> > >         ... before any test is run.
> > >         
> > >     def setup_directory(db):
> > >         # called when the first test in the directory tree is about
> > > to execute
> > 
> > I think the naming of these functions break the py.test convention,
> > normally the only functions picked up from conftest.py start with
> > pytest_.  I can certainly imagine a conftest.py or plugin already
> > having a setup_session function.  These are new functions and do not
> > provide a compatibility API with other testing frameworks, so I think
> > they would be better named pytest_setup_session and
> > pytest_setup_directory.
> I think using pytest_* hooks also has consistency problems:
> * hooks cannot usually receive arbitrary funcargs

This is why a signature with a request/node for these might be better::

   def pytest_setup_session(session):
       session.getresource('db')  # or .getfuncargvalue()?

> * xUnit-style consistency: consider explaining the new functions
>   to someone only knowing setup_module/ class etc.

As I tried to say before, they do not come for xUnit so I don't think
this is too important.  I think the consistency inside conftest.py is
more important.

> I am wondering, however, do we even need a "setup_session"? setup_directory
> should usually be enough, i guess, and it's more unlikely people used
> that name already (and we could warn about setup_session in 2.X to
> reserve introducing it in 2.X+1).

Maybe not, but if you don't provide setup_session (or
pytest_setup_session) then pytest_sessionstart will be used again
when someone thinks of a reason to use it.  And that's what you wanted
to avoid.

> And what what about putting setup_directory into an __init__.py file?
> I don't really like requiring __init__ files, but am fine to go with it if
> you and others prefer that.  I would guess, that using the already 
> directory-scoped conftest.py file feels fine to someone coming new to pytest.

I agree, requiring __init__.py is worse then just putting it in
conftest.py.  I think it would be best if it fits inside conftest.py.

> If a setup-function has no body, then tests could just require it themselves
> and that'd be enough.  If there is a need, we could introduce a marker for 
> requiring funcarg-resources such that tests do not need to require it 
> in their signature.

I'm not sure what that would save, either the test function must
request the resource or must be marked to need the resource.  If
anything the second takes more work.

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

I understand that this will still be possible via::

   def pytest_runtest_setup(item):
       if 'needsdb' in item.keywords:

Or something similar to that.


Debian GNU/Linux -- The Power of Freedom
www.debian.org | www.gnu.org | www.kernel.org

More information about the Pytest-dev mailing list