pytest cannot import module while python can
Asked Answered
H

45

320

I am working on a package in Python. I use virtualenv. I set the path to the root of the module in a .pth path in my virtualenv, so that I can import modules of the package while developing the code and do testing (Question 1: is it a good way to do?). This works fine (here is an example, this is the behavior I want):

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python
Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from rc import ns
>>> exit()
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ python tests/test_ns.py 
issued command: echo hello
command output: hello

However, if I try to use PyTest, I get some import error messages:

(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ pytest
=========================================== test session starts ============================================
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/zz/Desktop/GitFolders/rc, inifile: 
collected 0 items / 1 errors 

================================================== ERRORS ==================================================
________________________________ ERROR collecting tests/test_ns.py ________________________________
ImportError while importing test module '/home/zz/Desktop/GitFolders/rc/tests/test_ns.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ns.py:2: in <module>
    from rc import ns
E   ImportError: cannot import name ns
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================= 1 error in 0.09 seconds ==========================================
(VEnvTestRc) zz@zz:~/Desktop/GitFolders/rc$ which pytest
/home/zz/Desktop/VirtualEnvs/VEnvTestRc/bin/pytest

I am a bit puzzled, it looks like this indicates an import error, but Python does it fine so why is there a problem specifically with PyTest? Any suggestion to the reason / remedy (Question 2)? I googled and stack-overflowed the 'ImportError: cannot import' error for PyTest, but the hits I got were related to missing python path and remedy to this, which does not seem to be the problem here. Any suggestions?

Harvison answered 19/1, 2017 at 17:51 Comment(1)
This also might be some missing import issueNalchik
H
278

Found the answer:

DO NOT put a __init__.py file in a folder containing TESTS if you plan on using pytest. I had one such file, deleting it solved the problem.

This was actually buried in the comments to the second answer of PATH issue with pytest 'ImportError: No module named YadaYadaYada' so I did not see it, hope it gets more visibility here.

Harvison answered 19/1, 2017 at 21:30 Comment(14)
Funny. I had the same issue and I had to add init.py to my tests folder.Personalty
Yeah, this is not a general solution (even though it was in your case), to understand why this should be read: docs.pytest.org/en/latest/goodpractices.html#test-package-nameDissimulate
This information is WRONG and misleading! After adding init.py into the test folder everything worked fineIreland
@LeonardoOstan it may be wrong for you, but it doesn't mean this information is wrong in general. In my case it solved the issue.Beetner
This is wrong now. My tests are located in project_root/tests/ and source code in project_root/myapp/, I placed an init file in project_root/tests/__init__.py to be able to import the helper module project_root/tests/helper.py in project_root/tests/test_foo.py. Inside project_root/ I can run tests with python -m pytest -vv tests/.Hetero
@Harvison very strange as this worked for me as well. when ran locally and in the pipeline. thank you for your observation and suggestion :)Lexicology
I had exact issue. And for me, it's exactly the test module naming problem: starts with "test_". To fix it, rename it to avoid lowercased test_Jugulate
if you have tests starting wtih test_ in a folder, __init__.py shouldn't be there. Otherwise you will get the import errors.Aguila
As the above comment by @Personalty I had the same issue and I had to add init.py to my tests folder to correct itBearish
I want to be able to run from cmdline the tests.* files in the tests directory. So it would seem that __init__.py were needed. So this solution is not a good one for meSurrebutter
I followed this other answer https://mcmap.net/q/98841/-pytest-cannot-import-module-while-python-can that sayss to remove __init__.py from the project root directory. That works for me and without introducing additional usability issues.Surrebutter
Does anyone know why this works?Roots
This works using poetry poetry run python -m pytest tests/Hogfish
This does not work.Lathi
A
203

I can't say I understand why this works, but I had the same problem and the tests work fine if I run python -m pytest.

I'm in a virtualenv, with pytest also available globally:

(proj)tom@neon ~/dev/proj$ type -a python
python is /home/tom/.virtualenvs/proj/bin/python
python is /usr/bin/python

(proj)tom@neon ~/dev/proj$ python -V
Python 3.5.2

(proj)tom@neon ~/dev/proj$ type -a pytest
pytest is /home/tom/.virtualenvs/proj/bin/pytest
pytest is /usr/bin/pytest

