New doc role: globalvar for special variables

This introduces a new role, `:globalvar:`, so we can mark/reference
variables like `pytest_plugins`, `pytestmark`, etc. This besides being useful
also makes the documentation look more consistent.
This commit is contained in:
Bruno Oliveira 2020-07-10 09:50:03 -03:00
parent 1667d138aa
commit 906d8496c9
12 changed files with 45 additions and 62 deletions

View File

@ -294,8 +294,6 @@ Assertion introspection details
------------------------------- -------------------------------
Reporting details about a failing assertion is achieved by rewriting assert Reporting details about a failing assertion is achieved by rewriting assert
statements before they are run. Rewritten assert statements put introspection statements before they are run. Rewritten assert statements put introspection
information into the assertion failure message. ``pytest`` only rewrites test information into the assertion failure message. ``pytest`` only rewrites test

View File

@ -2188,7 +2188,7 @@ Features
- `#3711 <https://github.com/pytest-dev/pytest/issues/3711>`_: Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards. - `#3711 <https://github.com/pytest-dev/pytest/issues/3711>`_: Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards.
Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards. Add the :globalvar:`collect_ignore_glob` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards.
- `#4698 <https://github.com/pytest-dev/pytest/issues/4698>`_: The warning about Python 2.7 and 3.4 not being supported in pytest 5.0 has been removed. - `#4698 <https://github.com/pytest-dev/pytest/issues/4698>`_: The warning about Python 2.7 and 3.4 not being supported in pytest 5.0 has been removed.

View File

@ -390,4 +390,11 @@ def setup(app: "sphinx.application.Sphinx") -> None:
indextemplate="pair: %s; configuration value", indextemplate="pair: %s; configuration value",
) )
app.add_object_type(
"globalvar",
"globalvar",
objname="global variable interpreted by pytest",
indextemplate="pair: %s; global variable interpreted by pytest",
)
configure_logging(app) configure_logging(app)

View File

@ -413,7 +413,7 @@ pytest_plugins in non-top-level conftest files
.. versionremoved:: 4.0 .. versionremoved:: 4.0
Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py Defining :globalvar:`pytest_plugins` is now deprecated in non-top-level conftest.py
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
features ``conftest.py`` files are only *active* for tests at or below it. features ``conftest.py`` files are only *active* for tests at or below it.

View File

@ -280,27 +280,7 @@ its test methods:
This is equivalent to directly applying the decorator to the This is equivalent to directly applying the decorator to the
two test functions. two test functions.
Due to legacy reasons, it is possible to set the ``pytestmark`` attribute on a TestClass like this: To apply marks at the module level, use the :globalvar:`pytestmark` global variable:
.. code-block:: python
import pytest
class TestClass:
pytestmark = pytest.mark.webtest
or if you need to use multiple markers you can use a list:
.. code-block:: python
import pytest
class TestClass:
pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
You can also set a module level marker::
import pytest import pytest
pytestmark = pytest.mark.webtest pytestmark = pytest.mark.webtest
@ -309,8 +289,17 @@ or multiple markers::
pytestmark = [pytest.mark.webtest, pytest.mark.slowtest] pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
in which case markers will be applied (in left-to-right order) to
all functions and methods defined in the module. Due to legacy reasons, before class decorators were introduced, it is possible to set the
:globalvar:`pytestmark` attribute on a test class like this:
.. code-block:: python
import pytest
class TestClass:
pytestmark = pytest.mark.webtest
.. _`marking individual tests when using parametrize`: .. _`marking individual tests when using parametrize`:

View File

@ -299,7 +299,7 @@ file will be left out:
========================== no tests ran in 0.12s =========================== ========================== no tests ran in 0.12s ===========================
It's also possible to ignore files based on Unix shell-style wildcards by adding It's also possible to ignore files based on Unix shell-style wildcards by adding
patterns to ``collect_ignore_glob``. patterns to :globalvar:`collect_ignore_glob`.
The following example ``conftest.py`` ignores the file ``setup.py`` and in The following example ``conftest.py`` ignores the file ``setup.py`` and in
addition all files that end with ``*_py2.py`` when executed with a Python 3 addition all files that end with ``*_py2.py`` when executed with a Python 3

View File

