vscode-python: Pytest running doesn't take into consideration env.

Environment data

  • VS Code version: 1.36.1
  • Extension version (available under the Extensions sidebar): 2019.9.29489-dev
  • OS and version: Ubuntu 19.04
  • Python version (& distribution if applicable, e.g. Anaconda): 2.7.15+
  • Type of virtual environment used (N/A | venv | virtualenv | conda | …): virtualenv
  • Relevant/affected Python packages and their versions: pytest
  • Jedi or Language Server? (i.e. what is "python.jediEnabled" set to; more info #3977): LanguageServer

Expected behaviour

Test discovery and running have the enviroment variables declared in the .env file or the terminal.integrated.env.linux settings before executing.

Actual behaviour

Tests that depend on a specific environment variable being set to run fail.

Steps to reproduce:

  1. Set a test that depends on a enviroment variable to run.
  2. Declare that variable in an .env file or in terminal.integrated.env.linux
  3. Run test.

Logs

Output for Python in the Output panel (ViewOutput, change the drop-down the upper-right of the Output panel to Python)

In this output I’m running a test that depends on a variable PANOPTA_INTEGRATION_TESTS_CONFIG to point to a file, and if not found it defaults to this file /etc/panopta_tests_support_data.yaml, which doesn’t exist. I have declared said variable in an .env file at my workspace root. PANOPTA_INTEGRATION_TESTS_CONFIG=/home/cllamach/Panopta/classic/src/models/tests/integration/support_data_config.yaml

But when adding log statements to pytest run module I see it tries to load the default file instead of the one declared in the .env file. I ran into a similar problem with the PYTHONPATH variable not being taken into account when declared into the .env file and was able to bypass it by installing pytest-pythonpath to declare its values there.

python /home/cllamach/.vscode/extensions/ms-python.python-2019.9.29489-dev/pythonFiles/testing_tools/run_adapter.py discover pytest -- -s --cache-clear --disable-warning /home/cllamach/Panopta/classic/src/tests/
Test Discovery failed: 
Error: ============================= test session starts ==============================
platform linux2 -- Python 2.7.15+, pytest-4.4.1, py-1.8.0, pluggy-0.9.0
rootdir: /home/cllamach/Panopta/classic/src/tests, inifile: pytest.ini
plugins: xdist-1.28.0, sugar-0.9.2, pythonpath-0.7.3, forked-1.0.2, pylama-7.7.1
ConfTest /home/cllamach/Panopta/classic/src/tests/integration/conftest.py
PKGPath /home/cllamach/Panopta/classic/src/tests/integration
Error import conftest [Errno 2] No such file or directory: '/etc/panopta_tests_support_data.yaml'
collected 0 items / 1 errors

==================================== ERRORS ====================================
________________________ ERROR collecting test session _________________________
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/py/_path/common.py:377: in visit
    for x in Visitor(fil, rec, ignore, bf, sort).gen(self):
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/py/_path/common.py:419: in gen
    if p.check(dir=1) and (rec is None or rec(p))])
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/_pytest/main.py:660: in _recurse
    ihook = self.gethookproxy(dirpath)
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/_pytest/main.py:481: in gethookproxy
    my_conftestmodules = pm._getconftestmodules(fspath)
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/_pytest/config/__init__.py:419: in _getconftestmodules
    mod = self._importconftest(conftestpath.realpath())
../../.virtualenvs/panopta_env/local/lib/python2.7/site-packages/_pytest/config/__init__.py:461: in _importconftest
    raise ConftestImportFailure(conftestpath, sys.exc_info())
E   ConftestImportFailure: (local('/home/cllamach/Panopta/classic/src/tests/integration/conftest.py'), (<type 'exceptions.IOError'>, IOError(2, 'No such file or directory'), <traceback object at 0x7f7a47389ef0>))
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
===================== 21 warnings, 1 error in 0.53 seconds =====================

Traceback (most recent call last):
  File "/home/cllamach/.vscode/extensions/ms-python.python-2019.9.29489-dev/pythonFiles/testing_tools/run_adapter.py", line 18, in <module>
    main(tool, cmd, subargs, toolargs)
  File "/home/cllamach/.vscode/extensions/ms-python.python-2019.9.29489-dev/pythonFiles/testing_tools/adapter/__main__.py", line 90, in main
    parents, result = run(toolargs, **subargs)
  File "/home/cllamach/.vscode/extensions/ms-python.python-2019.9.29489-dev/pythonFiles/testing_tools/adapter/pytest/_discovery.py", line 36, in discover
    raise Exception('pytest discovery failed (exit code {})'.format(ec))