(proj)tom@neon ~/dev/proj$ pytest --version
This is pytest version 3.5.0, imported from /home/tom/.virtualenvs/proj/lib/python3.5/site-packages/pytest.py
Archdeaconry answered 26/3, 2018 at 10:1 Comment(9)
Also did the job for me, the thing is,, it's get run by the python version defined instead of your v.env.Wilkerson
one reason might be that python -m pytest [...] "will also add the current directory to sys.path."Zacynthus
Had the same in Windows 10, and running python -m pytest solved itHers
This worked for as well inside my virtual environment I had to run python3 -m pytestZinnia
Based on the comment by @Zacynthus I'm using PYTHONPATH=.:./src pytest as a make target.Crean
python -m pytest runs a __main__.py file while calling a module directly uses __init__.py. The poster's problem is that he has an __init__.py in his tests directoryDeontology
+1 In my case i also had to cd in app (src) directory from root dir where are stored global settings, docker files and etc.Strobile
Didn't work for me.Lathi
Deactivating and Reactivating my virtualenv solved the issue for me. You don't have to do python -m pytest.Contrail
L
82

I just solved this by removing the __init__.py in my project root:

.
├── __init__.py <--- removed
├── models
│   ├── __init__.py
│   ├── address.py
│   ├── appointment.py
│   └── client.py
├── requirements.txt
├── setup.cfg
├── tests
│   ├── __init__.py
│   ├── models
│   │   ├── __init__.py
│   │   ├── appointment_test.py
│   │   └── client_test.py
│   └── other_test.py
└── script.py
Lyricism answered 17/5, 2018 at 20:57 Comment(9)
The accepted answer __init__.py file in a folder containing TESTS did not solve my problem. This one worked. I guess it's because of the file hierarchy.Fascista
I have removed __init__.py file. I was still facing issue. Adding conftest.py file to the root directory worked for me.Power
I'd expect conftest.py to be in /tests not the rootLyricism
Getting the conftest.py file to the root directory also fixed it for me. Don't have an init.py file in the tests directoryPint
This solution worked for me but does anyone know this would cause an import error?Specht
Accidentally there was a init file in my root folder which caused the pytest to misbehave. After removing it worked.Symmetrical
This was also what fixed it for me! In my case I think the issue was also that the my project structure was proj_folder as a root and it had two children proj_folder/project_folder and proj_folder/tests (so same name for project root and subdirectory). So then in one of the test files in test i had an import like: from proj_folder import main. Now, because I had an init in the project root, pytest was attempting to get a main module that was actually in project_folder/project_folder!Tauro
This Many answers said it's necessary to remove __init__.py from the tests directory - but I don't want that. This solved the problem without introducing additional issues.Surrebutter
I have no such file in my project root. This is not the answer.Lathi
S
41

I had the same problem but for another reason than the ones mentioned:

I had py.test installed globally, while the packages were installed in a virtual environment.

The solution was to install pytest in the virtual environment. (In case your shell hashes executables, as Bash does, use hash -r, or use the full path to py.test)

Stephanystephen answered 5/1, 2018 at 19:59 Comment(4)
Just realized I had the same sneaky issue, using anaconda. I forgot to add pytest in the virtualenv created by conda, yet pytest it is available in anaconda's root environment. Therefore pytest could be found, but not any package installed in the environment.Berliner
I had the same issue. pytest was installed globally and not in the virtualenv. pip3 install pytest inside virtualenv fixed the issue.Initiation
I even had it installed in my venv but for some reason it wasn't picking it up. (which pytest showed the wrong version) Deactivating and reactivating the venv fixed everything.Stateroom
Doesn't work in my case.Lathi
G
38

Had a similar issue and it worked when I added __init__.py file under tests directory.

Goatsucker answered 3/7, 2019 at 2:40 Comment(3)
And, conftest.py as well in my case.Motherly
This doesn't work in my case.Lathi
While running python -m pytest . was able to discover and execute my tests, using VSCode to run tests required adding__init__.py so the IDE could discover and run my tests.Underworld
H
33

Simply put an empty conftest.py file in the project root directory, because when pytest discovers a conftest.py, it modifies sys.path so it can import stuff from the conftest module. A general directory structure can be:

Root
├── conftest.py
├── module1
│   ├── __init__.py
│   └── sample.py
└── tests
    └── test_sample.py
Handbook answered 25/7, 2020 at 15:8 Comment(4)
This is the best answer. Forget all that __init__.py craziness.Install
Didn't work for me. All very odd.Lathi
Didn't work for me as well.Timetable
Worked for me. I believe this is the long-term solution for anyone who has it working with python -m pytest but doesn't want to add the extra verbiage every timePsychomotor
P
26

As of pytest 7.0, you can now add pythonpath in pytest.ini. No need to add __init__.py or conftest.py in your root directory.

[pytest]
minversion = 7.0
addopts = --cov=src
pythonpath = src
testpaths =
    tests

You can run pytest without any parameters.

https://docs.pytest.org/en/7.0.x/reference/reference.html#confval-pythonpath

Update:

Here's a sample repo on how I setup my projects which uses the above config:

https://github.com/ianpogi5/pytest-path

