Question

pytest: ModuleNotFoundError: No module named 'app' but the app runs fine

Solved · 264 viewsasked by ravi_k

Structure:

myproject/
  app/
    main.py
    services/pricing.py
  tests/
    test_pricing.py

uvicorn app.main:app runs fine from myproject/. But pytest from the same folder:

ChatGPT told me to add sys.path.insert(0, ...) at the top of every test file. There has to be a better way?

What I’ve tried

The sys.path hack (works but ugly), adding init.py to tests/ (didn't help), running from inside tests/.

Comment
The sys.path thing is in half of all ChatGPT test files I've seen. Glad there's a real answer here. ines_data

3 answers

Marked as helpful by the asker
marco_py

uvicorn works because python -m-style startup puts the current directory on sys.path. The pytest command doesn't. Tell pytest in config:

# pyproject.toml
[tool.pytest.ini_options]
pythonpath = ["."]
testpaths = ["tests"]

Or run it as python -m pytest, which puts the cwd on the path the same way.

Delete the sys.path lines after that.

Comment
pyproject thing worked, removed the hack from 7 files. Thanks! ravi_k
Short and correct. olu_backend
olu_backend

For a bigger project the "proper" route is to make the app an installable package ([project] table in pyproject, then pip install -e .). Then imports work the same in tests, scripts and production, no path config at all.

For this size pythonpath = ["."] is completely fine though.

Comment
grace_mw

Third option you'll see in older projects: an empty conftest.py in the project root. With the default import mode pytest puts that folder on sys.path. Works, but the pyproject setting says what it does, so I'd use that.

Comment