Was introduced to an interesting problem today when decorating tests that need to be discovered by the nose runner. By default, nose explores a directory looking for things named test or tests and then executes those functions, classes, modules, etc. as tests. A standard test suite for me looks something like:

import unittest


class MyTests(unittest.TestCase):

    def test_undecorated(self):
        """
        assert undecorated works
        """
        self.assertEqual(2+2, 4)

The problem came up when we wanted to decorate a test with some extra functionality, for example loading a fixture:

def load_fixture(func):
    def wrapper(*args, **kwargs):
        # Load a fixture
        return func(*args, **kwargs)
    return wrapper


class MyTests(unittest.TestCase):

    @load_fixture
    def test_decorated(self):
        """
        assert a decorated test works
        """
        self.assertEqual(2+2, 4)

The key to remember is that you must wrap the function so that the name and docstring are added to the internal wrapper, thus allowing the nose test discovery function to work:

from functools import wraps

def load_fixture(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        # Load a fixture
        return func(*args, **kwargs)

    return wrapper

Thanks to @ndanielsen for pointing this out, it’s going to save me a bit of trouble in the future, I expect.