TL;DR: I would like Pytest to reload imports in certain files when it runs those tests. Some of the imports in my code base have side effects that I need to control at test time. The behavior would basically be like importlib.reload
for any module in the test file. Is this possible?
Longer explanation:
I have a class that works as a registry for certain kinds of functions:
# content of registry.py
class Registry:
_registry = []
@classmethod
def register_function(cls, func):
# decorator; registers a function in the registry.
cls._registry.append(func)
and I have a several files with registered functions:
# content of registered_func.py
@Registry.register_function
def registered_function(...):
...
I need to write tests that assure that the registered functions do what’s expected when pulled from the registry. However, the way the registry is accessed may return registered functions besides the function of interest. Note the behavior: registered_function
is registered on import of that file.
Running a suite of tests is creating issues; what functions are registered depends on the order of tests run. I have tried monkey patching:
import pytest
import Registry as _Registry
@pytest.fixture
def Registry(monkeypatch):
monkeypatch.setattr(_Registry, '_registry', {})
return _Registry
def test_registered_function_registry(Registry):
import registered_function
# do tests
assert registered_function in Register._registry
However, if registered function has been previously imported during any test, pytest won’t
re-import in test_registered_function_registry
.
Ideally, the syntax in test_registered_function_registry
works. I don’t want to couple tests to the modules that do registering–any import inside a function would re-execute the code in the imported file and populate the registry accordingly. This is ideal because it’s exactly the registry would be populated in our code base.
A work around is to explicitly reload
the parent module with importlib
, but it feels awkward to me. The behavior here is associated with Pytest–what happens when running a test depends on the state the Pytest creates, not the state that the test file creates. Is there a way to control this behavior of pytest?