Py.test No module named *
Asked Answered
K

16

137

I have a folder structure like this

App
--App
  --app.py       
--Docs
--Tests
  --test_app.py

In my test_app.py file, I have a line to import my app module. When I run py.test on the root folder, I get this error about no module named app. How should I configure this?

Kweisui answered 8/1, 2014 at 1:3 Comment(2)
Possible duplicate of PATH issue with pytest 'ImportError: No module named YadaYadaYada'Lonlona
I encounter with this problem. I have to remove my unit test classes & clear the cache using the --cache-clear pytest flag to solved the error. The problem happends to me when I modify import statements on a class that I was testing. At this point in time I do not know the exact reason about this.Quintilla
L
29

So you are running py.test from /App. Are you sure /App/App is in your $PYTHONPATH?

If it's not, code that tries to import app will fail with such a message.

EDIT0: including the info from my comment below, for completeness.

An attempt to import app will only succeed if it was executed inside /App/App, which is not the case here. You probably want to make /App/App a package by putting __init__.py inside it, and change your import to qualify app as from App import app.

EDIT1: by request, adding further explanation from my second comment below.

By putting __init__.py inside /App/App, that directory becomes a package. Which means you can import from it, as long as it - the directory - is visible in the $PYTHONPATH. I.e. you can do from App import app if /App is in the $PYTHONPATH. Your current working directory gets automatically added to $PYTHONPATH, so when you run a script from /App, the import will work.

Louth answered 8/1, 2014 at 1:5 Comment(4)
I have run pip install -e . on /App, so the package is installed to the /usr/local library. I would think this adds my folder to the path?Kweisui
There's no reason for /App/App to automatically be added into the $PYTHONPATH, regardless of where you installed pip. An attempt to import app will only succeed if it was executed inside /App/App, which is not the case here. You probably want to make /App/App a package by putting __init__.py inside it, and change your import to qualify app as from App import app.Louth
My test can be ran now. I am still confused about the $PYTHONPATH part. Is it that if I add init.py to my /App/App folder, python will automatically insert the /App/App folder into the path?Kweisui
@zsljulius: by putting __init__.py inside /App/App, that directory becomes a package. Which means you can import from it, as long as it - the directory - is visible in the $PYTHONPATH. I.e. you can do from App import app if /App is in the $PYTHONPATH. Your current working directory gets automatically added to $PYTHONPATH, so when you run a script from /App, the import will work.Louth
T
208

Working with Python 3 and getting the same error on a similar project layout, I solved it by adding an __init__ file to my tests module.

$ touch tests/__init__.py

I'm not great at packaging and importing, but I think that this helps pytest work out where the target App module is located.

Thug answered 22/4, 2017 at 13:23 Comment(7)
Before using this strategy, you should check the implications against pytest's best practices: docs.pytest.org/en/latest/…Thug
This is the only way I could make it work in Python 3.Upraise
@Thug I am following their "best practice" of the "outside app code" pattern and it works if I execute coverage run -m pytest or python -m pytest but fails if I run pytest directly with failed to load module errors.Anoxemia
@TheIncorrigible1 Really glad to see your comment here as I was stumped for a moment. I'm unsure if this is the same issue, but I've commented on GitHub: github.com/pytest-dev/pytest/issues/6370#issuecomment-575423003Judkins
@Judkins I've since resolved the problem I was running into by installing my source as a package into the virtual environment which required a deep foray into python packaging and distutils/setuptools.Anoxemia
confirm_ this works only as @burszely suggestedDresden
Thank you @Thug so much. Was struggling with this. So dumb!Egan
R
106

I already had an __init__.py file in the /App/App directory and wanted to run tests from the project root without any path-mangling magic:

 python -m pytest tests

The output immediately looks like this:

➟  python -m pytest tests
====================================== test session starts ======================================
platform linux -- Python 3.5.1, pytest-2.9.0, py-1.4.31, pluggy-0.3.1
rootdir: /home/andrew/code/app, inifile: 
plugins: teamcity-messages-1.17
collected 46 items 