Packton answered 16/8, 2022 at 22:17 Comment(15)
This is by far the cleanest and most effective answer here. No need to change folder structure; you can keep your tests separated from the src, nice, and clean; no need to bloat your code with sys.path in each single file; is supported officially and well documented; no need to manually edit PATH (which is not easily reproducible by default on other machines); and it works like a charm.Cutlip
By far the best answer I found. This should be the content of a community postArcadian
Still doesn't work (pytest 7.3.1). See my answer: import my_other_file in __main__.py still causes a fail, even when this package contains __init__.py (and even when I use these configuration settings in pytest.ini).Lathi
@mikerodent do you have sample github repo?Packton
Glad you asked. Just done it: github.com/Mrodent/pytest_probs/tree/main. On my system this wouldn't clone (SSH problem?) but you can download the .zip. Then see what I say in README.md. Interested to know whether you find the same prob as me... or not!Lathi
@mikerodent You have assert False github.com/Mrodent/pytest_probs/blob/… in your tests that's why all your tests fails. I changed it to True, now all tests passed. I also suggest you create venv to isolate your environment. Those are the only 2 things I changed.Packton
Hahaha. You didn't bother reading my README: "3 out of 4 tests in test_basic will fail, as intended". Now, very importantly, I need an accurate answer to this: in conftest.py, please COMMENT OUT the line "sys.path.insert(0, src_core_dir_path_str)" ... then run "pytest" again, and tell me whether or not you get a ModuleNotFound error. Everything is done in a VE in my setup. In fact this is irrelevant.Lathi
@mikerodent since your code is in src/core, set pythonpath = src/core in your pytest.ini. Your error will be gone.Packton
That works. But it's then exactly the same as extending sys.path manually in conftest.py! I.e. you have to include, manually, every single directory where you need .py files to be imported into other files. For example, if you have a directory (and module) src/matching you would then have to add "src/matching" to pythonpath in pytest.ini. Your answer here obviously implies, wrongly, that pythonpath=src will recursively make all directories in the directory tree under src work as they should. Sadly it doesn't do that, which you now know, so you should edit your answer accordingly.Lathi
@mikerodent you only need to include the root of your source files which in your case src/core. For sub-directories you will always have __init__.py in them so they will always work. This is the standard practice for importing files in sub directories. Without it, your app will not run.Packton
@mikerodent I've created a sample repo which you can use as a reference. The link to the repo is in my answer.Packton
That doesn't in fact run (running > python ...) on my machine: I had to get rid of the "dots" on the import lines in coffee\__main__.py and coffee\main.py. When I did that I could run as Python, but pytest failed on the line from americano import americano: ImportError. There's no point running pytest on something which is not valid, runnable Python in the first place. Does this run as Python on your machine? PS we probably need to move to chat ...Lathi
@mikerodent It runs without issues even on github action. Works with python 3.9, 3.10 and 3.11. I got more than 30 projects using the same structure, many different devs and deployment machines.Packton
Let us continue this discussion in chat.Packton
This is the only thing that worked for me! However, it complaint that addopts = --cov=src could not reconize. removed it and worked fine (wihtout relative imports)Marciano
L
23

2024-02-10 PATH AND VISIBILITY MYSTERIES EXPLAINED

I originally answered this in October 2021. I had struggled with this problem for ages. As described in my original answer below NONE of the solutions here worked. Over 2 years I got 24 upvotes (and 2 downvotes) so it seemed like others were having similar intractable difficulties. I had reluctantly concluded that I had to manipulate sys.path to get pytest to be able to "see" the files that I thought it should see.

I was wrong and failed to understand something about paths. And CRUCIALLY this involves the running of a project (as most of my projects are) where the application is run by using this command (in W10):

> python src\core

In other words, from the start, the CWD is not the current (project root) directory, but a subdirectory [project root directory]\src\core (which contains file __main__.py)

This is where the problem arose. If you are not in fact running a file in the root directory of your project you need to be aware that putting the tests directory in your root directory will plunge you into a world of pain and bafflement: sibling .py files will bafflingly not be "found" in your main "run" directory, i.e. where CWD is, i.e. by virtue of your command line.

Instead, in my case, I need the root "tests" directory to be a subdirectory of src\core (relative to the root directory of my project).

As a more general rule: wherever the CWD of your project is as you run it as an application is the place where you must put your "tests" directory.

Hope this helps someone.


-------------- MY ORIGINAL NAIVE, INCORRECT ANSWER OF 2021-10:

ANOTHER SUGGESTION

I explored this question and various others on SO and elsewhere... all the stuff about adding (or removing) an empty __init__.py in and/or conftest.py in various parts of the project directory structure, all the stuff about PYTHONPATH, etc., etc.: NONE of these solutions worked for me, in what is actually a very simple situation, and which shouldn't be causing any grief.

