This is a bit of a hack, but here it goes:
You can write your own importer and register it (note that this is Python 3-specific, Python 2 had another API for this):
import sut
import functools
import importlib
import sys
def use_slow(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
ImportRaiser.use_slow = True
if 'fastmodule' in sys.modules:
del sys.modules['fastmodule'] # otherwise it will remain cached
importlib.reload(sut)
f(*args, **kwargs)
return wrapped
def use_fast(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
ImportRaiser.use_slow = False
importlib.reload(sut)
f(*args, **kwargs)
return wrapped
class ImportRaiser:
use_slow = False
def find_spec(self, fullname, path, target=None):
if fullname == 'fastmodule':
if self.use_slow:
raise ImportError()
sys.meta_path.insert(0, ImportRaiser())
@use_fast
def test_fast():
# test code
@use_slow
def test_slow():
# test code
Here, sut is your module under test, which you have to reload in order to change the behavior. I added decorators for readabilty, but this can be done by some function or in the test setup, of course.
If you use the slow version, fastmodule will raise ImportError on import and slowmodule will be used instead. In "fast" case, all works as usual.