Exception: pytest discovery failed (exit code 2)

Output from Console under the Developer Tools panel (toggle Developer Tools on under Help; turn on source maps to make any tracebacks be useful by running Enable source map support for extension debugging)

XXX

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 20
  • Comments: 44 (11 by maintainers)

Most upvoted comments

@nickcointracker yes, it does when you specify the path to the .env file in your settings.json file. For example, if the .env file is in your workspace folder, you can add the following line there:

"python.envFile": "${workspaceFolder}/.env"

Does that help you?

@nickcointracker yes, it does when you specify the path to the .env file in your settings.json file. For example, if the .env file is in your workspace folder, you can add the following line there:

"python.envFile": "${workspaceFolder}/.env"

Does that help you?

Thanks @luabud I’ve tried setting that option, unfortunately it seems to be ignored during test discovery (although it works for regular python app execution). If it’s supposed to be taken into account and vars be visible during the discovery phase, then I’ll try to file a report with repro details.

What if it’s a typed-in variable at run time that doesn’t come from a file? How do I get the test runner to inject this? i.e. keyerror: ENV The ENV from ENV=testing python3 -m unittest tests/tests.py

@CMLL the way i solved it was to install pytest-dotenv

test_one py - pytest-env - Visual Studio Code_755

I ran the command pip install pytest-dotenv

And ready! Maybe you need to reload the vscode application

test_one py - pytest-env - Visual Studio Code_757

Thank you for the detailed description @luabud. Now I get it! It only works for debugging tests.

I wish I was able to override the environment vars when clicking the CodeLens adornments Run Test above the test function or the Run All Tests in the Test panel.

image

@lepsch please note that the configuration I mentioned is for debugging tests . The envFile set there will take precedence over the one in settings.json when debugging tests. I ran simple test case for that, based on Don’s example above:

  • Have a .env file with WOW=1234 and another one (e.g. called .envtest) with WOW=0000.
  • Add "python.envFile": ${workspaceFolder}/.env to the settings.json and "envFile": ${workspaceFolder}/.envtest to the launch.json configuration, making sure the request type there is test:
        {
            "name": "Python: Test",
            "type": "python",
            "request": "test",
            "console": "integratedTerminal",
            "envFile": "${workspaceFolder}/.envtest"
        },

Then when I run the below test sample, I get 1234 written in log.log. When I debug, I get 0000.

import os
def test_case_one():
    with open("log.log", "w") as fp:
        fp.write(os.getenv("WOW", "not found"))

@brgirgis can you try adding the below configuration to your launch.json file, adding to the envFile setting the path to your .env file if it’s not in the workspace folder?

        {
            "name": "Python: Test",
            "type": "python",
            "request": "test",
            "console": "integratedTerminal",
            "envFile": "${workspaceFolder}/.env"
        },

The request type “test” will make this to be picked up when debugging tests. If that doesn’t work, would you mind filing a new issue giving more details about your environment and repro steps? I think your issue may not be the same as the one here.

Does test discovery take into account variables in .env? Or is it possible to specify an env file for test discovery? I see a problem where my module files (__init__.py) use env vars, and test discovery fails because during the discovery those variables are not defined.

@DonJayamanne I installed version 2019.10.37374-dev from the link provided but still the same test case fails. I’m using the test test panel to discover and execute the tests. Using either the upper run all tests button and the Run Test link above the specific test fails. I tried with the Debug Test link and it also fails, but I normally don’t use this to run tests.

image

I use a combination of conda and poetry to create virtual environments. Pytest is always listed as a development dependency in my project.toml file. After I run poetry install, pytest will be installed to the appropriate environment. When I switch between interpreters in my various environments, I would expect python.testing.pytestPath to default to the pytest in the same directory as the interpreter, but in fact it is using the pytest installed on my system.

I noticed that when I change my interpreter, the python.pythonPath variable does not change in my workspace settings file .vscode/settings.json. My understanding of the VS Code documentation on Python Environments, is that this should happen automatically when I select an interpreter.

I wonder if others facing this problem are seeing the same thing.

@luabud, actually, only adding the ${workspaceFolder}/.env file solves it. Changing the launch.json with the pointed config does nothing. And I think this works because this file changes the environment vars by default for every tool in the IDE, not only the tests.

@luabud adding this to my launch.json solved my issue. Thanks!