diff options
author | Bruno Oliveira <nicoddemus@gmail.com> | 2020-06-13 11:29:01 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-13 11:29:01 -0300 |
commit | ab6dacf1d1e1ff0c5be70a3c5f48e63168168721 (patch) | |
tree | aae4f802f10ebe6c5e2e7ec49a2221cc44c293ac /doc/en/goodpractices.rst | |
parent | 2c37585f58a4bc0e2b1ce635c9a004fff6218538 (diff) | |
download | pytest-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.rst | 23 |
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/ |