57

How can I get VS Code to put me into the debugger at the point of failure when running tests with pytest?

Pytest catches all errors and asserts, and VS code invokes the debugger only on uncaught errors (I can change this to raised exception, but then it stops on everything raised under a try).

I tried to set --pdb as pytest argument, but this leads to errors:

============================= test session starts =============================
platform win32 -- Python 3.8.1, pytest-5.3.2, py-1.8.1, pluggy-0.13.1
rootdir: c:\Projects\debugtest, inifile: pytest.ini
collected 1 item

test.py F
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Traceback (most recent call last):
  File "C:\Projects\debugtest\test.py", line 4, in test_with_assert
    assert 42==2.71828
AssertionError: assert 42 == 2.71828
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

>>>>>>>>>>>>>>>>>> PDB post_mortem (IO-capturing turned off) >>>>>>>>>>>>>>>>>>
> c:\projects\debugtest\test.py(4)test_with_assert()
-> assert 42==2.71828
(Pdb)

PYDEV DEBUGGER WARNING:
sys.settrace() should not be used when the debugger is being used.
This may cause the debugger to stop working correctly.
If this is needed, please check: 
http://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html
to see how to restore the debug tracing back correctly.
Call Location:
  File "C:\Program Files\Python38\lib\bdb.py", line 359, in set_quit
    sys.settrace(None)


- generated xml file: C:\Users\tzhgfma1\AppData\Local\Temp\tmp-24044mEWMyB1nPYAu.xml -
!!!!!!!!!!!!!!!!!! _pytest.outcomes.Exit: Quitting debugger !!!!!!!!!!!!!!!!!!!
============================== 1 failed in 0.43s ==============================

I have a very simple project for testing this:

.vscode\settings.json

{
    "python.testing.pytestArgs": [
        "--pdb"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.pytestEnabled": true,
    "git.ignoreLimitWarning": false
}

.vscode\launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        
        
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "internalConsole",
            "justMyCode":false
        },
        {
            "name": "Python: Attach using Process Id",
            "type": "python",
            "request": "attach",
            "processId": "${command:pickProcess}",
            "justMyCode": false
        },
        {
            "name": "Debug Tests",
            "type": "python",
            "request": "test",
            "console": "internalConsole",
            "justMyCode": false
        }
    ]
}

pytest.ini

[pytest]

python_files = test*.py
python_classes = Test
python_functions = test
addopts = --tb=native
console_output_style = classic
junit_duration_report = call
filterwarnings =
    ignore::RuntimeWarning

and test.py:

def test_with_assert():
    assert 42==2.71828

Is --pdb the correct way to do this? Or how do I enter the debugger upon an assert or error?

3
  • Could you provide us with detailed steps and related code information that can reproduce this issue? Judging from the current information, the issue is that the use of code 'sys.settrace()' affects the use of the debugger. In addition, you could also refer to it: github.com/HypothesisWorks/hypothesis/issues/985 Commented Aug 28, 2020 at 9:51
  • @JillCheng I've set up an almost empty project and edited the question to include all contents. sys.settrace seems to come from the Python lib's bdb itself. Hypothesis is not part of that environment. I suspect I do something basically wrong - is --pdb the correct way to enter the VS Code debugger upon a failed assert or error? Commented Aug 29, 2020 at 17:44
  • Does this answer your question? How can I get pytest to not catch exceptions Commented Apr 9, 2021 at 16:33

6 Answers 6

23

If you want to enter debugging when running pytest in VSCode and stay at a line of code, you could click 'Debug Test' at the top of the method after selecting the pytest test, as shown in the screenshot:

enter image description here

In addition, "python.testing.pytestArgs": [], in .vscode\settings.json is the folder path of the tested file, for example, my test file is in Test_cc under the a folder.

>      "python.testing.pytestArgs": [
>             "a/Test_cc"
>         ],

If this is not what you want, please let me know and describe the details of your needs.

