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
statements before they are run. Rewritten assert statements put introspection
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.
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.

View File

@ -390,4 +390,11 @@ def setup(app: "sphinx.application.Sphinx") -> None:
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)

View File

@ -413,7 +413,7 @@ pytest_plugins in non-top-level conftest files
.. 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
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
two test functions.
Due to legacy reasons, it is possible to set the ``pytestmark`` attribute on a TestClass like this:
.. 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::
To apply marks at the module level, use the :globalvar:`pytestmark` global variable:
import pytest
pytestmark = pytest.mark.webtest
@ -309,8 +289,17 @@ or multiple markers::
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`:

View File

@ -299,7 +299,7 @@ file will be left out:
========================== no tests ran in 0.12s ===========================
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
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():
...
and you may specify fixture usage at the test module level, using
a generic feature of the mark mechanism:
and you may specify fixture usage at the test module level using :globalvar:`pytestmark`:
.. code-block:: python
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
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
-----------------------------------------------------------
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
@ -80,6 +80,7 @@ When the test module or conftest plugin is loaded the specified plugins
will be loaded as well.
.. note::
Requiring plugins using a ``pytest_plugins`` variable in non-root
``conftest.py`` files is deprecated. See
: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.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`
@ -919,8 +919,7 @@ Needs to be ``list[str]``.
collect_ignore = ["setup.py"]
collect_ignore_glob
~~~~~~~~~~~~~~~~~~~
.. globalvar:: collect_ignore_glob
**Tutorial**: :ref:`customizing-test-collection`
@ -933,8 +932,7 @@ contain glob patterns.
collect_ignore_glob = ["*_ignore.py"]
pytest_plugins
~~~~~~~~~~~~~~
.. globalvar:: pytest_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")
pytestmark
~~~~~~~~~~
.. globalvar:: pytestmark
**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
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
@ -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]
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
---------------------

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
each of the test methods of that class.
If you want to skip all test functions of a module, you may use
the ``pytestmark`` name on the global level:
If you want to skip all test functions of a module, you may use the
:globalvar:`pytestmark` global:
.. 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.
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

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.
* 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/
@ -227,7 +227,7 @@ import ``helper.py`` normally. The contents of
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
@ -241,31 +241,31 @@ application modules:
pytest_plugins = "myapp.testsupport.myplugin"
``pytest_plugins`` variables are processed recursively, so note that in the example above
if ``myapp.testsupport.myplugin`` also declares ``pytest_plugins``, the contents
:globalvar:`pytest_plugins` are processed recursively, so note that in the example above
if ``myapp.testsupport.myplugin`` also declares :globalvar:`pytest_plugins`, the contents
of the variable will also be loaded as plugins, and so on.
.. _`requiring plugins in non-root conftests`:
.. 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.
This is important because ``conftest.py`` files implement per-directory
hook implementations, but once a plugin is imported, it will affect the
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.
This mechanism makes it easy to share fixtures within applications or even
external applications without the need to create external plugins using
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`).
However for this to have any effect the module must not be
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
can either call :func:`pytest.register_assert_rewrite` yourself before
the module is imported, or you can arrange the code to delay the