decorators don't play nice with nose?
Diez B. Roggisch
deets at nospam.web.de
Mon Apr 6 17:11:08 EDT 2009
hyperboreean schrieb:
> Hi, I am trying to test the business part of a web service. For this I
> am using unittest & nose.
> I wrote a decorator that should handle the xml test file retrieval, but
> it seems I can't get it working with nose.
> Here's the code:
>
>
> * MyApp.py -- base test class *
>
> import os
> import unittest
>
> from MyApp.Core import XmlParser
>
>
> __all__ = ['MyAppTest', 'setup']
>
>
> PATH = os.path.dirname(__file__) or ''
>
>
> class setup(object):
> """Decorator to ease the use of xml files in MyApp tests.
>
> The way it works it that it decorates a test method which has a first
> default parameter called 'parser' and it overwrites this parameter value
> with a XmlParser instance.
>
> The xml file should be located under:
> data/testedBusinessRequest/testMethodName.xml
> """
> def __init__(self, testedBusinessRequest = ''):
> self.testedBusinessRequest =\
> testedBusinessRequest.lower()
>
>
> def _getXmlParser(self, xml):
> documentElement = XmlParser.parseXmlStream(xml)
> parser = XmlParser.getParser(documentElement)
> return parser
>
>
> def __call__(self, method):
>
> # TODO: error handling here
> methodName = method.func_code.co_name
> methodName = methodName.split('_')[1]
>
> xmlFolder = self.testedBusinessRequest
> xmlFile = '%s.xml' % methodName
>
> path = os.path.join(PATH, 'data',
> xmlFolder, xmlFile)
>
> f = open(path)
> xml = f.read()
> f.close()
> method.func_defaults = (self._getXmlParser(xml),)
> return method
>
>
> class MyAppTest(unittest.TestCase):
>
> def setUp(self):
> self.database = Database()
>
> def tearDown(self):
> pass
>
>
> * test_Login.py - test a business request *
> from MyAppTest import MyAppTest, setup
>
> from MyApp import Login
>
>
> class TestLogin(MyAppTest):
> testedBusinessRequest = 'Login'
>
> @setup(testedBusinessRequest)
> def test_validParameters(self, parser = None):
> response = Login(self.database, parser).run()
> return True
>
>
>
> Ok, so the decorator setup should fill the parser parameter with a
> XmlParser object. This works well if I add a __main__ and use unittest
> to run the tests. But if I use nose, I get the following error:
>
> *TypeError: unbound method __call__() must be called with setup instance
> as first argument (got module instance instead)*
>
> Any advices?
Nose works via the func_name parameter of a method/function.
So when you decorate it, you need to make sure that is set properly. One
option is to do something like this:
from functools import wraps
def my_decorator(f):
@wraps(f)
def _d(*args, **kwargs):
return f(*args, **kwargs)
return _d
Diez
More information about the Python-list
mailing list