I regard this as a flaw in pytest's current setup. In fact I got a message recently from someone on SO who clearly knew his stuff. He said that pytest is not designed to work with (as per Java/Groovy/Gradle) separate "src" and "test" directory structures, and that test files should be mingled in amongst the application directories and files. This perhaps goes some way to providing an explanation ... however, tests, particularly integration/functional tests, don't always necessarily correspond neatly to particular directories, and I think pytest should give users more choice in this regard.

Structure of my project:

project_root
    src
        core
            __init__.py
            __main__.py
            my_other_file.py 
    tests
        basic_tests
            test_first_tests.py

The import problem posed: very simply, __main__.py has a line import my_other_file. This (not surprisingly) works OK when I just run the app, i.e. run python src/core from the root directory.

But when I run pytest with a test which imports __main__.py I get

ModuleNotFoundError: No module named 'my_other_file'

on the line in __main__.py that tries to import "my_other_file". Note that the problem here, in my case, is that, in the course of a pytest test, one application file fails to find another application file in the same package.

USING PYTHONPATH
After a lot of experimentation, and putting an __init__.py file and a confest.py file in just about every directory I could find (I think the crucial files were __init__.py added to "tests" and "basic_tests", see above directory structure), and then setting PYTHONPATH to as follows

PYTHONPATH=D:\My Documents\software projects\EclipseWorkspace\my_project\src\core

... I found it worked. Imports in the testing files had to be tweaked a bit, the general pattern being from core import app, project, but the test files were able to "see" core, and crucially there was no need to mess around with the import commands in the app files.

HOWEVER... for some reason the tests now run much slower using this method! Compared to my solution below, where the core package can be seen to be loaded just once, my suspicion is that the PYTHONPATH solution probably results in vast amounts of code being reloaded again and again. I can't yet confirm this, but I can't see any other explanation.

THE ALTERNATIVE

As I say, I regard this as a flaw in pytest's setup. I have absolutely no idea what pytest does to establish a common-sense setup for sys.path, but it's obviously getting it wrong. There should be no need to rely on PYTHONPATH, or whatever, and if indeed this is the "official" solution, the documentation on this subject is sorely lacking.

The ONLY working solution, at least on my machines (OS W10 and Linux, as at pytest 7.3.1), is to add the application packages to sys.path. It is undesirable to mess with sys.path, but in this case nothing else at all works for me.

The most obvious place to do this is conftest.py, which gets executed at the start of each pytest run, and which is kept the project root directory. It involves no modification of the app files. Typically (for the above directory/files setup):

this_file_path = pathlib.Path(__file__)
src_core_dir_path_str = str(this_file_path.parent.joinpath('src', 'core'))
sys.path.insert(0, src_core_dir_path_str)

I am currently (2023-08) using pytest v 7.3.1, and have also tried editing pytest.ini, as suggested by ian's 2022 answer, where it is suggested that these configurations in pytest.ini are a new thing to solve the problem since v7 (release 2021-12). In my machines this does not solve the problem: without manually altering sys.path pytest's attempt to import __main__.py in my example fails as before: because import my_other_file raises ModuleNotFoundError: No module named 'my_other_file'.

PS I have now set up a minimal git repo illustrating the problem: download the .zip at https://github.com/Mrodent/pytest_probs/tree/main, and read what I say in README.md. Interested to know if anyone gets different results to what I get.

--

Lathi answered 23/10, 2021 at 19:37 Comment(2)
Thanks for your comprehensive answer - it's awesome and so clear! Could you please clarify what exactly to do with the "clunky but effective solution" you provide to fix the permanent sys.path addition? Where can this code be run? After each pytest run?Prerecord
"He said that pytest is not designed to work with (as per Java/Groovy/Gradle) separate "src" and "test" directory structures" This is false. A lot of information in this answer is incorrect and encouraging bad practices, like manipulating sys.path manually,Worry
S
17

In my case I am working in a container and unfortuantely pytest has the tendency to use python2.7 rather than my python3 interpreter of choice.

In my case this worked:

python3 -m pytest

My folder structure

/
app/
-module1.py
-module2.py
-tests/
--test_module1.py
--test_module2.py
requirements.txt
README.md
Sweat answered 17/8, 2020 at 21:42 Comment(0)
B
13

This problem will happen if you have a tests.py file and a tests folder with tests/__init__.py.

During the collection pytest finds the folder, but when it tries to import the test files from the folder, tests.py file will cause the import problem.

To fix simply remove the tests.py file and put all your tests inside the tests/ folder.

For your specific case the fix will be precisely:

  • Remove the file /home/zz/Desktop/GitFolders/rc/tests.py
  • Make sure /home/zz/Desktop/GitFolders/rc/tests/__init__.py is present
Buchan answered 6/6, 2018 at 21:53 Comment(0)
F
10

I solved my problem by setting the PYTHONPATH in Environment Variables for the specific configuration I'm running my tests with.

While you're viewing the test file on PyCharm:

  1. Ctrl + Shift + A
  2. Type Edit Configurations
  3. Set your PYTHONPATH under Environment > Environment variables.

UPDATE

  1. Move into your project's directory root
  2. Create a virtual environment
  3. Activate your newly created virtual environment
  4. Set the variable $PYTHONPATH to the root of your project and export it:
export PYTHONPATH=$(pwd)
  1. Do not remove the __init__.py from the tests/ directory or from the src/ directory.

Also note:

  • The root of your directory is not a python module so do NOT add an __init__.py
  • conftest.py is not necessary in the root of your project.
  1. The $PYTHONPATH var will only be available during the current terminal/console session; so you will need to set this each time. (You can follow the steps previous to this update if you are working in pycharm).
Fourflush answered 14/7, 2020 at 10:44 Comment(3)
As an explicit example, I set the Environment variables: field in my PyCharm pytest run configuration to PYTHONPATH=/my_projects_root_dir:$PYTHONPATH.Bide
This solved the issue for me: "The root of your directory is not a python module so do NOT add an init.py" By just removing the init.py, got me running again.Intermarriage
This worked for me. I don't understand why setting the pythonpath configuration option doesn't do the trick[1]. Also, in my case I have no init.py in the tests folders. [1]: docs.pytest.org/en/7.1.x/reference/…Jokester
T
8

I had a similar issue, exact same error, but different cause. I was running the test code just fine, but against an old version of the module. In the previous version of my code one class existed, while the other did not. After updating my code, I should have run the following to install it.

sudo pip install ./ --upgrade

Upon installing the updated module running pytest produced the correct results (because i was using the correct code base).

Tankard answered 16/2, 2018 at 1:4 Comment(2)
This worked for me! My module was at the same time installed as a library in the docker container I was using to run pytest. When running the python interpreter it would find the updated code, but pytest would continue to find the code as it was when the library was first installed. Running pip install ./ --upgrade updated the installed version of the lib with the latest code, and enabled pytest to find this latest version too.Adelaideadelaja
Same for me, conda update --all resolved the problemWilhelminawilhelmine
E
7

In my case, the import error occurred because the package is pointing to another package/directory with the same name and its path is one level above the folder I actually wanted. I think this also explains why some people need to remove _ init _.py while others need to add back.

I just put print(the_root_package.__path__) (after import the_root_package) in both python console and pytest scripts to compare the difference

BOTTOM LINE: When you do python, the package you import may be different from the package when you run pytest.

Either answered 25/4, 2018 at 17:36 Comment(0)
M
7

Please check here: https://docs.pytest.org/en/documentation-restructure/background/pythonpath.html

I has an issue with pytest (that was solved using python -m pytest); the error was

FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/lib/python3.9/site-packages/...

I found the problem was missing __init__.py in tests/ and tests/subfolders.

Marrufo answered 19/5, 2021 at 21:5 Comment(2)
Didn't work for meLathi
Didn't work for meHoffarth
T
6

I had placed all my tests in a tests folder and was getting the same error. I solved this by adding an __init__.py in that folder like so:

.
|-- Pipfile
|-- Pipfile.lock
|-- README.md
|-- api
|-- app.py
|-- config.py
|-- migrations
|-- pull_request_template.md
|-- settings.py
`-- tests
    |-- __init__.py <------
    |-- conftest.py
    `-- test_sample.py
Torey answered 5/3, 2020 at 7:30 Comment(2)
Didn't work for me.Lathi
what error did you get @mikerodentTorey
B
5

Install the packages into Your virtual environment.
Then start a new shell and source Your virtual environment again.

Bander answered 3/4, 2018 at 8:9 Comment(0)
S
4

Here's a medium article! describing the problem!

The issue is which pytest you are using and your use of a virtual environment. If you have installed pytest system-wide, in other words, outside of a virtual environment, pytest has a nasty habit of only looking outside your virtual environment for modules! If your project is using a module that is only installed in your virtual environment, and you’re using a system-wide pytest, it won’t find the module, even if you’ve activated the virtual environment.1

Here’s the step-by-step:1

  1. Exit any virtual environment
  2. Use Pip to uninstall pytest
  3. Activate your project’s virtual environment
  4. Install pytest inside the virtual environment
  5. pytest will now find your virtual-environment-only packages!
Sponson answered 18/5, 2021 at 8:22 Comment(1)
Didn't work for meLathi
S
3

The answer above not work for me. I just solved it by appending the absolute path of the module which not found to the sys.path at top of the test_xxx.py (your test module), like:

