... Aargh, forgot to reply to list...
-----Original Message-----
From: Florian Bauer 
Sent: Mittwoch, 1. September 2010 16:55
To: holger krekel
Subject: RE: [py-dev] py.test doesn't like functools.partial wrappers

Hi Holger, 

> -----Original Message-----
> From: holger krekel [mailto:hol...@merlinux.eu]
> 
> On Fri, Aug 20, 2010 at 15:49 +0200, Florian Bauer wrote:
> > Hi all,
> > 
> > I'm trying to make an existing testsuite py.test compatible.
> > At the moment, we use nose as test runner. I stumbled upon the 
> > following (simplified example).
> >  
> > from functools import partial
> >  
> > def forall_cases(cases):
> >     def decorate(testfn):
> >         def gen():
> >             for case in cases:
> >                 description = case[0]
> >                 args = case[1:]
> >                 func = partial(testfn, *args)
> >                 func.description = description
> >                 yield func,
> >         gen.__name__= 'test_%s_' % testfn.__name__ 
> >         #
> >         # inject the generator into the module testfn came from
> >         #
> >         gen.__module__ = testfn.__module__
> >         return gen
> >     return decorate
> >  
> > 
> > @forall_cases([['case1', 1, 1], ['case2', 2, 2],['case3',
> 3, 4]]) def
> > test_equal(a, b):
> >     assert a == b
> 
> Hum, is it an option to rather use a different decorator that makes 
> use of py.test's more general parametrized testing feature?
> See here:
 
Yes, definetely. I would like to leave this decorator untouched for now
(keeping nose working), and would be quite happy to have py.test using a
different decorator implementation. I will try this!

>     
> http://tetamap.wordpress.com/2009/05/13/parametrizing-python-t
> ests-generalized/
> 
> for some general examples.   In your case you would need to 
> 1) define @forallcases as a simple marker, e.g.:
>     forallcases = py.test.mark.forallcases
> 
> 2) implement a pytest_generate_tests hooks that checks for the 
> "forallcases"
>    decorator and generates the test function invocations. 
> 
> The second part can just live in a conftest.py file and does not 
> conflict with the nose-way of running tests.
> 
> For the first you could try to just do something like
> 
>     def pytest_configure(config):
>         import module_that_contains_forallcases
>         module_that_contains_forallcases.forallcases = 
> py.test.mark.forallcases
> 
> If the latter lives in a conftest.py file at the root of your project 
> or at the root of all test modules it should be executed before any 
> test module is imported (which might import and use the forallcases 
> decorator).

I will play around with this, thanks!
 
> > If I run this with nosetests, I get 3 test cases, 2 pass and 1 fail.
> > 
> > py.test tries to call inspect.getsource on the partial
> object, which
> > results in a TypeError:
> > 
> > $ py.test -v
> > ...
> > INTERNALERROR>
> > INTERNALERROR> object = <functools.partial object at 0x00F019C0>
> > INTERNALERROR>
> > INTERNALERROR>     def getfile(object):
> > INTERNALERROR>         """Work out which source or compiled file an 
> > INTERNALERROR> object was d
> > efined in."""
> 
> Can you post or attach a full traceback? 
> I agree that a) it would be nice if nose and py.test would be more 
> compatible here b) the error is obscure.  OTOH i consider yield-based 
> parametrization as a kind of dead-end.
> It certainly causes a more complex implementation for the testing 
> machinery and can not provide features/reporting as cleanly as the 
> above mentioned parametrized testing.

I attached a full traceback. I agree with you on the yield
based-parametrization. That's why I would like to move away from it and
am experimenting with py.test. My secret goal is to implement something
like Haskell's quickcheck. Generation of random test data is the easy
part. The fun begins when you start to think about the different
reporting needs a test might have in that case ('generated 10000 test
cases, 97% pass, 14% trivial' for example). But first I have to migrate
the current test suite...

> > Is there a conditional flag that can tell me whether I'm
> running under
> > py.test? Then I could start experimenting with parametric
> tests using
> > funcargs, while keeping the test suite runnable with nose
> at the moment.
> > I still have a bug in the test suite, as I have tests
> passing under nose
> > that fail under py.test...
> 
> There is no official way to detect if code is running within a test 
> session.
> You might do something like:
> 
>     # contents of conftest.py 
>     def pytest_configure(config):
>         import some_app_module
>         some_app_module._testing = True
> 
> and then do a "hasattr(some_app_module, '_testing')" check or so. 
> However, most people don't consider it good practise to have 
> application
> level code become aware if it's being tested or not.   Instead 
> people use monkeypatching or dependency-injection to modify app 
> behaviour.

My use case was actually to check in my test suite whether it's running
under nose or under py.test. 
I think your (and Ronny's) suggestion to use the conftest mechanism
provides a much cleaner solution.

Thanks,
Florian

_______________________________________________________________________________________

Dialog Semiconductor GmbH
Neue Str. 95
D-73230 Kirchheim
Managing Director: Dr. Jalal Bagherli
Chairman of the Supervisory Board: Gregorio Reyes
Commercial register: Amtsgericht Stuttgart: HRB 231181
UST-ID-Nr. DE 811121668


Legal Disclaimer: This e-mail communication (and any attachment/s) is 
confidential and 
contains proprietary information, some or all of which may be legally 
privileged. It is 
intended solely for the use of the individual or entity to which it is 
addressed. Access 
to this email by anyone else is unauthorized. If you are not the intended 
recipient, any
disclosure, copying, distribution or any action taken or omitted to be taken in 
reliance
on it, is prohibited and may be unlawful.

Attachment: traceback
Description: traceback

_______________________________________________
py-dev mailing list
py-dev@codespeak.net
http://codespeak.net/mailman/listinfo/py-dev

Reply via email to