Search code examples
pythonpython-3.xdockerpytest

ModuleNotFoundError with pytest


I want my tests folder separate to my application code. My project structure is like so

myproject/
  myproject/
    myproject.py
    moduleone.py
  tests/
    myproject_test.py

myproject.py

from moduleone import ModuleOne

class MyProject(object)
....

myproject_test.py

from myproject.myproject import MyProject
import pytest

...

I use myproject.myproject since I use the command

python -m pytest

from the project root directory ./myproject/

However, then the imports within those modules fail with

E ModuleNotFoundError: No module named 'moduleone'

I am running Python 3.7 and have read that since 3.3, empty __init__ files are no longer needed which means my project becomes an implicit namespace package

However, I have tried adding an __init__.py file in myproject/myproject/ and also tried adding a conftest.py file in myproject/ but neither works

I have read answers that say to mess with the paths and then upvoted comments in other questions saying not to.

What is the correct way and what am I missing?

EDIT;

Possibly related, I used a requirements.txt to install pytest using pip. Could this be related? And if so, what is the correct way to install pytest in this case?

EDIT 2:

One of the paths in sys.path is /usr/src/app/ which is a docker volume lined to /my/local/path/myproject/.

Should the volume be /my/local/path/myproject/myproject/ instead?


Solution

  • Solution: use the PYTHONPATH env. var

    PYTHONPATH=. pytest
    

    As mentioned by @J_H, you need to explicitly add the root directory of your project, since pytest only adds to sys.path directories where test files are (which is why @Mak2006's answer worked.)


    Good practice: use a Makefile or some other automation tool

    If you do not want to type that long command all the time, one option is to create a Makefile in your project's root dir with, e.g., the following:

    .PHONY: test
    test:
        PYTHONPATH=. pytest
    

    Which allows you to simply run:

    make test
    

    Another common alternative is to use some standard testing tool, such as tox.