@ -1213,15 +1213,12 @@ You can specify multiple fixtures like this:
def test(): def test():
... ...
and you may specify fixture usage at the test module level, using and you may specify fixture usage at the test module level using :globalvar:`pytestmark`:
a generic feature of the mark mechanism:
.. code-block:: python .. code-block:: python
pytestmark = pytest.mark.usefixtures("cleandir") pytestmark = pytest.mark.usefixtures("cleandir")
Note that the assigned variable *must* be called ``pytestmark``, assigning e.g.
``foomark`` will not activate the fixtures.
It is also possible to put fixtures required by all tests in your project It is also possible to put fixtures required by all tests in your project
into an ini-file: into an ini-file:

View File

@ -70,7 +70,7 @@ You may also discover more plugins through a `pytest- pypi.org search`_.
Requiring/Loading plugins in a test module or conftest file Requiring/Loading plugins in a test module or conftest file
----------------------------------------------------------- -----------------------------------------------------------
You can require plugins in a test module or a conftest file like this: You can require plugins in a test module or a conftest file using :globalvar:`pytest_plugins`:
.. code-block:: python .. code-block:: python
@ -80,6 +80,7 @@ When the test module or conftest plugin is loaded the specified plugins
will be loaded as well. will be loaded as well.
.. note:: .. note::
Requiring plugins using a ``pytest_plugins`` variable in non-root Requiring plugins using a ``pytest_plugins`` variable in non-root
``conftest.py`` files is deprecated. See ``conftest.py`` files is deprecated. See
:ref:`full explanation <requiring plugins in non-root conftests>` :ref:`full explanation <requiring plugins in non-root conftests>`

View File

@ -900,14 +900,14 @@ Result used within :ref:`hook wrappers <hookwrapper>`.
.. automethod:: pluggy.callers._Result.get_result .. automethod:: pluggy.callers._Result.get_result
.. automethod:: pluggy.callers._Result.force_result .. automethod:: pluggy.callers._Result.force_result
Special Variables Global Variables
----------------- ----------------
pytest treats some global variables in a special manner when defined in a test module. pytest treats some global variables in a special manner when defined in a test module or
``conftest.py`` files.
collect_ignore .. globalvar:: collect_ignore
~~~~~~~~~~~~~~
**Tutorial**: :ref:`customizing-test-collection` **Tutorial**: :ref:`customizing-test-collection`
@ -919,8 +919,7 @@ Needs to be ``list[str]``.
collect_ignore = ["setup.py"] collect_ignore = ["setup.py"]
collect_ignore_glob .. globalvar:: collect_ignore_glob
~~~~~~~~~~~~~~~~~~~
**Tutorial**: :ref:`customizing-test-collection` **Tutorial**: :ref:`customizing-test-collection`
@ -933,8 +932,7 @@ contain glob patterns.
collect_ignore_glob = ["*_ignore.py"] collect_ignore_glob = ["*_ignore.py"]
pytest_plugins .. globalvar:: pytest_plugins
~~~~~~~~~~~~~~
**Tutorial**: :ref:`available installable plugins` **Tutorial**: :ref:`available installable plugins`
@ -950,13 +948,12 @@ Can be either a ``str`` or ``Sequence[str]``.
pytest_plugins = ("myapp.testsupport.tools", "myapp.testsupport.regression") pytest_plugins = ("myapp.testsupport.tools", "myapp.testsupport.regression")
pytestmark .. globalvar:: pytestmark
~~~~~~~~~~
**Tutorial**: :ref:`scoped-marking` **Tutorial**: :ref:`scoped-marking`
Can be declared at the **global** level in *test modules* to apply one or more :ref:`marks <marks ref>` to all Can be declared at the **global** level in *test modules* to apply one or more :ref:`marks <marks ref>` to all
test functions and methods. Can be either a single mark or a list of marks. test functions and methods. Can be either a single mark or a list of marks (applied in left-to-right order).
.. code-block:: python .. code-block:: python
@ -971,12 +968,6 @@ test functions and methods. Can be either a single mark or a list of marks.
pytestmark = [pytest.mark.integration, pytest.mark.slow] pytestmark = [pytest.mark.integration, pytest.mark.slow]
PYTEST_DONT_REWRITE (module docstring)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The text ``PYTEST_DONT_REWRITE`` can be add to any **module docstring** to disable
:ref:`assertion rewriting <assert introspection>` for that module.
Environment Variables Environment Variables
--------------------- ---------------------

View File

@ -152,8 +152,8 @@ You can use the ``skipif`` marker (as any other marker) on classes:
If the condition is ``True``, this marker will produce a skip result for If the condition is ``True``, this marker will produce a skip result for
each of the test methods of that class. each of the test methods of that class.
If you want to skip all test functions of a module, you may use If you want to skip all test functions of a module, you may use the
the ``pytestmark`` name on the global level: :globalvar:`pytestmark` global:
.. code-block:: python .. code-block:: python

