Could you provide a concrete example? It's still unclear to me why one wants a custom breakpoint() handler.
__init__.py
os.environ.setdefault('PYTHONBREAKPOINT', 'tests.utils.raise_or_debug')
tests.utils.raise_or_debug def raise_or_debug(msg=''):
if settings.BREAKPOINT_ON_ERROR:
extype, value, tb = sys.exc_info()
if getattr(sys, 'last_traceback', None):
pdb.pm()
elif tb:
pdb.post_mortem(tb)
else:
pdb.set_trace()
elif msg:
raise AssertionError(msg)
else:
pdb.set_trace()
The reason is so we can leave breakpoints in the tests, and then depending on context run the tests in a context where debug is possible, or simply raise the failure again.Selenium can be very flaky, so this has really sped up iteration and improvements. Standard functions with retries, and smart assertions and timeouts can then be fixed and resumed in dev - and give a good message on fail (for example headless chrome runner on CI).
We have manually overwritten the breakpoint handler to a custom handler that in default mode does this:
- `breakpoint()` calls trigger `pdb.set_trace()` as per usual
- `breakpoint(<str>)` calls trigger AssertionError to fail tests
When `BREAKPOINT_ON_ERROR=TRUE` is turned on:
- `breakpoint()` calls trigger `pdb.set_trace()` as per usual
- `breakpoint(<str>)` call `pdb.set_trace()` so you can try to manually work out how the code is functioning
- if you call `breakpoint(<str>)` from an `except` block it will open the debugger at the position of the exception
Usage example: try:
WebDriverWait(self.driver, 10).until(
EC.element_to_be_clickable((By.ID, 'desktop-apply')))
except TimeoutException:
breakpoint('Was not able to click apply button.') PYTHONBREAKPOINT=print python
and all your breakpoint() calls will be prints.Which is not super useful, however you can use
PYTHONBREAKPOINT=icecream.ic
and now you get the advantages of TFA without having to import anything anywhere.The only annoyance is that the default hook takes no arguments, so you can't trivially switch between the default and custom implementations, you may need to modify the source depending on the breakpoint hook you're using.