path error when running Pytest tests from cmd - python

I have this issue with Pytest where unit tests run fine from PyCharm but doesn't when I run through pipeline "python -m pytest".
Below is my project structure:
Common
|_____configuration.py
|
Services
|
|-----ServiceA
| |
| |___src
| | |___utils
| | |__ __init__.py
| | |__ helper1.py
| |__ helper2.py
| |___Test
| |___utils
| |__ __init.py
| |__ test1.py
|
|-----ServiceB
|
|
In helper1 I have code as
from Common import configuration
Tests runs absolutely fine when I run through Pycharm because it resolves all path but when I run it through pipeline, I get below error when running through cmd,
ModuleNotFoundError: No module named 'Common'
Can anyone help how to resolve this issue. TIA

In pytest >= 7.0.0 you can register extra path using Pytest's pythonpath config option. The path value should be relative to the rootdir. So it might be Common or ../Common or even prefixed with more parent levels.
If you use pyproject.toml:
[tool.pytest.ini_options]
pythonpath = ["Common"]
If you use pytest.ini instead:
[pytest]
pythonpath = Common

Added path to the common in test init.py and resolved the issue
sys.path.append('..\..\Common')

Related

Pytest import problems when tests import from adjacent directory

/root
|- __init__.py
|
|- /src
| |
| |- __init__.py
| |- /x
| |
| |- __init__.py
| |- xy.py
|
|- /tests
| |- __init__.py
| |- /test_x
| |
| |- __init__.py
| |- test_xy.py
# tests/test_x/test_xy.py
from src.x.xy import XY
Class TestXY:
# etc
When I’m in root I try to run pytest tests/*/* and I get an error that due to from src.x.xy import XY because src can’t be found. If I change the import to from …src.x.xy import XY I get “cannot import” because it’s from a directory one level above.
I also tried running Python -m pytest tests/*/* but I get an error about conftest not being found in __pycache__ which I don’t understand. (ERROR: not found: /root/tests/__pycache__/conftest.cpython-310-pytest-7.1.2.pyc (no name '/root/tests/__pycache__/conftest.cpython-310-pytest-7.1.2.pyc' in any of []))
What am I missing? Why is it so hard to run tests this way? I can run them individually in pycharm by clicking the little green arrows in the test script no problem.
In that architecture of project you should use config file. Config file should have path to src.
pyproject.toml example:
[tool.pytest.ini_options]
pythonpath = [
"src"
]
pytest.ini example:
[pytest]
pythonpath = src
If you will have multiple src directories you also can add it to config
For example pyproject.toml:
[tool.pytest.ini_options]
pythonpath = [
"src", "src2",
]

Python import module from within module in another subpackage

I am having trouble importing a module from within another module. I understand that that sentence can be confusing so my question and situation is exactly like the one suggested here: Python relative-import script two levels up
So lets say my directory structure is like so:
main_package
|
| __init__.py
| folder_1
| | __init__.py
| | folder_2
| | | __init__.py
| | | script_a.py
| | | script_b.py
|
| folder_3
| | __init__.py
| | script_c.py
And I want to access code in script_b.py as well as code from script_c.py from script_a.py.
I have also followed exactly what the answer suggested with absolute imports.
I included the following lines of code in script_a.py:
from main_package.folder_3 import script_c
from main_package.folder1.folder2 import script_b
When I run script_a.py, I get the following error:
ModuleNotFoundError: No module named 'main_package'
What am I doing wrong here?
This is because python doesn't know where to find main_package in script_a.py.
There are a couple of ways to expose main_package to python:
run script_a.py from main_package's parent directory (say packages). Python will look for it in the current directory (packages), which contains main_package:
python main_package/folder_1/folder_2/script_a.py
add main_package's parent directory (packages) to your PYTHONPATH:
export PYTHONPATH="$PYTHONPATH:/path/to/packages"; python script_a.py
add main_package's parent directory (packages) to sys.path in script_a.py
In your script_a.py, add the following at the top:
import sys
sys.path.append('/path/to/packages')

How to import modules from adjacent package without setting PYTHONPATH

