Debug pytest tests with pdb and breakpoints
Set a breakpoint in a pytest test or enter pdb on failure, inspect variables, and understand capture behavior and PYTHONBREAKPOINT.
Insert breakpoint() to stop at a chosen line, or run pytest --pdb to enter the debugger when a test fails. Use these in an interactive terminal so you can respond to the debugger prompt.
Stop at a specific line
Save this as test_exception.py:
import pytest
def divide(left, right):
return left / right
def test_zero_division():
breakpoint()
with pytest.raises(ZeroDivisionError):
divide(9, 0)
Run python -m pytest test_exception.py. At the breakpoint, pytest suspends capture for the test while the debugger is active. Enter c to continue; the exception is expected, so this test passes.
breakpoint() was introduced in Python 3.7. The older explicit form, import pdb; pdb.set_trace(), also works.
Stop when a test fails
python -m pytest test_exception.py --pdb
python -m pytest test_exception.py -x --pdb
The first command opens a post-mortem debugging session for failures. The second stops the test run after the first failure, once you leave that debugging session. An exception correctly handled by pytest.raises() is not a test failure.
To stop at the start of each test instead, pytest also provides --trace.
Useful debugger commands
| Command | Action |
|---|---|
l |
List nearby source lines |
n |
Advance to the next line in the current function |
s |
Step into a function call |
c |
Continue execution |
p variable |
Print an expression's value |
q |
Quit debugging; this can interrupt the pytest session |
In post-mortem mode, you inspect the failed program state; continuing does not simply resume normal execution from the failing statement.
FAQ
Are breakpoint() and pdb.set_trace() identical? By default, breakpoint() delegates through sys.breakpointhook to pdb. The hook can be replaced, and the default hook honors PYTHONBREAKPOINT, including PYTHONBREAKPOINT=0 to disable it. A direct pdb.set_trace() does not use that environment-variable switch.
How do I see print output? -s disables pytest's normal output capture. Pytest also suspends capture while its debugger is active. Live logs have separate logging settings.
Should I leave interactive breakpoints in CI? Usually no. A noninteractive run cannot answer the prompt. Remove the breakpoint or deliberately disable the default hook for that run; PYTHONBREAKPOINT=0 does not disable --pdb.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan