Pytest import error despite using conftest in root directory? - python

I have the following directory structure:
src
\conftest.py
\dir_A
\run_A.py
\test_run_A.py
\dir_B
\run_B.py
where run_A.py has the following code:
from dir_B import run_B
...
When I run pytest from src, I get the error:
ImportError while importing test module '/home/user/src/dir_A/run_A.py'
...
ImportError: cannot import name 'run_B'
Is there a reason why this fails despite using conftest.py?
I'd like to add that running python3 -m dir_A.test_run_A from src works perfectly fine as a test.

You'll find this link helpful: https://docs.pytest.org/en/latest/pythonpath.html
Essentially, when running these tests from the src directory, pytest will walk all the way down to /home/user/src/dir_A/run_A.py. Without any __init__.py files, it will then refuse to walk anywhere else, as it doesn't realize it is part of a larger package.

Related

Gitlab CI Python run test - ModuleNotFoundError: No module named xxx

I saw a lot of questions about importing modules error but I could not manage to solve the problem with Gitlab CI pipeline.
My project structure:
├───config
├───docs
├───src
__init__.py
│ ├───dataset
__init__.py
│ ├───exceptions
│ ├───resources
│ └───utils
__init__.py
└───tests
__init__.py
└───resources
__init__.py
I would like to run tests using pytest.
I invoke this command python -m pytest -p no:cacheprovider or using unittest
'python -m unittest discover -v' from root directory and also tried to invoke from test directory. In both cases I have a problem with importing class from dataset module. What's interesting, I have two tests file.
First file imports:
import os import unittest
from src.utils.FileManager import FileManager
Second imports:
from src.dataset.DatasetHelper import DatasetHelper
The first file is passing but the second is failing with error:
from dataset import DatasetHelper ModuleNotFoundError: No module
named 'dataset'
So the thing is that other modules like utils from src are imported correctly, only the dataset has a problem. I am struggling with this a few days and I completely out of ideas. I also tried to change instead of from dataset to from src.dataset. It didn't work. I can run tests in PyCharm by clicking right mous button and just run tests but not on CI environment.
What I tried:
Add modules to $PYTHONPATH like
sys.path.insert(0, "/builds/USER/PROJECT/src/dataset")
sys.path.insert(0, "/builds/USER/PROJECT/src")
sys.path.insert(0, "/builds//USER/PROJECT/tests")
The content of PYTHONPATH before adding it was:
Current $PYTHONPATH: ['/builds/USER/PROJECT/config', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/site-packages']
The first module in list is config because I run script from this directory to add above modules to path. Doesn't Help
Run test command from root directory and add prefix src to imports in tests directory. Doesn't Help
from dataset import DatasetHelper
ModuleNotFoundError: No module named 'dataset'
Either in src.__init__ or more proabably in src.dataset.__init__ there is the import statement from dataset import DatasetHelper. You have to rewrite it as from src.dataset import…
You can try using a relative import in your __init__.py file that's inside the tests directory.
The syntax depends on the current location as well as the current location of the module,package, or object you're trying to import. Here are some examples:
from .some_module import some_class
from ..some_package import some_function
from . import some_class
Source: https://realpython.com/absolute-vs-relative-python-imports/

Executing python script from command line: error with imports

I have written a small script in Python with Eclipse, and it works when executed from Eclipse. But it doesn't work from command line:
>python test.py argument1 argument2
from src import Tests, ImportError: No module named src
The script is stored with the following folders:
ScriptFolder
.input
.report
.src
..test.py
..Tests
...Test1.py
...Test2.py
..TestUtils
...FileUtils.py
And this is the way I'm doing the imports at test.py:
from src import Tests
from TestUtils import FileUtils
About the init.py files, the one which shares folder with test.py is empty, and the one into Tests folder has this content:
import Test1
import Test2
And the init.py file into TestUtils has this content:
import FileUtils
The problem is that, if I change the line from src import Tests to just import Tests I'm getting error in Eclipse: Unresolved imports: Tests. found at src.Tests
How can I make it work for both Eclipse and command line?
sys.path.append(path_to_src_directory)
This will add a path to default paths where python looks for modules.
Since, currently the path to your src directory is not known to python, it gives No module named src error.
Also, your src directory does not seem to have an __init__.py file.

ImportError: No module named test.meetinghandler

Hey friends i set my python path as
/home/rohit/test
Here is the structure my test folder
test/
__init__.py
meetinghandler/
__init__.py
meetinghandler.py
db/
__init__.py
models.py
setting.py
manage.py
My problem is when i am trying to import
from test.meetinghandler import meetinghandler
from models.py
i am getting error i.e;
ImportError: No module named test.meetinghandler
please help me out what i am doing wrong .
from test import meetinghandler looks for a test module, which it will not find in your python path.
The reason? You added /home/rohit/test/ to your python path, but that directory doesn't itself contain a test directory :-) Python looks for modules inside the path, that's why.
In your case you'd have to add your home dir to your python path to be able to find it. (Or better, google for virtualenv and so).
Try debugging from the console.
See if the import test works without error. If so, likely there is some error statement in your meetinghandler.py that is not loding the file.
If the import test itself fails on the console, see if the test is in the python path (i.e, as a part of the folder that is present in the settings.INSTALLED_APPS)

How to import a module from a folder next to the current folder?

I have checked as many SO pages as I could and tried everything I found, but none have been successful. I also checked the PEP page regarding importing and tried every example, none of which worked.
I have a tests folder with unit tests in them, and I need to import the module I want to test. The modules are in a folder called 'src' which is next to the src folder.
The folders/files look something like this:
Project /
src /
stringbuilder.py
__init__.py
tests /
stringbuilder_test.py
__init__.py
main.py
__init__.py
I have tried everything I could: adding __init__.py to every folder making it a module including the project's main folder.
import src.module_to_test
from ..src.module_to_test import function_to_test
from ..src import module_to_test
I have tested all other combinations all of which have failed. I am starting to think there must be something wrong with either my settings or understanding-- I thought this was suppose to be simple.
If I am making any obvious errors please let me know.
from tests import stringbuilder
Error Message:
$ ./stringbuilder_test.py
Traceback (most recent call last):
File "./stringbuilder_test.py", line 14, in <module>
from tests import stringbuilder
ImportError: No module named tests
The same error occurs for (but tests = src):
from src import stringbuilder
If scripts are executed from inside a package, then various hacks need to be employed to get the imports to work properly. Probably the most common of these is to manipulate sys.path:
import sys, os
sys.path.insert(0,
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from src import stringbuilder
del sys.path[0]
There is no way to achieve this using normal import statements.
A generally better solution is to simply avoid running scripts inside packages altogether. Instead, put all scripts outside the package in a containing directory. Given that the directory of the currently running script is automatically added to the start of sys.path, this will guarantee that the package can be always be directly imported, no matter where the script is executed from.
So the directory structure might look something like this:
project /
package /
__init__.py
src /
__init__.py
stringbuilder.py
tests /
__init__.py
stringbuilder_test.py
main.py
test.py
The test.py script can then import its tests like this:
from package.tests import stringbuilder_test
And stringbuilder_test.py can import the src modules like this:
from package.src import stringbuilder
from folder import my_module
If there is a __init__.py file in folder.
Add that folder to your PATH.

Python import src modules when running tests

My source files are located under src and my test files are located under tests. When I want to run a test file, say python myTest.py, I get an import error: "No module named ASourceModule.py".
How do I import all the modules from source needed to run my tests?
You need to add that directory to the path:
import sys
sys.path.append('../src')
Maybe put this into a module if you are using it a lot.
If you don't want to add the source path to each test file or change your PYTHONPATH, you can use nose to run the tests.
Suppose your directory structure is like this:
project
package
__init__.py
module.py
tests
__init__.py
test_module.py
You should import the module normally in the test_module.py (e.g. from package import module). Then run the tests by running nosetests in the project folder. You can also run specific tests by doing nosetests tests/test_module.py.
The __init__.py in the tests directory is necessary if you want to run the tests from inside it.
You can install nose easily with easy_install or pip:
easy_install nose
or
pip install nose
nose extends unittest in a lot more ways, to learn more about it you can check their website: https://nose.readthedocs.org/en/latest/
On my system (Windows 10), I was required to do something like this:
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../src")
Appending the relative directory directly to sys.path did not work
The best (most manageable) solution appears to be using a virtualenv and setuptools/distribute to install a development copy of your (src) package. That way your tests execute against a fully "installed" system.
In the pystest docs there is a section on "good practices" explaining this approach, see here.
For those using Pytest:
Make sure src is recognized as a package by putting an empty__init__.py inside.
Put an empty conftest.py in the project folder.
Make sure there is no __init__.py in the test directory.
Looks like this:
project
conftest.py
src
__init__.py
module.py
test
test_module.py
And make sure module.py contains the line:
from src import module
Source: Pytest docs

Categories