katch
katch

Reputation: 930

How to configure VS code for pytest with environment variable

I am trying to debug pytest. I would like to inject an environment variable. Here is how I have set launch.json

{
    "type": "python",
    "request": "test",
    "name": "pytest",
    "console": "integratedTerminal",
    "env": {
        "ENV_VAR":"RandomStuff"
    }
},

But it seems when I start debugging. I do not see the env variable injected, as a result my test which expects that env variable fails.

Also I notice error

Could not load unit test config from launch.json

Upvotes: 30

Views: 40477

Answers (4)

totooooo
totooooo

Reputation: 1415

VSCode's python extension now has a special way of running the debugger when you are running it on python tests.

You can configure it following this guide. In a nutshell:

  • Install the python extension
  • Type command Python: Configure Tests in the command palette
  • Choose your testing framework (only pytest or unittest at the moment)
  • Create a config in your .vscode/launch.json file with your necessary envs:
{
    "name": "Python: Tests in current file",
    "purpose": ["debug-test"],
    "type": "python",
    "request": "launch",
    "program": "${file}",
    "args": ["--color=yes"],
    "env": {"ENV_VAR":"RandomStuff"},
    "console": "integratedTerminal",
    "justMyCode": false
}

^ the "purpose": ["debug-test"] is important, this is how VSCode will know this config is used for debugging tests.

  • To debug the tests, run command Test: Debug Tests in Current File (or Test: Debug Test at Cursor) in the command palette

Advantage v/s the "module" method: not sure there is really one. Well you get a dedicated VS Code shortcut for debugging tests in current file (cmd ; + cmd f).

EDIT: after trying it out, I wouldn't recommend the Test: Debug Test at Cursor command, as it seems to mess up with the tear down (in my case it was preventing the emptying of the test DB)

Upvotes: 7

Efren
Efren

Reputation: 4907

This works in v 1.72.2

  • Create in the workspace folder:
    • .vscode/launch.json
  • Similar to the OP, but using "module"
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Pytest",
      "type": "python",
      "request": "launch",
      "module": "pytest",
      "console": "integratedTerminal",
      "env": {
        "testy": "someval"
      }
    }
  ]
}
  • Try some breakpoints (either in test files or app code)
  • Start the debugger

enter image description here

  • Watch the os.environ['testy'] value (must import os where the breakpoint is of course)

enter image description here

Upvotes: 6

Sterling
Sterling

Reputation: 456

pytest-env

Install

Per https://stackoverflow.com/a/39162893/13697228:

conda install -c conda-forge pytest-env

Or:

pip install pytest-env

pytest.ini

Create pytest.ini file in project directory:

[pytest]
env = 
    ENV_VAR=RandomStuff

Python

In your code, load environment variables as you normally would:

import os
env_var = os.environ["ENV_VAR"]

pytest / VS Code

Either run:

pytest

(Notice how it says configfile: pytest.ini)

C:\Users\sterg\Documents\GitHub\sparks-baird\mp-time-split> pytest
==================================== test session starts ===================================== platform win32 -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0 rootdir:
C:\Users\sterg\Documents\GitHub\sparks-baird\mp-time-split,
configfile: pytest.ini plugins: anyio-3.6.1, cov-3.0.0, env-0.6.2
collecting ...

Or:

enter image description here

This only seems to work with breakpoints that have manually been set, I'm guessing some other change is needed to pause on errors.

Python for VS Code Extension

Apparently the Python for VS Code extension recognizes a .env file automatically. E.g. .env file:

ENV_VAR=RandomStuff

Haven't verified, but I'd assume this has the same behavior as using pytest-env with a pytest.ini file.

When all else fails

When I don't feel like dealing with the strange hackery necessary to get VS Code, Anaconda environments, and pytest playing nicely together (and/or forget how I fixed it before), I call my tests manually and run it like a normal script (see below). This may not work with more advanced pytest trickery using fixtures for example. At the end of your Python script, you can add something like:

if __name__ == "__main__":
    my_first_test()
    my_second_test()

and run it in debug mode (F5) as normal.

Upvotes: 20

katch
katch

Reputation: 930

Could not really figure out how to fix "unit" test debugging with Vscode. But with Pytest one can call tests like python -m pytest <test file>(https://docs.pytest.org/en/stable/usage.html#cmdline) That means Vscode can be configured like a module

"configurations": [
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "pytest",
            "args": ["--headful","--capture=no", "--html=report.html"],
        }

This is good enough to do debugging of python tests. Also you can then insert environment variables

   "env": {
        "ENV_VAR":"RandomStuff"
    }

Upvotes: 8

Related Questions