[py-dev] Decorators and funcargs in py.test

Vyacheslav Rafalskiy rafalskiy at gmail.com
Wed Jun 1 18:31:06 CEST 2011


Gentlemen!

Thanks for your input. I really appreciate it.

@Ronny
1. I do agree that creating a new data convention is a big deal.
What I tried to suggest is using something that already exists in
_pytest.core.varnames(). A comment in _pytest.python.getfuncargnames()
indicates that the two functions may merge. If they do, and towards
the former, my original suggestion will *just work*.

2. Using decorators is a great deal for me. They are powerful and
expressive. I understand however the reluctance to open a can of worms
here. The replacement using pytest.mark below seems acceptable to me.
It still uses the same decorator function, just at a different place.

@Holger, Ronny
Here is what I came up with:

#---------->>  in test_1.py
@pytest.mark.timeout(10)
def test_f1():
    # test here

#---------->>  in conftest.py
def pytest_runtest_call(item):
    if hasattr(item.obj, 'timeout'):
        timeout = item.obj.timeout.args[0]
        item.obj = run_with_timeout(timeout)(item.obj)

Your comments are welcome.

Regards,
Vyacheslav

On Wed, Jun 1, 2011 at 3:49 AM, holger krekel <holger at merlinux.eu> wrote:
> Hi Vyacheslav, hi Ronny,
>
> On Mon, May 30, 2011 at 22:38 +0200, Ronny Pfannschmidt wrote:
>> On Mon, 2011-05-30 at 16:23 -0400, Vyacheslav Rafalskiy wrote:
>> > No problem. Here is my (real life) example.
>> >
>> > My functional test functions may or may not return for different
>> > reasons (like a faulty web application or middleware). I want to
>> > declare a fail if it takes more than so many seconds to complete. So I
>> > write a decorator
>> > run_with_timeout(), which will start the function in a new thread and
>> > abandon it after timeout.
>>
>> This can easily be solved by combining something like
>> pytest.mark('timeout') and a override to pytest_pyfunc_call using it
>
> I agree.
>
> Vyacheslav, if you can't make sense of the "use pytest.mark()" and
> provide-a-hook suggestion, one of us will be certainly be happy to
> provide a more complete example and add it to the docs.
>
>> i suppose this could also take a look at extending the "--boxed" mode
>> (which forks for each test and uses subprocesses but doesn’t handle
>> timeouts atm.
>
> this is part of the pytest-xdist plugin, however.  Question is,
> if we shouldn't eventually grow timeout-support in core pytest
> through "alarm" or so.
>
> best,
> holger
>
>> >
>> > A I stated in OP, it is not that I cannot do it. I can and I do. My
>> > point is that it makes sense to allow decorators and should not be
>> > very difficult (see the example in OP).
>>
>> personally i am opposed to creating new data conventions for problems
>> that can be solved with plain marks + a hook
>>
>> usually there are 2 reasons people use to decorate tests
>>
>> my opinions for implementing those are
>> a) add arguments + their cleanups -> funcargs please, they are made for
>> that
>> b) use more sophisticated call's -> hooks please, maybe add a bug ticket
>> for empowering one to return a exception-info, so stuff like
>> thread-wrappers can pass that more nicely for failures
>>
>> *i* really think it is wrong to decorate test functions that way and
>> expect stuff to work
>>
>> there are already plenty of mechanisms to change the behavior of pytest
>> test function calling in the desired way, none of those require hacks to
>> pass around argspecs
>>
>> -- Ronny
>> >
>> > Thanks,
>> > Vyacheslav
>> >
>> > On Mon, May 30, 2011 at 3:55 PM, Ronny Pfannschmidt
>> > <Ronny.Pfannschmidt at gmx.de> wrote:
>> > > Hi,
>> > >
>> > > can you try to explain the usecase those decorators are fulfilling,
>> > >
>> > > there may be a better integrated way using pytest.mark + setup/teardown
>> > > hooks
>> > >
>> > > -- Ronny
>> > >
>> > > On Mon, 2011-05-30 at 15:17 -0400, Vyacheslav Rafalskiy wrote:
>> > >> Hi Holger,
>> > >>
>> > >> I am trying to make decorators work with test functions, which depend
>> > >> on funcargs. As it stands, they don't.
>> > >> Decorated functions lose funcargs. A workaround would be to decorate
>> > >> an internal function like this:
>> > >>
>> > >> def test_it(funcarg_it):
>> > >>     @decorate_it
>> > >>     def _test_it():
>> > >>         # test it
>> > >>
>> > >>     _test_it()
>> > >>
>> > >> This works, but it is not nice. I'd rather wrote a decorator like
>> > >>
>> > >> def decorate_it(f):
>> > >>     def _wrap_it(*args, **kwargs):
>> > >>         # wrap f() here
>> > >>
>> > >>     _wrap_it._varnames = _pytest.core.varnames(f)
>> > >>     return _wrap_it
>> > >>
>> > >> and apply it straight to the test function.
>> > >>
>> > >> After examining the source code I even expected it to just work
>> > >> (magically of course) but it didn't.
>> > >> Do you think it is worthwhile? If so I can enter a feature request.
>> > >>
>> > >> Thanks,
>> > >> Vyacheslav
>> > >> _______________________________________________
>> > >> 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
>
>



More information about the Pytest-dev mailing list