How to set up a Python debugger in VS Code for pytest

Published August 14, 2022

Running and debugging a test module with pytest using VS Code

You may be wondering how to set up the Python debugger in VS Code to debug pytest tests. Let us assume that you have opened a Python project in VS Code. In the following post, I specify some shortcuts to access certain UI elements of VS Code. These keyboard shortcuts are for MacOS. You can easily find the counterparts for the other operating systems with a quick web search. Also, I am going to reference several UI elements of VS Code as defined in their official documentation, which you can access here: https://code.visualstudio.com/docs/getstarted/userinterface. Let’s get started:

  1. Go to the Activity Bar on the left and select “Run and Debug (Shift+Command+D)” (by default, it is the fourth item listed vertically in the bar).

  2. Click on the underlined text “create a launch.json file”.

  3. You are prompted with “Select debugger” in the quick input field at the top of the editor.

    1. Choose “Python Debugger”.
    2. Next you are prompted for “Debug Configuration”. Select “Python File”.
    3. A new configuration file (launch.json) is opened in the Editor.
  4. Note that you may have run the debugger before. In this case, in step 2 above, you will see a view with four sections by default (Variables, Watch, Call Stack, and Breakpoints).

    1. Right above the section “Variables” you will find a dropdown menu. Choose “Add Configuration…” from it.
    2. The launch.json configuration file is opened and you are prompted with the same steps as listed in step 3 (apply them here too).
  5. Assuming you don’t have any other configuration in the launch.json file, the contents should look like this:

{
    // 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 Debugger: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}
  • The important part for us is the configuration named “Python Debugger: Current File” that has been added to the list of configurations. This is the minimal setup for debugging a regular Python script. Depending on which file is active in the Editor, it will debug that file (because "program": "${file}").

  • The variables in the configuration come from a list of predefined variables in VS Code. Here in the documentation (https://code.visualstudio.com/docs/editor/variables-reference#_predefined-variables) you can find many more explained in detail.

  • For our purposes, to be able to run the debugger with pytest, i.e. the debugger should call the pytest module on the current test file, similar to running the command pytest test.py from the terminal, we need to edit some variables. They are as follows:

{
    // The name of the configuration,
    // as it will be shown in the list from (cf. step 4.1).
    "name": "Pytest",
    "type": "debugpy",
    "request": "launch",
    // We specify which module to run, whenever we run the debugger, 
    // in this case it is `pytest`.
    "module": "pytest",  
    "console": "integratedTerminal",
    // before, we specified the `$file` in the `program` attribute, 
    // but since we added `module`, 
    // the two are mutually exclusive (so only one of the attributes is permitted).
    "args": [ "${file}" ],
    // specifies the which python version from the system to use. 
    // If your python version is in a virtual envrionment, then specify that path.
    "python": "/usr/bin/python3.11",
},

The most important changes to the configuration are:

  • program attribute has been removed.
  • module attribute has been added.
  • We specify the current file using the args attribute which accepts a list of arguments that will be appended when invoking the module pytest.

Now you can select one of the test files, add breakpoints to it if necessary, and run the debugger for pytest (by pressing fn+F5 as a shortcut) or by clicking the green Play button in the drop-down menu with debugging configurations (cf. step 4.1).

Running and debugging a specific test with pytest using VS Code

If you’d like to run and debug a specific test with pytest, you can add a new configuration, that contains the following, to the list of configurations in launch.json:

{
    "name": "Pytest specific test",
    "type": "debugpy",
    "request": "launch",
    "module": "pytest",
    "console": "integratedTerminal",
    "args": [
        "${file}::${command:pickArgs}"
    ],
    "python": "/usr/bin/python3.11",
}

As you know, in pytest you can run a specific test using the command pytest test/test_my_module.py::my_test. To do this in VS Code, we need to pass the current test file and the name of the test method we want to run.

VSCode provides command:pickArgs as a way to prompt you for the name of the test method each time you start the debug session (see more here).

As a side note, if you already have a launch.json, you can add a new configuration either by manually creating a new JSON object in the configuration list, or by pressing the green button on the bottom right called “Add Configuration…” which will give you some useful prompts to quickly customize the configuration.

If you don’t have a launch.json, follow the steps above, starting with step 1, to create one. Alternatively, advanced users can create the file and place it in <YOUR_PROJECT_ROOT>/.vscode/. The file should contain at least the following:

{
    "version": "0.2.0",
    "configurations": [

    ],
}