Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nose ignores test with custom decorator

I have some relatively complex integration tests in my Python code. I simplified them greatly with a custom decorator and I'm really happy with the result. Here's a simple example of what my decorator looks like:

def specialTest(fn):

    def wrapTest(self):
        #do some some important stuff
        pass
    return wrapTest

Here's what a test may look like:

class Test_special_stuff(unittest.TestCase):

    @specialTest
    def test_something_special(self):
        pass

This works great and is executed by PyCharm's test runner without a problem. However, when I run a test from the commandline using Nose, it skips any test with the @specialTest decorator. I have tried to name the decorator as testSpecial, so it matches default rules, but then my FN parameter doesn't get passed.

How can I get Nose to execute those test methods and treat the decorator as it is intended?


SOLUTION

Thanks to madjar, I got this working by restructuring my code to look like this, using functools.wraps and changing the name of the wrapper:

from functools import wraps

def specialTest(fn):

    @wraps(fn)
    def test_wrapper(self,*args,**kwargs):
        #do some some important stuff
        pass
    return test_wrapper


class Test_special_stuff(unittest.TestCase):

    @specialTest
    def test_something_special(self):
        pass
like image 704
Corey Coogan Avatar asked Oct 11 '11 14:10

Corey Coogan


1 Answers

If I remember correctly, nose loads the test based on their names (functions whose name begins with test_). In the snippet you posted, you do not copy the __name__ attribute of the function in your wrapper function, so the name of the function returned is wrapTest and nose decides it's not a test.

An easy way to copy the attributes of the function to the new one is to used functools.wraps.

like image 128
madjar Avatar answered Oct 04 '22 11:10

madjar