summaryrefslogtreecommitdiff
path: root/doc/en/goodpractices.rst
diff options
context:
space:
mode:
authorBruno Oliveira <nicoddemus@gmail.com>2020-06-13 11:29:01 -0300
committerGitHub <noreply@github.com>2020-06-13 11:29:01 -0300
commitab6dacf1d1e1ff0c5be70a3c5f48e63168168721 (patch)
treeaae4f802f10ebe6c5e2e7ec49a2221cc44c293ac /doc/en/goodpractices.rst
parent2c37585f58a4bc0e2b1ce635c9a004fff6218538 (diff)
downloadpytest-ab6dacf1d1e1ff0c5be70a3c5f48e63168168721.tar.gz
Introduce --import-mode=importlib (#7246)
Fix #5821 Co-authored-by: Ran Benita <ran@unusedvar.com>
Diffstat (limited to 'doc/en/goodpractices.rst')
-rw-r--r--doc/en/goodpractices.rst23
1 files changed, 20 insertions, 3 deletions
diff --git a/doc/en/goodpractices.rst b/doc/en/goodpractices.rst
index 16b41eda4..ee5674fd6 100644
--- a/doc/en/goodpractices.rst
+++ b/doc/en/goodpractices.rst
@@ -91,7 +91,8 @@ This has the following benefits:
See :ref:`pytest vs python -m pytest` for more information about the difference between calling ``pytest`` and
``python -m pytest``.
-Note that using this scheme your test files must have **unique names**, because
+Note that this scheme has a drawback if you are using ``prepend`` :ref:`import mode <import-modes>`
+(which is the default): your test files must have **unique names**, because
``pytest`` will import them as *top-level* modules since there are no packages
to derive a full package name from. In other words, the test files in the example above will
be imported as ``test_app`` and ``test_view`` top-level modules by adding ``tests/`` to
@@ -118,9 +119,12 @@ Now pytest will load the modules as ``tests.foo.test_view`` and ``tests.bar.test
you to have modules with the same name. But now this introduces a subtle problem: in order to load
the test modules from the ``tests`` directory, pytest prepends the root of the repository to
``sys.path``, which adds the side-effect that now ``mypkg`` is also importable.
+
This is problematic if you are using a tool like `tox`_ to test your package in a virtual environment,
because you want to test the *installed* version of your package, not the local code from the repository.
+.. _`src-layout`:
+
In this situation, it is **strongly** suggested to use a ``src`` layout where application root package resides in a
sub-directory of your root:
@@ -145,6 +149,15 @@ sub-directory of your root:
This layout prevents a lot of common pitfalls and has many benefits, which are better explained in this excellent
`blog post by Ionel Cristian Mărieș <https://blog.ionelmc.ro/2014/05/25/python-packaging/#the-structure>`_.
+.. note::
+ The new ``--import-mode=importlib`` (see :ref:`import-modes`) doesn't have
+ any of the drawbacks above because ``sys.path`` and ``sys.modules`` are not changed when importing
+ test modules, so users that run
+ into this issue are strongly encouraged to try it and report if the new option works well for them.
+
+ The ``src`` directory layout is still strongly recommended however.
+
+
Tests as part of application code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -190,8 +203,8 @@ Note that this layout also works in conjunction with the ``src`` layout mentione
.. note::
- If ``pytest`` finds an "a/b/test_module.py" test file while
- recursing into the filesystem it determines the import name
+ In ``prepend`` and ``append`` import-modes, if pytest finds a ``"a/b/test_module.py"``
+ test file while recursing into the filesystem it determines the import name
as follows:
* determine ``basedir``: this is the first "upward" (towards the root)
@@ -212,6 +225,10 @@ Note that this layout also works in conjunction with the ``src`` layout mentione
from each other and thus deriving a canonical import name helps
to avoid surprises such as a test module getting imported twice.
+ With ``--import-mode=importlib`` things are less convoluted because
+ pytest doesn't need to change ``sys.path`` or ``sys.modules``, making things
+ much less surprising.
+
.. _`virtualenv`: https://pypi.org/project/virtualenv/
.. _`buildout`: http://www.buildout.org/