... lines omitted ...

============================= 44 passed, 2 skipped in 1.61 seconds ==============================
Rapture answered 9/3, 2016 at 16:16 Comment(2)
Were you able to figure out the reason why launching py.test directly fails to discover the /App/App?Ceroplastics
well python does add the current directory to the pythonpath, so you are still using path-mangling magic, btw that's why it works!Darceydarci
W
42

I had a similar problem and had to delete __init__.py from the root and add an __init__.py to the tests folder.

Watthour answered 20/8, 2020 at 14:22 Comment(2)
I had the same problem and needed to delete the init from the root. Does anyone know why init in root would cause havoc to pytest?Lye
I had init.py under src/app/ and adding another to src/tests/ worked for me, no idea why.Shanan
L
39

Running pytest with the python -m pytest command helps with this exact thing.

Since your current package is not yet in your $PYTHONPATH or sys.path - pytest gets this error.

By using python -m pytest you automatically add the working directory into sys.path for running pytest. Their documentation also mentions:

This is almost equivalent to invoking the command line script pytest

Lowestoft answered 4/5, 2021 at 13:13 Comment(2)
the best answer for python 3.8Cockboat
It is the same for me. I had init.py but it still did not work. While I found out python -m pytest . works, I could not figure it out why pytest . does not work. Thanks for a good and brief explanation.Grosberg
L
29

So you are running py.test from /App. Are you sure /App/App is in your $PYTHONPATH?

If it's not, code that tries to import app will fail with such a message.

EDIT0: including the info from my comment below, for completeness.

An attempt to import app will only succeed if it was executed inside /App/App, which is not the case here. You probably want to make /App/App a package by putting __init__.py inside it, and change your import to qualify app as from App import app.

EDIT1: by request, adding further explanation from my second comment below.

By putting __init__.py inside /App/App, that directory becomes a package. Which means you can import from it, as long as it - the directory - is visible in the $PYTHONPATH. I.e. you can do from App import app if /App is in the $PYTHONPATH. Your current working directory gets automatically added to $PYTHONPATH, so when you run a script from /App, the import will work.

Louth answered 8/1, 2014 at 1:5 Comment(4)
I have run pip install -e . on /App, so the package is installed to the /usr/local library. I would think this adds my folder to the path?Kweisui
There's no reason for /App/App to automatically be added into the $PYTHONPATH, regardless of where you installed pip. An attempt to import app will only succeed if it was executed inside /App/App, which is not the case here. You probably want to make /App/App a package by putting __init__.py inside it, and change your import to qualify app as from App import app.Louth
My test can be ran now. I am still confused about the $PYTHONPATH part. Is it that if I add init.py to my /App/App folder, python will automatically insert the /App/App folder into the path?Kweisui
@zsljulius: by putting __init__.py inside /App/App, that directory becomes a package. Which means you can import from it, as long as it - the directory - is visible in the $PYTHONPATH. I.e. you can do from App import app if /App is in the $PYTHONPATH. Your current working directory gets automatically added to $PYTHONPATH, so when you run a script from /App, the import will work.Louth
L
14

I also got same error while running test cases for my app located as below

myproject
  --app1
    --__init.py__
    --test.py
  --app2
    --__init.py__
    --test.py
  --__init.py__

I deleted my myproject's init.py file to run my test cases.

Lewandowski answered 11/12, 2018 at 6:13 Comment(1)
Worked for me in PycharmMulch
A
8

TL;DR

You might as well add an empty conftest.py file to your root app folder.

(if you take a look at the question folder structure, that would be the same level as the "Tests" folder, not inside of it).

More info:

Pytest looks for conftest.py files inside all your project folders.

conftest.py provides configuration for the file tree pytest finds it in. Because pytest somehow scans all subdirectories starting from conftest.py folder, it should find packages/modules outside the tests folder (as long as a conftest.py file is in your app root folder).

