feder
feder

Reputation: 2058

how to debug python unittests in Visual Studio Code?

I have the following directory structure (a friends was so kind to put it on github while he examined it)

- code      
  - elements
    __init__.py
    type_of_car.py
  __init__.py
  car.py
- tests
  __init__.py
  test_car.py

These are my launch.json settings:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Debug Tests",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "purpose": ["debug-test"],
            "console": "integratedTerminal",
            "justMyCode": false
        },
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "main",
            "justMyCode": false,
            "cwd": "${workspaceFolder}"
        }
    ]
}

The VS Python Test settings are:

{
    "python.testing.unittestArgs": [
        "-v",
        "-s",
        "./tests",
        "-p",
        "test_*.py"
    ],
    "python.testing.pytestEnabled": false,
    "python.testing.unittestEnabled": true,
    "python.testing.cwd": "${workspaceFolder}"
}

The test_car.py imports module - of course - code.car. But also code.car.type_of_car

When I run the test from the project root, the test can be invoked and passes. py -m unittest tests.test_car.py

However, I cannot run my main code by pressing F5 (see launch.json) configuration. This fails because with No module named 'code.car'; 'code' is not a package being reported.

Also, I have to debug my tests as well with Visual Studio Code:

  1. I navigate to test_engine.py and open it
  2. Switch the "RUN AND DEBUG" to Python: Debug Tests configuration
  3. Press F5 to run the debugging.

This fails because with No module named 'code.car'; 'code' is not a package being reported.

How can I resolve the module-hell so that I can run the test also from VSCode/debugger? (this thing did cost me hours. Any hint is appreciated.)

Does someone has insight what the VS Code launcher considers it's root when calling the module?

Upvotes: 3

Views: 2797

Answers (2)

ipper
ipper

Reputation: 784

Although it works, manipulating the sys path is considered a bad practice. My linting configuration keeps complaining about it, so I thought I had to look for a proper fix. This works for me:

When using VSCode you could create a launch file and set/append the sys path. This launch.json file is located in .vscode of the project directory and can be created by hand or via the debug UI dialogs. By adding the following you don't need to manipulate the sys path in the test file:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Unittest",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "purpose": ["debug-test"],
            "console": "integratedTerminal",
            "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}
        }
    ]
}

By specifying the debug-test for purpose for this configuration it is only used for debugging tests.

And by extending env you can add the project work directory to the PYTHONPATH used to resolve packages/modules.

See more about vscode en testing: https://code.visualstudio.com/docs/python/testing

Upvotes: 2

JialeDu
JialeDu

Reputation: 9883

You can modify the car.py and test_car.py files as follows:

I only pasted the modified code。

car.py

# your code
from code.elements.type_of_car import TypeOfCar
# my code
from elements.type_of_car import TypeOfCar

test_car.py

# your code
import unittest
from code.car import Car
from random import randint

from code.elements.type_of_car import TypeOfCar
# my code
import unittest

import sys
sys.path.append("./code")

from car import Car
from random import randint

from elements.type_of_car import TypeOfCar

Results of debugging Python: Debug Tests:

enter image description here

Upvotes: 2

Related Questions