I am storing all the pytest files in the tests
sub-directory under the project root. There is no __init__.py
in that directory or above and pytest tests/test_a.py
works as expected. I can also run pytest test_a.py
directly from within the tests
folder.
|--<project_root>
+---[tests]
test_a.py
base.py
config.py
conftest.py
The test class in test_a.py
inherits from base.py
. Now, the problem is that because of the missing __init__.py
the IDE tooling does not work and the imports cannot be resolved. Adding __init__.py
under the tests
resolves all import errors in the IDE, but tests won't run anymore with pytest test_a.py
because py.test fails to import conftest.py
.
In my conftest.py
I have the following imports:
from config import HOST_URL_DEFAULT, USER, PASSWORD
which results in:
ModuleNotFoundError: No module named 'config'
ERROR: could not load /project_root/tests/conftest.py
Is there a way to solve this so that both IDE tooling works and pytest
keeps working? I would like to avoid using dot imports, if possible.
Update: After reading this answer I think I am finally starting to understand a bit more how python imports work.
Add __init__.py
and use a relative or absolute import in conftest.py
:
# relative
from .config import HOST_URL_DEFAULT, USER, PASSWORD
# absolute
from tests.config import HOST_URL_DEFAULT, USER, PASSWORD
In a package (identified by __init__.py
), you need unambiguous import paths. Using unqualified imports (from config import ...
) depends on PYTHONPATH
or sys.modules
including your package root - this is generally not robust and should be avoided as it circumvents the package infrastructure.
What you have here (config.py
used by other modules) is a package. Treat it as one.
pytest
does not discourage the use of a test package with an __init__.py
! There are veritable use cases for this - such as yours.
What pytest
does discourage is having a source package and test package in the same source root. However, that means you should move your source package, not your test package!
mysource/ # root directory for both mypackage and mytests
+- mypackage/ # should be src/mypackage instead!
+- __init__.py
+- abcd.py
+- mytests
+- __init__.py
+- tests_abcd.py # ``from mypackage import abcd`` imports from source
The problem is that running mytests
means that mypackage
is importable from source as well. That is, your tests are working on your source package, not your installed package. If there are any errors in your installation procedure, testing will not catch it. See the blog linked in the pytest
docs for details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With