Debug pytest¶
Stop inside a Python test.
Prerequisites¶
debugpyinstalled into the interpreter that runs your tests:
pytestin the same environment
The short way: the test under the cursor¶
or
Bugsaur runs the selected pytest node through debugpy. The adapter, environment
and working directory come from the profile.
The buffer must be saved, and saved breakpoints are not picked up — a test run uses only the breakpoints of that request.
The long way: a pytest profile¶
For running a whole suite or a directory under the debugger:
[profiles.tests]
adapter = "debugpy"
adapter_command = "${root}/.venv/bin/python"
program = "."
args = ["-x", "tests/"]
[profiles.tests.launch_arguments]
module = "pytest"
python = "${root}/.venv/bin/python"
module = "pytest" is the escape hatch: debugpy accepts a module key, and
the profile schema has no dedicated field for it.
-x stops on the first failure, which is usually what you want under a debugger.
Useful pytest arguments¶
| Argument | Effect |
|---|---|
-x |
stop after the first failure |
-s |
do not capture output, so print reaches the Logs panel |
-k expr |
only tests whose name matches |
tests/test_orders.py::test_create |
one specific test |
Two interpreters¶
adapter_command chooses the interpreter that runs the adapter;
launch_arguments.python chooses the one that runs your code. They are usually
the same venv, and No module named debugpy almost always means one of them is
pointing somewhere else.
When it does not work¶
| Symptom | Fix |
|---|---|
No module named debugpy |
install it into the interpreter in adapter_command |
No module named pytest |
install pytest into the same environment |
| Breakpoints in a fixture never fire | the fixture is cached from an earlier test — check the scope |
ImportError for your package |
working directory — Working directory |
print output invisible |
add -s |