Take the 2-minute tour ×

I'm using nose for testing. I know how to skip test, but I was wondering if there's an easy solution to write a decorator to skip tests, when some module is not imported.

Right now I try to import mock and catch the ImportError if it isn't installed and set mock = None. At the start of tests that require mock I use if not mock: raise SkipTest() as the 1st line.

That works alright. I'm just wondering if it's also possible with a decorator. I've tried to write one for some time... after figuring out the thing with __name__ I thought i got it. But then I noticed, that all my test using that decorator pass no matter what.


I've been using Using kindall's answer for some time, just to notice today, that it still doesn't work right (at least not in all cases)!

It seems to work, when I use a test function, that is not a generator (contains no yield statement). Whenever I use the decorator on a test function that uses yield, the test passes no whatter what assert fails in the yielded function.

share|improve this question
Yes, functools.wraps() sets __name__ and other attributes such as __doc__, so if you want to do it without functools that's the way. –  kindall Mar 27 '12 at 14:32
Your update is an answer, if you want you can put it among them, but it doesn't belong in your question. If you'll do it your question will be more clear. –  Rik Poggi Mar 29 '12 at 9:06

3 Answers 3

up vote 4 down vote accepted

Wouldn't something like this work?

import functools

def requires_mock(test):

    def wrapper():
        if mock:
            return test()
        raise SkipTest

    return wrapper
share|improve this answer

The decorator should look like so:

def needsMock(fn):
    def wrapped():
        if mock is None: return


    return wrapped

This makes the test pass when mock is None. You can also try to raise the SkipTest() but that might interfere with decorators.

share|improve this answer
No luck with this one: no errors but the test won't run. I guess nose couldn't find it because it's name didn't match the RegEx ((?:^|[b_.-])[Tt]est)). –  Brutus Mar 27 '12 at 9:33
The name of the decorator is irrelevant - nose runs it without noticing that it's there. Add a couple of println or run the code in a debugger to see where/why it fails. –  Aaron Digulla Mar 27 '12 at 16:39

Inspired by kindall's answer (which works) I tried to get it to work without functools again:

def requires_mock(test):

    def wrapper(*args, **kwargs):
      if mock_not_available:
        raise SkipTest()
        return test(*args, **kwargs)

    wrapper.__name__ = test.__name__
    return wrapper

It seems to works too. The __name__ thing is important so that nose recognize the function and marks it on verbose test runs accordingly.

I hope I didn't miss anything? Loosing faith in you test is a sad thing :(

share|improve this answer

Your Answer