I have a python 2.7 project which I have structured as below:
project
|
|____src
| |
| |__pkg
| |
| |__ __init__.py
|
|____test
|
|__test_pkg
| |
| |__ __init__.py
|
|__helpers
| |
| |__ __init__.py
|
|__ __init__.py
I am setting the src folder to the PYTHONPATH, so importing works nicely in the packages inside src. I am using eclipse, pylint inside eclipse and nosetests in eclipse as well as via bash and in a make file (for project). So I have to satisfy lets say every stakeholder!
The problem is importing some code from the helpers package in test. Weirdly enough, my test is also a python package with __init__.py containing some top level setUp and tearDown method for all tests. So when I try this:
import helpers
from helpers.blaaa import Blaaa
in some module inside test_pkg, all my stakeholders are not satisfied. I get the ImportError: No module named ... and pylint also complains about not finding it. I can live with pylint complaining in test folders but nosetests is also dying if I run it in the project directory and test directory. I would prefer not to do relative imports with dot (.).
The problem is that you can not escape the current directory by importing from ..helpers.
But if you start your test code inside the test directory with
python3 -m test_pkg.foo
the current directory will be the test directory and importing helpers will work. On the minus side that means you have to import from . inside test_pkg.

Python Pycharm module path

I would understand this behaviour.
In Pycharm I can successfully run (green play button) this main.py which includes src.v0.Det.py
src
|
+--v0
| |
| +--Det.py (class det)
| __init__.py
|
+-- main.py
__init__.py
main.py
------------
from src.v0.Det import det
....
But when I run on unix using: python main.py I get "No module named src.v0.Det".
I can obviously remove "src" and it works but I don't want to change the file. How can I run this file like in Pycharm?
Riccardo
export PYTHONPATH="${PYTHONPATH}:<.....path.to.src.without.src....>"

import error when run tests in submodule with nose

We use git submodule to share common module within our team.
Each module has test cases in its source folder, and ran by nose.
I have a project in this structure:
/project_sample
|__/project_sample
| |__ __init__.py
| |__ moduleA.py
| |__/tests
| | |__ __init__.py
| | |__ moduleA_tests.py
| |__/subpackage
| |__ __init__.py
| |__ moduleB.py
| |__/tests
| |__ __init__.py
| |__ moduleB_tests.py
|__setup.py
All of these init.py files are empty.
The subpackage is developed seperately and added to the project by git submodule. We want it to be self-contained , and try to share it in different project. Its test case is like this:
moduleB_tests.py:
from subpackage import moduleB
def test_funcA():
moduleB.funcA()
The test pass when i run nosetests from the subpackage's repo folder.
Seems like nose find a init.py file in the parent folder of subpackage (project_sample), when i run nosetests from project_sample's root directory, i get "ImportError: No module named subpackage". But it passed when i change the first line to:
from project_sample.subpackage import moduleB
But this way makes subpackage not self-contained.
I tried some way like : adding subpackage to sys.path or use -w option of nose, but still get this exception.
My teammate run subpackage's test case seperately in PyCharm and get passed, so i think there should be some way to make it pass from command line.
Is there any way to resolve the problem, or any suggestion with the project structure?
This is my first question on SO, Any suggestion is appreciated.
I know this question is a bit old and has already been answered but we use a different strategy in our code base.
If for some reason you still want the package in the project_sample module directory, you can structure it something like this:
/project_sample
|__/project_sample
| |__ __init__.py
| |__ moduleA.py
| |__/tests
| | |__ __init__.py
| | |__ moduleA_tests.py
| |__/subpackage_repo
| |__/subpackage
| |__ __init__.py
| |__ moduleB.py
| |__/tests
| |__ __init__.py
| |__ moduleB_tests.py
| |__setup.py
|__setup.py
Without an __init__.py in the subpackage, it won't be a part of your project.
Then in the __init__.py of the main package, you can include
import os
import sys
sys.path.insert(0,
os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'subpackage_repo')
)
import subpackage
which puts the subpackage in the path for the main project.
Then in moduleA.py that allows us to do something like
from . import subpackage
since the package is imported at the __init__.py level.
Of course you can also move it up a level as well and just reflect that in the path you're adding if you want to do it that way. The only disadvantage of doing that is that when you run your tests with something like
python -m unittest discover
you'll discover the subpackage tests as well and run those. Ideally those tests should be taken care of with whatever CI you have for the package so we'd hope that they don't need to be run.
If you want subpackage to be self-contained, you need it to treat as such. This means that you need to put it top-level, parallel to project_sample instead of into it.

Categories