View File

@ -117,7 +117,7 @@ Filters applied using a mark take precedence over filters passed on the command
by the ``filterwarnings`` ini option. by the ``filterwarnings`` ini option.
You may apply a filter to all tests of a class by using the ``filterwarnings`` mark as a class You may apply a filter to all tests of a class by using the ``filterwarnings`` mark as a class
decorator or to all tests in a module by setting the ``pytestmark`` variable: decorator or to all tests in a module by setting the :globalvar:`pytestmark` variable:
.. code-block:: python .. code-block:: python

View File

@ -52,7 +52,7 @@ Plugin discovery order at tool startup
your ``conftest.py`` file in the top level test or project root directory. your ``conftest.py`` file in the top level test or project root directory.
* by recursively loading all plugins specified by the * by recursively loading all plugins specified by the
``pytest_plugins`` variable in ``conftest.py`` files :globalvar:`pytest_plugins` variable in ``conftest.py`` files
.. _`pytest/plugin`: http://bitbucket.org/pytest-dev/pytest/src/tip/pytest/plugin/ .. _`pytest/plugin`: http://bitbucket.org/pytest-dev/pytest/src/tip/pytest/plugin/
@ -227,7 +227,7 @@ import ``helper.py`` normally. The contents of
Requiring/Loading plugins in a test module or conftest file Requiring/Loading plugins in a test module or conftest file
----------------------------------------------------------- -----------------------------------------------------------
You can require plugins in a test module or a ``conftest.py`` file like this: You can require plugins in a test module or a ``conftest.py`` file using :globalvar:`pytest_plugins`:
.. code-block:: python .. code-block:: python
@ -241,31 +241,31 @@ application modules:
pytest_plugins = "myapp.testsupport.myplugin" pytest_plugins = "myapp.testsupport.myplugin"
``pytest_plugins`` variables are processed recursively, so note that in the example above :globalvar:`pytest_plugins` are processed recursively, so note that in the example above
if ``myapp.testsupport.myplugin`` also declares ``pytest_plugins``, the contents if ``myapp.testsupport.myplugin`` also declares :globalvar:`pytest_plugins`, the contents
of the variable will also be loaded as plugins, and so on. of the variable will also be loaded as plugins, and so on.
.. _`requiring plugins in non-root conftests`: .. _`requiring plugins in non-root conftests`:
.. note:: .. note::
Requiring plugins using a ``pytest_plugins`` variable in non-root Requiring plugins using :globalvar:`pytest_plugins` variable in non-root
``conftest.py`` files is deprecated. ``conftest.py`` files is deprecated.
This is important because ``conftest.py`` files implement per-directory This is important because ``conftest.py`` files implement per-directory
hook implementations, but once a plugin is imported, it will affect the hook implementations, but once a plugin is imported, it will affect the
entire directory tree. In order to avoid confusion, defining entire directory tree. In order to avoid confusion, defining
``pytest_plugins`` in any ``conftest.py`` file which is not located in the :globalvar:`pytest_plugins` in any ``conftest.py`` file which is not located in the
tests root directory is deprecated, and will raise a warning. tests root directory is deprecated, and will raise a warning.
This mechanism makes it easy to share fixtures within applications or even This mechanism makes it easy to share fixtures within applications or even
external applications without the need to create external plugins using external applications without the need to create external plugins using
the ``setuptools``'s entry point technique. the ``setuptools``'s entry point technique.
Plugins imported by ``pytest_plugins`` will also automatically be marked Plugins imported by :globalvar:`pytest_plugins` will also automatically be marked
for assertion rewriting (see :func:`pytest.register_assert_rewrite`). for assertion rewriting (see :func:`pytest.register_assert_rewrite`).
However for this to have any effect the module must not be However for this to have any effect the module must not be
imported already; if it was already imported at the time the imported already; if it was already imported at the time the
``pytest_plugins`` statement is processed, a warning will result and :globalvar:`pytest_plugins` statement is processed, a warning will result and
assertions inside the plugin will not be rewritten. To fix this you assertions inside the plugin will not be rewritten. To fix this you
can either call :func:`pytest.register_assert_rewrite` yourself before can either call :func:`pytest.register_assert_rewrite` yourself before
the module is imported, or you can arrange the code to delay the the module is imported, or you can arrange the code to delay the