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.

Best practices
Python programming and application logging

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

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting