Skip to content

Instantly share code, notes, and snippets.

@Dotrar
Last active October 19, 2022 01:47
Show Gist options
  • Save Dotrar/f6f9a4fc0d691cf7f6f825c0e17ce6b5 to your computer and use it in GitHub Desktop.
Save Dotrar/f6f9a4fc0d691cf7f6f825c0e17ce6b5 to your computer and use it in GitHub Desktop.
Pytest Reloader
"""
Pytest reloader:
author: Dre
place this file in your source directory (ie: src/confteset.py) which will auto-load by pytest.
when running pytests with the --pdb option, when leaving the debugger from test-failure, this plugin will re-load the
test and run it to see if any code changes have improved.
currently only reloads the test.
"""
import importlib
import inspect
import pytest
from _pytest.runner import runtestprotocol
def _check_options_have_pdb(config) -> bool:
val = config.getvalue
if not val("collectonly"):
if config.option.usepdb: # a core option
return True
return False
@pytest.hookimpl()
def pytest_enter_pdb(config, pdb):
print("##" * 10)
print("Running in reloader mode:")
print(" make changes to the source code")
print(" then use 'continue' or 'return' in pdb")
print(" to reload and re-test your changes.")
print("")
print(" use 'quit' to quit entirely.")
print("##" * 10)
@pytest.hookimpl()
def pytest_runtest_protocol(item, nextitem):
if not _check_options_have_pdb(item.session.config):
return
while True:
reports = runtestprotocol(item, log=False, nextitem=nextitem)
if len(reports) != 3:
# something else happened and we don't care
return
call = reports[1]
if call.outcome == "passed":
return
# the test didn't pass, so let's reload and re-try the test.
test_func = item._obj
func_path = test_func.__qualname__.split(".")
# re-import the parent module
func = importlib.reload(inspect.getmodule(test_func))
# load reference to new function
while func_path:
p = func_path[0]
func = getattr(func, p)
# test classes need to be instantiated.
if inspect.isclass(func):
func = func()
func_path.remove(p)
item._obj = func
print(
"""
#################
Reloaded latest code changes.
#################
"""
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment