... 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.
traceback
Description: traceback
_______________________________________________ py-dev mailing list py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev