How do I write a decorator to skip certain tests when a module is not being imported?
I am using nose for testing. I know how to skip a test, but I was wondering if there is a simple solution for writing a decorator to skip tests when some module is not being imported.
I am currently trying to import the mock and catch ImportError
if it is not installed and installed mock = None
. At the beginning of tests that require mock, I use if not mock: raise SkipTest()
as the first line.
It works well. I'm just wondering if this is possible with a decorator too?
Update
I've been using the kind answer for some time now, just to notice today that it still doesn't work correctly (at least not all !
Seems to work when I use a test function that is not a generator (contains no instructions yield
). Whenever I use a decorator on a test function that uses yield
, though, the test passes regardless of whether assert
the resulting function fails .
Any ideas why this is happening and how to prevent this behavior?
Wouldn't it be like this job?
import functools
def requires_mock(test):
@functools.wraps(test)
def wrapper():
if mock:
return test()
raise SkipTest
return wrapper
The decorator should look like this:
def needsMock(fn):
def wrapped():
if mock is None: return
fn()
return wrapped
This makes the test pass when mock
- None
. You can also try to elevate SkipTest()
, but that might interfere with decorators.
Inspired by the kind 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()
else:
return test(*args, **kwargs)
wrapper.__name__ = test.__name__
return wrapper
Seems to work too. __name__
it is important that nose recognizes the function and flags it when performing complex tests.
I hope I haven't missed anything? Losing faith in you test is a sad thing :(