pytest --pdb 未进入 pdb 是因它仅在测试失败或未捕获异常时触发,若测试通过则静默跳过;需确认测试真失败(加 -v 查看 FAILED)、排除 try/except 吞异常、IDE/插件干扰或 stdout/stderr 被捕获(应加 -s)。

pytest --pdb 启动后为什么没进 pdb?
因为 --pdb 只在测试失败或异常时触发,不是一运行就进调试器。它等同于在异常抛出点自动执行 import pdb; pdb.post_mortem(),属于「事后调试」。如果测试用例压根没报错,--pdb 就静默跳过。
- 想强制在某行中断,得用
breakpoint()(Python 3.7+)或import pdb; pdb.set_trace() - 若用
pytest --pdb却没停住,先检查测试是否真失败了——加-v看输出,确认有FAILED或 traceback - pytest 7.0+ 默认启用
breakpoint(),但若环境变量PYTHONBREAKPOINT=0被设过,会禁用所有断点
如何让 pytest --pdb 在 assert 失败时单步回溯?
--pdb 本身不支持「单步执行测试函数」,它只在异常传播结束后的最后一个帧里启动交互式 pdb。要真正单步,得配合 --trace 或手动插断点。
-
pytest --pdb --trace test_file.py::test_func:测试开始前就进入 pdb,可用n(next)、s(step)、c(continue)控制流程 -
--trace和--pdb可共存,但行为不同:--trace是「事前介入」,--pdb是「事后接管」 - assert 失败时,
--pdb停在 assert 行;但若该 assert 被 try/except 捕获且未重新抛出,就不会触发
常见干扰:IDE、pytest 插件和 PYTHONPATH 导致 --pdb 失效
PyCharm/VS Code 的内置测试运行器通常忽略命令行参数,直接绕过 --pdb;某些插件如 pytest-xdist(并行执行)或 pytest-asyncio 也可能拦截异常传播路径。
- 务必在终端中用原生命令运行:
python -m pytest --pdb test_x.py,不要点 IDE 的 ▶️ 按钮 - 禁用可疑插件临时验证:
python -m pytest --pdb -p no:xdist test_x.py - 如果项目有
conftest.py重写了pytest_exception_interact钩子,可能吞掉异常,导致--pdb不启动
替代方案:用 breakpoint() + pytest -s 更可控
比起依赖 --pdb 的被动触发,主动在关键位置写 breakpoint() 更可靠,尤其适合想观察变量中间状态的场景。
立即学习“Python免费学习笔记(深入)”;
- 在测试函数中插入:
def test_something(): x = 1; breakpoint(); assert x == 2 - 必须加
-s(即--capture=no),否则 stdin/stdout 被捕获,pdb 无法读取输入 - 在 pdb 中可直接打印变量:
p x、查看栈:where、执行语句:!x += 1 - 注意:
breakpoint()在生产环境可通过PYTHONBREAKPOINT=0全局关闭,避免误留


