import sys
sys.path.append('path')
Subcontract answered 11/4, 2019 at 8:44 Comment(1)
Instead of putting these lines at the top of my test_main.py, I put it in conftest.py in my test directory, and it worked. Thanks for providing a programmatic solution, instead of file litter.Trovillion
J
3

I was getting this using VSCode. I have a conda environment. I don't think the VScode python extension could see the updates I was making.

python c:\Users\brig\.vscode\extensions\ms-python.python-2019.9.34911\pythonFiles\testing_tools\run_adapter.py discover pytest -- -s --cache-clear test
Test Discovery failed:

I had to run pip install ./ --upgrade

Johannajohannah answered 26/9, 2019 at 19:49 Comment(1)
That pip command returns an error: Directory './' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.Leatherman
V
3

I was experiencing this issue today and solved it by calling python -m pytest from the root of my project directory.

Calling pytest from the same location still caused issues.

My Project dir is organized as:

api/
 - server/
  - tests/
      - test_routes.py
  - routes/
      - routes.py
 - app.py

The module routes was imported in my test_routes.py as: from server.routes.routes import Routes

Hope that helps!

Vday answered 31/10, 2019 at 15:48 Comment(1)
Thanks for the reminder, I've had to use the trick in the past and it's in the pytest documentation.Metaphosphate
M
3

I disagree with the posts saying that you must remove any __init__.py files. What you must instead do is alter the sys.path.

Run an experiment where you print sys.path when running the code normally. Then print sys.path while running the code via pytest. I think you will find that there is a difference between these two paths, hence why pytest breaks.

To fix this, insert the path from the first experiment at the 0th index of the second.

Let '/usr/exampleUser/Documents/foo' be the first element of print(sys.path) for experiment 1.

Below is code that should fix your issue:

import sys sys.path[0] = '/usr/exampleUser/Documents/foo'

Put this at the top of your file, before your actual import statement.

Source: I was dealing with this myself and the above process solved it.

Minute answered 24/5, 2020 at 0:35 Comment(2)
The only solution from listed here that worked for me.Negligible
Yes, even now, version 7.3.1., messing with sys.path appears to be the only solution. Otherwise files are simply unable to import sibling .py files (i.e. in the same directory). Both are indicators that the makers of pytest have a fundamental design flaw here. Or potentially that the correct practice is not properly documented.Lathi
D
3

Points to be observed in the same order as below:

  1. Make sure that every folder and subfolder of your app has a __init__.py file.
  2. Make sure that the tests folder(module) is inside the app folder(module).
  3. Try pytest command and if that doesn't work try python3 -m pytest .
Duo answered 13/7, 2022 at 10:39 Comment(0)
G
3

The TestCase directory must be a Python Package

Governess answered 10/1, 2023 at 14:36 Comment(0)
A
2

Another special case:

I had the problem using tox. So my program ran fine, but unittests via tox kept complaining. After installing packages (needed for the program) you need to additionally specify the packages used in the unittests in the tox.ini

[testenv]
deps =
    package1
    package2 
...
Adelladella answered 9/1, 2019 at 10:29 Comment(0)
H
2

If it is related to python code that was originally developed in python 2.7 and now migrated into python 3.x than the problem is probably related to an import issue.

e.g. when importing an object from a file: base that is located in the same directory this will work in python 2.x:

from base import MyClass

in python 3.x you should replace with base full path or .base not doing so will cause the above problem. so try:

from .base import MyClass
Havana answered 19/8, 2019 at 13:29 Comment(0)
P
2

Yet another massive win for Python's import system. I think the reason there is no consensus is that what works probably depends on your environment and the tools you are using on top of it.

I'm using this from VS Code, in the test explorer under Windows in a conda environment, Python 3.8.

The setup I have got to work is:

mypkg/
    __init__.py
    app.py
    view.py
tests/
    test_app.py
    test_view.py

Under this setup intellisense works and so does test discovery.

Note that I originally tried the following, as recommended here.

src/
    mypkg/
        __init__.py
        app.py
        view.py
tests/
    test_app.py
    test_view.py

I could find no way of getting this to work from VS Code because the src folder just blew the mind of the import system. I can imagine there is a way of getting this to work from the command line. As a relatively new convert to Python programming it gives me a nostalgic feeling of working with COM, but being slightly less fun.

Puisne answered 26/3, 2020 at 11:39 Comment(0)
I
2

My 2 cents on this: pytest will fail at chance if you are not using virtual environments. Sometimes it will just work, sometimes not.

Therefore, the solution is:

  • remove pytest with pip uninstall
  • create your venv
  • activate your venv
  • pip install your project path in editable mode, so it will be treated by pytest as a module (otherwise, pytest wont find your internal imports). You will need a setup.py file for that
  • install your packages, including pytest
  • finally, run your tests