Eventually, you might want to write some code in your empty conftest.py, specially to share fixtures among different tests files, in order to avoid duplicate code. Afterall, the DRY principle (Don't Repeat Yourself) should also be follwed when writing tests.

Adding __init.py__ to the tests folder also should help pytest to find modules throughout your application. However, note that Python 3.3+ has implicit namespace packages that allow it to create a packages without an __init__.py file. That been said, creating __init__.py files for this specific purpose seems more like a a workaround for pytest than a python requirement. More about that in: Is __init__.py not required for packages in Python 3.3+

Ameline answered 28/4, 2022 at 19:52 Comment(1)
Adding conftest.py to the root folder helped. root units_under_tests tests conftest.py Without conftest.py in the place got the error when running pytest from the command line.Calcific
D
2

I got the similar issue. And after trying multiple things including installing pytest on virtual environment and adding/removing __init__.py file from the package, none worked for me.

Solution that worked for me is(windows solution): Added Project folder(not package folder) to python path(set PYTHONPATH=%PYTHONPATH%;%CD%)

Ran my script from Project Folder and boom, it worked.

Dercy answered 3/6, 2020 at 8:34 Comment(0)
O
2

I hit the same issue.

my-app
--conf
--my-app
--tests

I set the __init__.py files. I added a conftest.py ( for sharing pytest.fixtures ). I added this to my Poetry file ( pyproject.toml:

[tool.pytest.ini_options]
pythonpath = [
  "."

Turned out it was my use of hyphens and not underscores ! Noo...

# pytest can't find Module
--my-app

# works
--my_app
Overarch answered 31/1, 2023 at 11:40 Comment(0)
S
2

I have the following project structure

myproject
      manage.py
      pyproject.toml
      --apps
        --app1
        --app2
      --tests
        --apps
          -- app1
          -- app2
      --config
         --settings
            base.py
            local.py

Adding init.py did not help. I was able to solve the issue by adding the following to pyproject.toml

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "config.settings.local" 
Shiftless answered 16/5, 2023 at 4:14 Comment(0)
D
2

Solution is very simple: set PYTHONPATH environment variable to . (current directory).

# Windows
set PYTHONPATH=.

# Linux 
export PYTHONPATH=.
Desirae answered 30/6, 2023 at 7:4 Comment(0)
R
1

What worked for me: I had to make absolute imports in my test file and call python -m test in the root folder.

Rustication answered 15/12, 2022 at 0:6 Comment(3)
This runs the regression test package and not pytest: docs.python.org/3/library/test.htmlAvigdor
I don't get why this called my test modules then...Rustication
For it worked with python -m pytestGaribaldi
A
0

Make sure you do not have an __init__(self) method in your testcase.

Adair answered 20/7, 2023 at 17:55 Comment(0)
U
0

I added the following to the init.py within the tests directory:

import sys
import os
sys.path.append(os.path.abspath('./App'))

Whilst calling from the Root App directory.

Underachieve answered 10/10, 2023 at 8:30 Comment(0)
F
0

I ran into this issue and had trouble finding an answer that worked for me. This was my project structure:

project_root
  app_folder
    file_under_test1.py
    file_under_test2.py
  tests
    tests_for_file1.py
    tests_for_file2.py
  Dockerfile
  helmvalues.yml
  pytest.ini

I followed the advice in one of the early comments to look at pytest's recommendations: https://docs.pytest.org/en/latest/goodpractices.html#choosing-a-test-layout-import-rules, thanks @jamesc

This lead me to add the following to my pytest.ini, then things worked:

[pytest]
pythonpath = app_folder

Then I was able to just run $ pytest in my project_root and the imports in the test files worked. I was able to import in my test files in the same way I did the imports in my app files.

I did not have to add __init__.py files anywhere either.

Freshen answered 21/2, 2024 at 18:50 Comment(0)
R
-2

This worked for me: Went to parent app, and pip install -e . (install a local and editable app).

Ranitta answered 18/5, 2021 at 9:39 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.