Reference: Debug tests.

Update:

Usually, when we debug the test in VSCode, without setting a breakpoint for it, it will only display the test result. (success or failure). It will only display relevant test information in the console OUTPUT.

When I use the extension 'Python Test Explorer for Visual Studio code', it will display the debugging test information on the console, prompting the issue.

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

So I have to set a breakpoint where the assert fails? In the real application, I have hundreds of asserts and so many errors (I'm porting a legacy code base to Py3), I thought I could enter the debugger at the first error or first failing assert, without knowing the condition firsthand when it will trigger (some asserts are correct for a thousand runs, then fail on one). But pytest always completes, reporting failures at the end, instead of breaking into the debugger. If I set Breakpoint to Raised Exceptions, it will break on any handled exception, which is far too much.
@mgf I added some content to my answer, and you could try to refer to it.
Thanks. I've installed the extension, but it still completes the tests instead of stopping in the debugger at the point of failure. I guess this is a problem of pytest, which cannot be made to raise the error, so it remains uncaught, triggering the VSC debugger.
@mgf Thank you for your feedback. At present, VSCode cannot automatically catch errors when debugging test scripts, unless we set breakpoints for it or obtain relevant information from the console. We have already reported this issue(the link), let us look forward to the realization of this feature. GitHub link: github.com/microsoft/vscode-python/issues/13709
Thank you very much Jill! Your support is greatly appreciated!
4

This Answer actually solves the problem. I wish there would be a more straight-forward way, either from Visual Studio Code or a simple raise flag from pytest.

5 Comments

This was honestly pretty straightforward and doesn't require fiddling with a (not very well documented) VSCode extension.
@brandonscript Can you pls explain what is pretty straightforward? I agree with stackoverflow.com/questions/62419998/… that this should be trivial, but it isn't.
Adding a few lines of code your conftest.py, and an env variable to launch.json? Took me about a minute to copy paste it into my workspace.
@brandonscript Yes, the lines are few, but not intuitive. I agree with the author of the quoted question: "But I have a very hard time understanding how pytest does not have a flag or mode for this. It seems like the most normal natural thing in the world to want the debugger to break where you your test fails."
@mgf: I agree that it would be great to have an option built-in. here's a possibly more straight-forward, but certainly more cumbersome hack. :)
2

If you are struggling to make pytest appear in VSCode tests, or you don't like the pytest --pdb solution, you can also include this at the bottom of your test file test_me.py:

if __name__ == '__main__':
    pytest.main(["to_test/test_me.py"])

and then use the VSCode default debugger, with breakpoints set as you need. The debugger will run it as a regular test file, and the pytest fixtures and other specificities will work, as they are called from within.

Comments

1

If you are using Python Test Explorer for Visual Studio Code, you will need to add a specific configuration in .vscode/lauch.json file. It needs to contain the entries type == python and purpose == ["debug-test"], as described in the official documentation. You can see a valid example below:

{
   "name": "Python Test Debugger",
   "type": "python",
   "request": "launch",
   "console": "integratedTerminal",
   "justMyCode": false,
   "purpose": ["debug-test"]
}

A complete example of .vscode/launch.json file looks like the following snippet.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Test Debugger",
            "type": "python",
            "request": "launch",
            "console": "integratedTerminal",
            "justMyCode": false,
            "purpose": ["debug-test"]
        }
        {
            "name": "Python Debugger: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "justMyCode": false,
        }
    ]
}

Comments

0

Just make sure the breakpoints are enabled

breakpoints

Comments

0

A simple way is to just run the file as a regular python one. Just add to the end of the file one of the following:

if __name__ == '__main__':
    # for vanilla unittest
    unittest.main()
    # for all tests with pytest
    pytest.main(["-s", "-v", __file__ ])
    # for a specific pytest function
    pytest.main(["-s", "-v", __file__ + "::test_specific"])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.