The code, using windows PowerShell:

pip uninstall pytest
python.exe -m venv my_env
.\my_env\Scripts\activate
(my_env) pip install -e .
(my_env) pip install pytest pytest-html pandas numpy

Then finally

(my_env) pytest --html="my_testing_report.html"

An example of setup.py, for pip install -e:

import setuptools

setuptools.setup(
    name='my_package',
    version='devel',
    author='erickfis',
    author_email='[email protected]',
    description='My package',
    long_description='My gooood package',
    packages=setuptools.find_packages(),
    classifiers=[
        'Programming Language :: Python :: 3',
        'Operating System :: OS Independent',
    ],
    include_package_data=True
)
Ithnan answered 22/4, 2020 at 20:17 Comment(2)
Recreating virtual environment solved the issue for me!Frere
I have only ever used virtual environments. This is not the solution in my case.Lathi
C
2

I find the answer in there :Click here

If you have other project structure, place the conftest.py in the package root dir (the one that contains packages but is not a package itself, so does not contain an init.py)

Corkwood answered 29/7, 2021 at 1:53 Comment(0)
P
2

update PYTHONPATH till src folder

export PYTHONPATH=/tmp/pycharm_project_968/src
Preceptory answered 2/11, 2021 at 12:4 Comment(0)
H
1

For anyone who tried everything and still getting error,I have a work around.

In the folder where pytest is installed,go to pytest-env folder.

Open pyvenv.cfg file.

In the file change include-system-site-packages from false to true.

home = /usr/bin
include-system-site-packages = true
version = 3.6.6

Hope it works .Don't forget to up vote.

Hyperpyrexia answered 30/11, 2018 at 6:36 Comment(1)
No such folder. There's only pytest under site-packages, and no .cfg file. Strange.Lathi
P
1

Kept everything same and just added a blank test file at the root folder .. Solved it

Here are the findings, this problem really bugged me for a while. My folder structure was

mathapp/
    - server.py  
    - configuration.py 
    - __init__.py 
    - static/ 
       - home.html  
tests/            
    - functional 
       - test_errors.py 
    - unit  
       - test_add.py

and pytest would complain with the ModuleNotFoundError and gives the hint:

make sure your test modules/packages have valid Python names.

I introduced a mock test file at the same level as mathsapp and tests directory. The file contained nothing. Now pytest does not complain.

Result without the file

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 1 item / 1 error

=================================== ERRORS ====================================
_______________ ERROR collecting tests/functional/test_func.py ________________
ImportError while importing test module 'C:\mainak\workspace\0github\python-rest-app-cont\tests\functional\test_func.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests\functional\test_func.py:4: in <module>
    from mathapp.service import sum
E   ModuleNotFoundError: No module named 'mathapp'
=========================== short test summary info ===========================
ERROR tests/functional/test_func.py
!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
============================== 1 error in 0.24s ===============================

Results with the file

$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 2 items

tests\functional\test_func.py .                                          [ 50%]
tests\unit\test_unit.py .                                                [100%]

============================== 2 passed in 0.11s ==============================
Puppy answered 2/6, 2020 at 15:38 Comment(3)
this worked for me after a long time with this issue. seems like pytest is treating the project root as wherever it finds the first test file? surely this is a bug?Skiagraph
Wow this worked for me. I still have to use python3 -m pytest but adding a blank test file solved the issue.Catboat
What is "a blank test file"?Veii
N
1

If you run Pytest from a terminal:

Run pytest with the --import-mode=append command-line flag.

Argument description in the official documentation: https://docs.pytest.org/en/stable/pythonpath.html


UPD: Before I also wrote how to do the same if you use PyCharm, but community does not like extendend answers, so I removed additional information that probably was helpful to someone who have a similar issue.

Negligible answered 10/12, 2020 at 18:30 Comment(4)
OP doesn't mention pycharm anywhere.Mudra
@Mudra I gave a command line command for the OP. The second option is just in case, maybe it will help someone.Negligible
Didn't work for meLathi
I'm trying to run this from PyCharm and having this issue. Would love that infoSanctitude
S
1

In my case the problem was that the filename and the class name were exactly the same: FrameAnalyzer.py and FrameAnalyzer respectively. Once I changed the filename to frame_analyzer.py, everything worked.

Sadoff answered 11/3, 2021 at 9:20 Comment(0)
P
1

For me, this issue was that my test file was named: xxx.test.py

it was resolved my naming the file: xxx_test.py

But i imagine naming it: test_xxx.py would work too.

Phlegmy answered 22/1, 2022 at 21:23 Comment(0)
T
1

My issue was solved by fixing an import. I was importing from project_root.tests.xxxx and when I changed it to from tests.xxxx it worked. Funny thing is Pycharm didn't mark it as an error in the project tree view, I had to go into the file and only there it showed in red.

