Search code examples
pythonunit-testingimportpython-importflask-testing

Importing files from sibling directory


I need to run unit tests for my Flask app. In my test config file, I need to import the flask create_app function from a sibling directory to initialize the test app. I cannot figure it out without getting import errors.

I have tried putting __init__.py on virtually every folder without success. I have read that editing the sys path is not recommended so I would like a solution without.

Folder Structure

root/
----__init__.py
----server/
--------__init__.py
--------database.py
----tests/
--------__init__.py
--------config.py

config.py

from server import create_app
from server.database import db

Raises this error:

Traceback (most recent call last):
  File "tests/config.py", line 2, in <module>
    from server import create_app
ModuleNotFoundError: No module named 'server'

and:

from ..server import create_app
from ..server.database import db

Raises this error:

Traceback (most recent call last):
  File "tests/config.py", line 2, in <module>
    from ..server import create_app
ValueError: attempted relative import beyond top-level package

Can someone explain why it doesn't work and how python imports work in general? I have never been able to figure them out.


Solution

  • For an import statement to work correctly, names must be resolved in sys.path somehow. Creating a correct package structure and installing the package is usually the best way to get the names visible in sys.path.

    1. Remove root/__init__.py and tests/__init__.py
    2. Correct your import statements:
    from ..server import create_app  # no
    from server import create_app  # yes
    
    1. Add root/setup.py with contents as described in setuptools basic guide.
    2. Create/activate virtualenv (usually in root/.venv/ subdir, but doesn't really matter where)
    3. From the project root, i.e. the directory containing setup.py, install your package:
    pip install --editable .