Clarify PYTHONPATH changes and `rootdir` roles
- Also minor adjustments in the docs (wording, formatting, links, etc). Fix #2589
This commit is contained in:
71
doc/en/pythonpath.rst
Normal file
71
doc/en/pythonpath.rst
Normal file
@@ -0,0 +1,71 @@
|
||||
.. _pythonpath:
|
||||
|
||||
pytest import mechanisms and ``sys.path``/``PYTHONPATH``
|
||||
========================================================
|
||||
|
||||
Here's a list of scenarios where pytest may need to change ``sys.path`` in order
|
||||
to import test modules or ``conftest.py`` files.
|
||||
|
||||
Test modules / ``conftest.py`` files inside packages
|
||||
----------------------------------------------------
|
||||
|
||||
Consider this file and directory layout::
|
||||
|
||||
root/
|
||||
|- foo/
|
||||
|- __init__.py
|
||||
|- conftest.py
|
||||
|- bar/
|
||||
|- __init__.py
|
||||
|- tests/
|
||||
|- __init__.py
|
||||
|- test_foo.py
|
||||
|
||||
|
||||
When executing::
|
||||
|
||||
pytest root/
|
||||
|
||||
|
||||
|
||||
pytest will find ``foo/bar/tests/test_foo.py`` and realize it is part of a package given that
|
||||
there's an ``__init__.py`` file in the same folder. It will then search upwards until it can find the
|
||||
last folder which still contains an ``__init__.py`` file in order to find the package *root* (in
|
||||
this case ``foo/``). To load the module, it will insert ``root/`` to the front of
|
||||
``sys.path`` (if not there already) in order to load
|
||||
``test_foo.py`` as the *module* ``foo.bar.tests.test_foo``.
|
||||
|
||||
The same logic applies to the ``conftest.py`` file: it will be imported as ``foo.conftest`` module.
|
||||
|
||||
Preserving the full package name is important when tests live in a package to avoid problems
|
||||
and allow test modules to have duplicated names. This is also discussed in details in
|
||||
:ref:`test discovery`.
|
||||
|
||||
Standalone test modules / ``conftest.py`` files
|
||||
-----------------------------------------------
|
||||
|
||||
Consider this file and directory layout::
|
||||
|
||||
root/
|
||||
|- foo/
|
||||
|- conftest.py
|
||||
|- bar/
|
||||
|- tests/
|
||||
|- test_foo.py
|
||||
|
||||
|
||||
When executing::
|
||||
|
||||
pytest root/
|
||||
|
||||
pytest will find ``foo/bar/tests/test_foo.py`` and realize it is NOT part of a package given that
|
||||
there's no ``__init__.py`` file in the same folder. It will then add ``root/foo/bar/tests`` to
|
||||
``sys.path`` in order to import ``test_foo.py`` as the *module* ``test_foo``. The same is done
|
||||
with the ``conftest.py`` file by adding ``root/foo`` to ``sys.path`` to import it as ``conftest``.
|
||||
|
||||
For this reason this layout cannot have test modules with the same name, as they all will be
|
||||
imported in the global import namespace.
|
||||
|
||||
This is also discussed in details in :ref:`test discovery`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user