Topotype answered 21/6, 2022 at 10:27 Comment(0)
V
0

It could be that Pytest is not reading the package as a Python module while Python is (likely due to path issues). Try changing the directory of the pytest script or adding the module explicitly to your PYTHONPATH.

Or it could be that you have two versions of Python installed on your machine. Check your Python source for pytest and for the python shell that you run. If they are different (i.e. Python 2 vs 3), use source activate to make sure that you are running the pytest installed for the same python that the module is installed in.

Vienne answered 19/1, 2017 at 19:40 Comment(0)
D
0

if you need a init.py file in your folder make a copy of the folder and delete init.py in that one to run your tests it works for local projects. If you need to run test regularly see if you can move your init.py to a separate file.

Dias answered 9/9, 2019 at 15:24 Comment(0)
S
0

[Resolved] Before directly jumping into the solution of removing/ adding __init__.py, we might also want to look at how the imports are been done in your classes. Actually, I lost a day playing around with just __init__.py thinking that might be the problem :) However, that was quite informative.

In my case, it was the wrong way of calling classes from one python class to another python class which was throwing ImportError. Fixed the way classes/ modules to be called and it worked like charm. Hope, this helps others as well.

And yes, for similar error, we might have different solutions depending on how the code is written. Better to spend more time on self debugging. Lesson Learnt :) Happy coding!!!

Sharleensharlene answered 16/10, 2019 at 4:16 Comment(1)
Could you give some examples of the wrong way and the right way?Cher
M
0

I had a similar problem just recently. The way it worked for me it was realizing that "setup.py" was wrong

Previously I deleted my previous src folder, and added a new one with other name, but I didn't change anything on the setup.py (newbie mistake I guess).

So pointing setup.py to the right packages folder did the trick for me

from setuptools import find_packages, setup

setup(
    name="-> YOUR SERVICE NAME <-",
    extras_Require=dict(test=["pytest"]),
    packages=find_packages(where="->CORRECT FOLDER<-"),
    package_dir={"": "->CORRECT FOLDER<-"},
)

Also, not init.py in test folder nor in the root one.

Hope it helps someone =)

Best!

Mcmath answered 13/1, 2021 at 4:6 Comment(1)
Voting up since it helped me and not too bad and very quick workaround if project is not organized using best practices. You saved me hours try and fail. Thanks a lot :) docs.pytest.org/en/6.2.x/…Quartana
Y
0

This can be resolved by adding the respective path to the System's Environmental Variables.

Since you are using the virtualenv, the pytest may not read the environmental variables of the virtual machine.

I also faced this issue and resolved it by adding the path to the System's Environmental Variable (PATH)

Yeld answered 15/6, 2021 at 4:4 Comment(0)
L
0

I was having the same problem using pytest under tox. I solved it by including any submodule of my project in my setup.cfg file.

My project structure:

src/
    main_module
       - __init__.py
       ...
       submodule_a
           - __init__.py
           ...
       submodule_b
           - __init__.py
           ...
tests/
    - __init__.py
    - test_a.py
    ...

My setup.cfg file

...
[options]
packages = main_module, main_module.submodule_a, main_module.submodule_b
package_dir = 
    = src
...
Leibowitz answered 16/5, 2022 at 16:39 Comment(0)
N
0

my case:

  • all configurations are correct except I forgot to remove the default my_app/tests.py

    • After removing it, python -m pytest tests/my_app works fine
  • pytest.ini:

[pytest]
DJANGO_SETTINGS_MODULE=necktie_hy.settings
python_files=*/tests/*/test_*.py
python_classes=Test

structure

Naumachia answered 23/5, 2022 at 23:15 Comment(0)
P
0

I faced the same/similar issue when trying to import a new class in my test file. In my case I moved the new import to be the last one in the test file, and then the problem went away. Not entirely sure why though.

Peri answered 29/9, 2022 at 6:44 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Comorin
H
0

I can generally recommend using absolute paths and running the applications and/or tests from the root or perhaps parent folder.

If someone is receiving this error in FastAPI with Uvicorn, simply run e.g.

uvicorn app.main:app --host 0.0.0.0 --port 8080
Hua answered 24/1, 2023 at 11:55 Comment(0)
A
-2

Edit your conftest.py and add following lines of code:

import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(file), '..')))

And if trying to run the test case through terminal, use following ex:

python -m pytest test_some_step_file_steps.py --html=HTML_step_file_output.html --self-contained-html
Arbitration answered 7/10, 2019 at 17:16 Comment(2)
NameError: name 'file' is not defined - what should file equal to?Hispid
it should probably be file, see note.nkmk.me/en/python-script-file-pathRevelry

© 2022 - 2024 — McMap. All rights reserved.