FileNotFoundError when using python -m pytest vs. pytest

Viewed 5249

I recently changed the IDE I am using to VSCode. For the most part I like it, but there is one particular problem that I can't seem to resolve. I didn't realize it was a problem either, until I moved IDEs.

I have a directory structure like this:

my_app
├── env
│   ├── bin
│   ├── include
│   ├── lib
│   ├── lib64 -> lib
│   ├── pyvenv.cfg
│   └── share
├── my_app
│   ├── expected_results
│   ├── __init__.py
│   ├── test_data
│   └── tests
├── pytest.ini
├── README.rst
├── setup.cfg
└── setup.py

When I launch my virtual environment I am sitting at the root of this directory structure.

I run my tests by issuing this command (or providing additional options). This currently works:

pytest

But, when VSCode launches, it spits out an error saying it can't find an expected file:

E   FileNotFoundError: [Errno 2] No such file or directory: 'my_app/expected_results/expected_available_items.yml'

After some investigation, I figured out that this is because when VSCode launches it issues the following command:

python -m pytest

I am setting that path by doing this:

import pathlib
EXPECTED_RESULTS_BASE = pathlib.Path("my_app/expected_results")
expected_results = EXPECTED_RESULTS_BASE.joinpath('expected_available_items.yml')

What do I need to modify so that my tests will continue to operate when I just issue a pytest command AND will operate if I (or my IDE, apparently) issues python -m pytest?

I hope it's safe to assume that VSCode is launching this from the root of my_app like I am?

2 Answers

Probably not enough information to answer this for you straight out, but lets try some things:

  • In your test code, above the line where you are getting the error insert some lines like these and see if they print out what you're expecting
print(os.getcwd())
print(EXPECTED_RESULTS_BASE.absolute())
  • Since you're using a venv and the error is a result of calling pytest with a different command, try using which to see if you're actually calling different things. Both before and after activating your venv:
which pytest
which python

python -m pytest will call the pytest module installed with the version of python you've just called. If python calls a different version than you're getting from pytest inside your venv, then that could be the problem.

You should be able to check which python version pytest is calling by looking at the hashbang at the top of the file

head -1 $(which pytest)

On my system, macOS with anaconda Python installed, I get the following from those commands

$ which pytest
/Users/Shannon/anaconda/bin/pytest

$ which python
/Users/Shannon/anaconda/bin/python

$ head -1 $(which pytest)
#!/Users/Shannon/anaconda/bin/python

This tells me that pytest is calling the same version of python I get when I call python. As such, pytest and python -m pytest should result in the same thing for me, inside my default environment.

Are you sure VSCode is loading your venv correctly before running the test?

Assuming you have a virtual environment selected for your Python interpreter in VS Code:

  1. Open the terminal in VS Code
  2. Let the virtual environment activate
  3. Run python -m pip install pytest

That will install pytest into the virtual environment which is why python -m fails (pytest globally on your PATH is installed in some global Python install which a virtual environment won't have access to).

Related