decorators don't play nice with nose?

2009-04-06 Thread hyperboreean
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?
Thanks!

--
http://mail.python.org/mailman/listinfo/python-list


Re: decorators don't play nice with nose?

2009-04-06 Thread J Kenneth King
hyperboreean hyperbore...@nerdshack.com writes:

 From: hyperboreean hyperbore...@nerdshack.com
 Subject: decorators don't play nice with nose?
 Newsgroups: comp.lang.python
 To: python-list@python.org
 Date: Mon, 06 Apr 2009 11:01:04 +0300

 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):

FWIW, nose and unittest both provide methods for setting up and
tearing down tests. You should probably look at those first before
rolling your own. At the very least it will give you an idea of how
yours should work.

Cheers
--
http://mail.python.org/mailman/listinfo/python-list


Re: decorators don't play nice with nose?

2009-04-06 Thread Diez B. Roggisch

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
--
http://mail.python.org/mailman/listinfo/python-list


Re: decorators don't play nice with nose?

2009-04-06 Thread Michele Simionato
On Apr 6, 11:11 pm, Diez B. Roggisch de...@nospam.web.de wrote:
 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

Or you can use the decorator module: http://pypi.python.org/pypi/decorator
--
http://mail.python.org/mailman/listinfo/python-list