PATH problem with pytest 'ImportError: no module named YadaYadaYada'

I used easy_install to install pytest on mac and started writing tests for a file structure project:

repo/ repo/app.py repo/settings.py repo/models.py repo/tests/ repo/tests/test_app.py 

run py.test while everything in the repo directory behaves as you expected.

but when I try to do the same on linux or windows (both have pytest 2.2.3 on them), it is taken whenever it starts its first import of anything from my application path. Say for example from app import some_def_in_app

Do I need to edit PATH to run py.test on these systems? Has anyone experienced this?

+185
python unit-testing pytest
Apr 20 2018-12-21T00:
source share
13 answers

Yes, the source folder is not in the Python path if you cd to the test directory.

You have 2 options:

  1. Add the path to the test files manually, for example:

     import sys, os myPath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, myPath + '/../') 
  2. Run the tests with env var PYTHONPATH=../ .

+73
Apr 20 2018-12-21T00:
source share

I'm not sure why py.test does not add the current directory to PYTHONPATH itself, but here is a workaround (which should be done from the root of your repository):

 python -m pytest tests/ 

This works because Python adds the current directory to PYTHONPATH for you.

+225
Dec 07 '15 at 18:21
source share

I had the same problem. I fixed it by adding an empty __init__.py file to my tests directory.

+101
Sep 24 '13 at 1:20
source share

conftest solution

The least invasive solution is to add an empty file called conftest.py to conftest.py repo/ :

 $ touch repo/conftest.py 

It. There is no need to write your own code to distort sys.path or remember to drag PYTHONPATH together or put __init__.py in directories where it does not belong.

Project catalog subsequently:

 repo ├── conftest.py ├── app.py ├── settings.py ├── models.py └── tests └── test_app.py 

explanation

pytest looks for pytest modules in conftest tests for collecting custom hooks and fixtures, and to import custom objects from them, pytest adds the parent directory conftest.py to sys.path .

Other project structures

If you have a different project structure, put conftest.py in the root directory of the package (the one that contains the packages but not the package itself, therefore does not contain __init__.py ), for example:

 repo ├── conftest.py ├── spam │ ├── __init__.py │ ├── bacon.py │ └── egg.py ├── eggs │ ├── __init__.py │ └── sausage.py └── tests ├── test_bacon.py └── test_egg.py 

src location

Although this approach can be used with the src layout (put conftest.py in conftest.py src ):

 repo ├── src │ ├── conftest.py │ ├── spam │ │ ├── __init__.py │ │ ├── bacon.py │ │ └── egg.py │ └── eggs │ ├── __init__.py │ └── sausage.py └── tests ├── test_bacon.py └── test_egg.py 

PYTHONPATH in mind that adding src to PYTHONPATH reduces the value and benefits of the src layout! You will end up testing the code from the repository, not the installed package. If you need to do this, you probably do not need src dir at all.

Where to go from here

Of course, conftest modules are not just files that help in detecting source code; this is the place where all the project-specific improvements to the pytest platform and the tuning of your test suite take place. pytest lot of information about conftest modules scattered across all documents ; start with conftest.py : local plugins for each directory

In addition, SO has a great question on conftest modules: what is the use of conftest.py files in py.test?

+92
May 30 '18 at 17:42
source share

You can run PYTHONPATH at the root of the project

 PYTHONPATH=. py.test 

Or use pip install as editable import

 pip install -e . # install package using setup.py in editable mode 
+37
Oct 24 '14 at 9:03
source share

Run pytest as a module with: python -m pytest tests

+36
Feb 02 '18 at 9:37
source share

I created this as an answer to your question and my own confusion. I hope this helps. Pay attention to PYTHONPATH both in the py.test command line and in tox.ini.

https://github.com/jeffmacdonald/pytest_test

In particular: you must tell py.test and tox where you will find the modules you include.

With py.test you can do this:

 PYTHONPATH=. py.test 

And with toxicity, add this to your tox.ini:

 [testenv] deps= -r{toxinidir}/requirements.txt commands=py.test setenv = PYTHONPATH = {toxinidir} 
+20
Jul 15 '16 at 13:46
source share

I started getting weird ConftestImportFailure: ImportError('No module named... errors when I accidentally added the __init__.py file to my src directory (which should not have been a Python package, just a container of the whole source).

+7
Aug 14 '17 at 16:44 on
source share

I was getting this error due to something even simpler (one might even say trivially). I did not install the pytest module. So a simple apt install python-pytest fixed this for me.

'pytest' would be listed in setup.py as a test dependency. Make sure you also set up your test requirements.

+3
Aug 28 '17 at 2:56 on
source share

I fixed this by deleting the top level __init__.py in the parent folder of my sources.

+3
Jul 03 '19 at 16:58
source share

For me, the problem was tests.py generated by Django along with the tests directory. Removing tests.py solved the problem.

+1
Dec 04 '18 at 12:10
source share

I got this error because I used relative imports incorrectly. In the OP example, test_app.py should import functions using, for example,

 from repo.app import * 

However, in the general case, __init__.py files are scattered across the file structure, this does not work and creates the appearance of an imported error, unless the files and test files are in the same directory.

 from app import * 

Here is an example of what I had to do with one of my projects:

Here is my project structure:

 microbit/ microbit/activity_indicator/activity_indicator.py microbit/tests/test_activity_indicator.py 

To access activity_indicator.py from test_activity_indicator.py, I needed:

  • run test_activity_indicatory.py with the correct relative import:
  from microbit.activity_indicator.activity_indicator import * 
  • put the __init__.py files throughout the project structure:
  microbit/ microbit/__init__.py microbit/activity_indicator/__init__.py microbit/activity_indicator/activity_indicator.py microbit/tests/__init__.py microbit/tests/test_activity_indicator.py 
+1
Jan 16 '19 at 17:07
source share

I had a similar problem. pytest did not recognize the module installed in the environment in which I worked.

I solved this by also installing pytest in the same environment.

+1
Apr 25 '19 at 14:12
source share



All Articles