Merge branch 'main' into patch-1
This commit is contained in:
commit
b3c1377693
|
@ -114,6 +114,7 @@ jobs:
|
||||||
python: "3.11-dev"
|
python: "3.11-dev"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
tox_env: "py311"
|
tox_env: "py311"
|
||||||
|
use_coverage: true
|
||||||
- name: "ubuntu-pypy3"
|
- name: "ubuntu-pypy3"
|
||||||
python: "pypy-3.7"
|
python: "pypy-3.7"
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
|
|
|
@ -68,6 +68,9 @@ repos:
|
||||||
- packaging
|
- packaging
|
||||||
- tomli
|
- tomli
|
||||||
- types-pkg_resources
|
- types-pkg_resources
|
||||||
|
# for mypy running on python>=3.11 since exceptiongroup is only a dependency
|
||||||
|
# on <3.11
|
||||||
|
- exceptiongroup>=1.0.0rc8
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: rst
|
- id: rst
|
||||||
|
|
2
AUTHORS
2
AUTHORS
|
@ -168,6 +168,7 @@ Jeff Rackauckas
|
||||||
Jeff Widman
|
Jeff Widman
|
||||||
Jenni Rinker
|
Jenni Rinker
|
||||||
John Eddie Ayson
|
John Eddie Ayson
|
||||||
|
John Litborn
|
||||||
John Towler
|
John Towler
|
||||||
Jon Parise
|
Jon Parise
|
||||||
Jon Sonesen
|
Jon Sonesen
|
||||||
|
@ -313,6 +314,7 @@ Seth Junot
|
||||||
Shantanu Jain
|
Shantanu Jain
|
||||||
Shubham Adep
|
Shubham Adep
|
||||||
Simon Gomizelj
|
Simon Gomizelj
|
||||||
|
Simon Holesch
|
||||||
Simon Kerr
|
Simon Kerr
|
||||||
Skylar Downes
|
Skylar Downes
|
||||||
Srinivas Reddy Thatiparthy
|
Srinivas Reddy Thatiparthy
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Invalid XML characters in setup or teardown error messages are now properly escaped for JUnit XML reports.
|
|
@ -0,0 +1,5 @@
|
||||||
|
``@pytest.mark.parametrize()`` (and similar functions) now accepts any ``Sequence[str]`` for the argument names,
|
||||||
|
instead of just ``list[str]`` and ``tuple[str, ...]``.
|
||||||
|
|
||||||
|
(Note that ``str``, which is itself a ``Sequence[str]``, is still treated as a
|
||||||
|
comma-delimited name list, as before).
|
|
@ -0,0 +1 @@
|
||||||
|
Showing inner exceptions by forcing native display in ``ExceptionGroups`` even when using display options other than ``--tb=native``. A temporary step before full implementation of pytest-native display for inner exceptions in ``ExceptionGroups``.
|
|
@ -0,0 +1 @@
|
||||||
|
The documentation is now built using Sphinx 5.x (up from 3.x previously).
|
|
@ -0,0 +1 @@
|
||||||
|
Update documentation on how :func:`pytest.warns` affects :class:`DeprecationWarning`.
|
|
@ -38,6 +38,7 @@ release = ".".join(version.split(".")[:2])
|
||||||
|
|
||||||
autodoc_member_order = "bysource"
|
autodoc_member_order = "bysource"
|
||||||
autodoc_typehints = "description"
|
autodoc_typehints = "description"
|
||||||
|
autodoc_typehints_description_target = "documented"
|
||||||
todo_include_todos = 1
|
todo_include_todos = 1
|
||||||
|
|
||||||
latex_engine = "lualatex"
|
latex_engine = "lualatex"
|
||||||
|
@ -162,11 +163,11 @@ linkcheck_workers = 5
|
||||||
|
|
||||||
_repo = "https://github.com/pytest-dev/pytest"
|
_repo = "https://github.com/pytest-dev/pytest"
|
||||||
extlinks = {
|
extlinks = {
|
||||||
"bpo": ("https://bugs.python.org/issue%s", "bpo-"),
|
"bpo": ("https://bugs.python.org/issue%s", "bpo-%s"),
|
||||||
"pypi": ("https://pypi.org/project/%s/", ""),
|
"pypi": ("https://pypi.org/project/%s/", "%s"),
|
||||||
"issue": (f"{_repo}/issues/%s", "issue #"),
|
"issue": (f"{_repo}/issues/%s", "issue #%s"),
|
||||||
"pull": (f"{_repo}/pull/%s", "pull request #"),
|
"pull": (f"{_repo}/pull/%s", "pull request #%s"),
|
||||||
"user": ("https://github.com/%s", "@"),
|
"user": ("https://github.com/%s", "@%s"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,8 +420,6 @@ def configure_logging(app: "sphinx.application.Sphinx") -> None:
|
||||||
|
|
||||||
|
|
||||||
def setup(app: "sphinx.application.Sphinx") -> None:
|
def setup(app: "sphinx.application.Sphinx") -> None:
|
||||||
# from sphinx.ext.autodoc import cut_lines
|
|
||||||
# app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
|
|
||||||
app.add_crossref_type(
|
app.add_crossref_type(
|
||||||
"fixture",
|
"fixture",
|
||||||
"fixture",
|
"fixture",
|
||||||
|
|
|
@ -42,6 +42,8 @@ Running pytest now produces this output:
|
||||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||||
======================= 1 passed, 1 warning in 0.12s =======================
|
======================= 1 passed, 1 warning in 0.12s =======================
|
||||||
|
|
||||||
|
.. _`controlling-warnings`:
|
||||||
|
|
||||||
Controlling warnings
|
Controlling warnings
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -176,11 +178,14 @@ using an external system.
|
||||||
DeprecationWarning and PendingDeprecationWarning
|
DeprecationWarning and PendingDeprecationWarning
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings from
|
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings from
|
||||||
user code and third-party libraries, as recommended by :pep:`565`.
|
user code and third-party libraries, as recommended by :pep:`565`.
|
||||||
This helps users keep their code modern and avoid breakages when deprecated warnings are effectively removed.
|
This helps users keep their code modern and avoid breakages when deprecated warnings are effectively removed.
|
||||||
|
|
||||||
|
However, in the specific case where users capture any type of warnings in their test, either with
|
||||||
|
:func:`pytest.warns`, :func:`pytest.deprecated_call` or using the :ref:`recwarn <recwarn>` fixture,
|
||||||
|
no warning will be displayed at all.
|
||||||
|
|
||||||
Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
|
Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over
|
||||||
(such as third-party libraries), in which case you might use the warning filters options (ini or marks) to ignore
|
(such as third-party libraries), in which case you might use the warning filters options (ini or marks) to ignore
|
||||||
those warnings.
|
those warnings.
|
||||||
|
@ -197,6 +202,9 @@ For example:
|
||||||
This will ignore all warnings of type ``DeprecationWarning`` where the start of the message matches
|
This will ignore all warnings of type ``DeprecationWarning`` where the start of the message matches
|
||||||
the regular expression ``".*U.*mode is deprecated"``.
|
the regular expression ``".*U.*mode is deprecated"``.
|
||||||
|
|
||||||
|
See :ref:`@pytest.mark.filterwarnings <filterwarnings>` and
|
||||||
|
:ref:`Controlling warnings <controlling-warnings>` for more examples.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
If warnings are configured at the interpreter level, using
|
If warnings are configured at the interpreter level, using
|
||||||
|
@ -245,10 +253,10 @@ when called with a ``17`` argument.
|
||||||
Asserting warnings with the warns function
|
Asserting warnings with the warns function
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
You can check that code raises a particular warning using :func:`pytest.warns`,
|
You can check that code raises a particular warning using :func:`pytest.warns`,
|
||||||
which works in a similar manner to :ref:`raises <assertraises>`:
|
which works in a similar manner to :ref:`raises <assertraises>` (except that
|
||||||
|
:ref:`raises <assertraises>` does not capture all exceptions, only the
|
||||||
|
``expected_exception``):
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@ -261,8 +269,8 @@ which works in a similar manner to :ref:`raises <assertraises>`:
|
||||||
with pytest.warns(UserWarning):
|
with pytest.warns(UserWarning):
|
||||||
warnings.warn("my warning", UserWarning)
|
warnings.warn("my warning", UserWarning)
|
||||||
|
|
||||||
The test will fail if the warning in question is not raised. The keyword
|
The test will fail if the warning in question is not raised. Use the keyword
|
||||||
argument ``match`` to assert that the exception matches a text or regex::
|
argument ``match`` to assert that the warning matches a text or regex::
|
||||||
|
|
||||||
>>> with warns(UserWarning, match='must be 0 or None'):
|
>>> with warns(UserWarning, match='must be 0 or None'):
|
||||||
... warnings.warn("value must be 0 or None", UserWarning)
|
... warnings.warn("value must be 0 or None", UserWarning)
|
||||||
|
@ -359,17 +367,29 @@ Additional use cases of warnings in tests
|
||||||
|
|
||||||
Here are some use cases involving warnings that often come up in tests, and suggestions on how to deal with them:
|
Here are some use cases involving warnings that often come up in tests, and suggestions on how to deal with them:
|
||||||
|
|
||||||
- To ensure that **at least one** warning is emitted, use:
|
- To ensure that **at least one** of the indicated warnings is issued, use:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
with pytest.warns():
|
def test_warning():
|
||||||
|
with pytest.warns((RuntimeWarning, UserWarning)):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
- To ensure that **only** certain warnings are issued, use:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def test_warning(recwarn):
|
||||||
|
...
|
||||||
|
assert len(recwarn) == 1
|
||||||
|
user_warning = recwarn.pop(UserWarning)
|
||||||
|
assert issubclass(user_warning.category, UserWarning)
|
||||||
|
|
||||||
- To ensure that **no** warnings are emitted, use:
|
- To ensure that **no** warnings are emitted, use:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
def test_warning():
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("error")
|
warnings.simplefilter("error")
|
||||||
...
|
...
|
||||||
|
|
|
@ -738,6 +738,79 @@ does offer some nuances for when you're in a pinch.
|
||||||
. [100%]
|
. [100%]
|
||||||
1 passed in 0.12s
|
1 passed in 0.12s
|
||||||
|
|
||||||
|
Note on finalizer order
|
||||||
|
""""""""""""""""""""""""
|
||||||
|
|
||||||
|
Finalizers are executed in a first-in-last-out order.
|
||||||
|
For yield fixtures, the first teardown code to run is from the right-most fixture, i.e. the last test parameter.
|
||||||
|
|
||||||
|
.. regendoc:wipe
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_bar(fix_w_yield1, fix_w_yield2):
|
||||||
|
print("test_bar")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fix_w_yield1():
|
||||||
|
yield
|
||||||
|
print("after_yield_1")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fix_w_yield2():
|
||||||
|
yield
|
||||||
|
print("after_yield_2")
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: pytest
|
||||||
|
|
||||||
|
$ pytest test_module.py
|
||||||
|
=========================== test session starts ============================
|
||||||
|
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
|
||||||
|
collected 1 item
|
||||||
|
|
||||||
|
test_module.py test_bar
|
||||||
|
.after_yield_2
|
||||||
|
after_yield_1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
For finalizers, the first fixture to run is last call to `request.addfinalizer`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fix_w_finalizers(request):
|
||||||
|
request.addfinalizer(partial(print, "finalizer_2"))
|
||||||
|
request.addfinalizer(partial(print, "finalizer_1"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_bar(fix_w_finalizers):
|
||||||
|
print("test_bar")
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: pytest
|
||||||
|
|
||||||
|
$ pytest test_module.py
|
||||||
|
=========================== test session starts ============================
|
||||||
|
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
|
||||||
|
collected 1 item
|
||||||
|
|
||||||
|
test_module.py test_bar
|
||||||
|
.finalizer_1
|
||||||
|
finalizer_2
|
||||||
|
|
||||||
|
This is so because yield fixtures use `addfinalizer` behind the scenes: when the fixture executes, `addfinalizer` registers a function that resumes the generator, which in turn calls the teardown code.
|
||||||
|
|
||||||
|
|
||||||
.. _`safe teardowns`:
|
.. _`safe teardowns`:
|
||||||
|
|
||||||
Safe teardowns
|
Safe teardowns
|
||||||
|
|
|
@ -14,18 +14,16 @@ environment variable, or to modify ``sys.path`` for importing.
|
||||||
The ``monkeypatch`` fixture provides these helper methods for safely patching and mocking
|
The ``monkeypatch`` fixture provides these helper methods for safely patching and mocking
|
||||||
functionality in tests:
|
functionality in tests:
|
||||||
|
|
||||||
.. code-block:: python
|
* :meth:`monkeypatch.setattr(obj, name, value, raising=True) <pytest.MonkeyPatch.setattr>`
|
||||||
|
* :meth:`monkeypatch.delattr(obj, name, raising=True) <pytest.MonkeyPatch.delattr>`
|
||||||
|
* :meth:`monkeypatch.setitem(mapping, name, value) <pytest.MonkeyPatch.setitem>`
|
||||||
|
* :meth:`monkeypatch.delitem(obj, name, raising=True) <pytest.MonkeyPatch.delitem>`
|
||||||
|
* :meth:`monkeypatch.setenv(name, value, prepend=None) <pytest.MonkeyPatch.setenv>`
|
||||||
|
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
|
||||||
|
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
|
||||||
|
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
|
||||||
|
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
|
||||||
|
|
||||||
monkeypatch.setattr(obj, name, value, raising=True)
|
|
||||||
monkeypatch.setattr("somemodule.obj.name", value, raising=True)
|
|
||||||
monkeypatch.delattr(obj, name, raising=True)
|
|
||||||
monkeypatch.setitem(mapping, name, value)
|
|
||||||
monkeypatch.delitem(obj, name, raising=True)
|
|
||||||
monkeypatch.setenv(name, value, prepend=None)
|
|
||||||
monkeypatch.delenv(name, raising=True)
|
|
||||||
monkeypatch.syspath_prepend(path)
|
|
||||||
monkeypatch.chdir(path)
|
|
||||||
monkeypatch.context()
|
|
||||||
|
|
||||||
All modifications will be undone after the requesting
|
All modifications will be undone after the requesting
|
||||||
test function or fixture has finished. The ``raising``
|
test function or fixture has finished. The ``raising``
|
||||||
|
@ -64,8 +62,8 @@ and a discussion of its motivation.
|
||||||
|
|
||||||
.. _`monkeypatch blog post`: https://tetamap.wordpress.com//2009/03/03/monkeypatching-in-unit-tests-done-right/
|
.. _`monkeypatch blog post`: https://tetamap.wordpress.com//2009/03/03/monkeypatching-in-unit-tests-done-right/
|
||||||
|
|
||||||
Simple example: monkeypatching functions
|
Monkeypatching functions
|
||||||
----------------------------------------
|
------------------------
|
||||||
|
|
||||||
Consider a scenario where you are working with user directories. In the context of
|
Consider a scenario where you are working with user directories. In the context of
|
||||||
testing, you do not want your test to depend on the running user. ``monkeypatch``
|
testing, you do not want your test to depend on the running user. ``monkeypatch``
|
||||||
|
|
|
@ -90,7 +90,7 @@ and can also be used to hold pytest configuration if they have a ``[pytest]`` se
|
||||||
setup.cfg
|
setup.cfg
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
``setup.cfg`` files are general purpose configuration files, used originally by :doc:`distutils <distutils/configfile>`, and can also be used to hold pytest configuration
|
``setup.cfg`` files are general purpose configuration files, used originally by :doc:`distutils <python:distutils/configfile>`, and can also be used to hold pytest configuration
|
||||||
if they have a ``[tool:pytest]`` section.
|
if they have a ``[tool:pytest]`` section.
|
||||||
|
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
|
@ -11,7 +11,7 @@ automatically. Packages classified as inactive are excluded.
|
||||||
creating a PDF, because otherwise the table gets far too wide for the
|
creating a PDF, because otherwise the table gets far too wide for the
|
||||||
page.
|
page.
|
||||||
|
|
||||||
This list contains 1094 plugins.
|
This list contains 1100 plugins.
|
||||||
|
|
||||||
.. only:: not latex
|
.. only:: not latex
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-coverage-context` Coverage dynamic context support for PyTest, including sub-processes Jan 04, 2021 4 - Beta pytest (>=6.1.0)
|
:pypi:`pytest-coverage-context` Coverage dynamic context support for PyTest, including sub-processes Jan 04, 2021 4 - Beta pytest (>=6.1.0)
|
||||||
:pypi:`pytest-cov-exclude` Pytest plugin for excluding tests based on coverage data Apr 29, 2016 4 - Beta pytest (>=2.8.0,<2.9.0); extra == 'dev'
|
:pypi:`pytest-cov-exclude` Pytest plugin for excluding tests based on coverage data Apr 29, 2016 4 - Beta pytest (>=2.8.0,<2.9.0); extra == 'dev'
|
||||||
:pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Mar 18, 2022 5 - Production/Stable pytest (!=5.4.0,!=5.4.1)
|
:pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Mar 18, 2022 5 - Production/Stable pytest (!=5.4.0,!=5.4.1)
|
||||||
:pypi:`pytest-cppython` A pytest plugin that imports CPPython testing types Jun 08, 2022 N/A N/A
|
:pypi:`pytest-cppython` A pytest plugin that imports CPPython testing types Aug 13, 2022 N/A N/A
|
||||||
:pypi:`pytest-cram` Run cram tests with pytest. Aug 08, 2020 N/A N/A
|
:pypi:`pytest-cram` Run cram tests with pytest. Aug 08, 2020 N/A N/A
|
||||||
:pypi:`pytest-crate` Manages CrateDB instances during your integration tests May 28, 2019 3 - Alpha pytest (>=4.0)
|
:pypi:`pytest-crate` Manages CrateDB instances during your integration tests May 28, 2019 3 - Alpha pytest (>=4.0)
|
||||||
:pypi:`pytest-cricri` A Cricri plugin for pytest. Jan 27, 2018 N/A pytest
|
:pypi:`pytest-cricri` A Cricri plugin for pytest. Jan 27, 2018 N/A pytest
|
||||||
|
@ -372,7 +372,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-factoryboy-state` Simple factoryboy random state management Mar 22, 2022 5 - Production/Stable pytest (>=5.0)
|
:pypi:`pytest-factoryboy-state` Simple factoryboy random state management Mar 22, 2022 5 - Production/Stable pytest (>=5.0)
|
||||||
:pypi:`pytest-failed-screenshot` Test case fails,take a screenshot,save it,attach it to the allure Apr 21, 2021 N/A N/A
|
:pypi:`pytest-failed-screenshot` Test case fails,take a screenshot,save it,attach it to the allure Apr 21, 2021 N/A N/A
|
||||||
:pypi:`pytest-failed-to-verify` A pytest plugin that helps better distinguishing real test failures from setup flakiness. Aug 08, 2019 5 - Production/Stable pytest (>=4.1.0)
|
:pypi:`pytest-failed-to-verify` A pytest plugin that helps better distinguishing real test failures from setup flakiness. Aug 08, 2019 5 - Production/Stable pytest (>=4.1.0)
|
||||||
:pypi:`pytest-fail-slow` Fail tests that take too long to run Apr 25, 2022 4 - Beta pytest (>=6.0)
|
:pypi:`pytest-fail-slow` Fail tests that take too long to run Aug 13, 2022 4 - Beta pytest (>=6.0)
|
||||||
:pypi:`pytest-faker` Faker integration with the pytest framework. Dec 19, 2016 6 - Mature N/A
|
:pypi:`pytest-faker` Faker integration with the pytest framework. Dec 19, 2016 6 - Mature N/A
|
||||||
:pypi:`pytest-falcon` Pytest helpers for Falcon. Sep 07, 2016 4 - Beta N/A
|
:pypi:`pytest-falcon` Pytest helpers for Falcon. Sep 07, 2016 4 - Beta N/A
|
||||||
:pypi:`pytest-falcon-client` Pytest \`client\` fixture for the Falcon Framework Mar 19, 2019 N/A N/A
|
:pypi:`pytest-falcon-client` Pytest \`client\` fixture for the Falcon Framework Mar 19, 2019 N/A N/A
|
||||||
|
@ -407,6 +407,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-flakes` pytest plugin to check source code with pyflakes Dec 02, 2021 5 - Production/Stable pytest (>=5)
|
:pypi:`pytest-flakes` pytest plugin to check source code with pyflakes Dec 02, 2021 5 - Production/Stable pytest (>=5)
|
||||||
:pypi:`pytest-flaptastic` Flaptastic py.test plugin Mar 17, 2019 N/A N/A
|
:pypi:`pytest-flaptastic` Flaptastic py.test plugin Mar 17, 2019 N/A N/A
|
||||||
:pypi:`pytest-flask` A set of py.test fixtures to test Flask applications. Feb 27, 2021 5 - Production/Stable pytest (>=5.2)
|
:pypi:`pytest-flask` A set of py.test fixtures to test Flask applications. Feb 27, 2021 5 - Production/Stable pytest (>=5.2)
|
||||||
|
:pypi:`pytest-flask-ligand` Pytest fixtures and helper functions to use for testing flask-ligand microservices. Aug 09, 2022 4 - Beta pytest (~=7.1)
|
||||||
:pypi:`pytest-flask-sqlalchemy` A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions. Apr 30, 2022 4 - Beta pytest (>=3.2.1)
|
:pypi:`pytest-flask-sqlalchemy` A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions. Apr 30, 2022 4 - Beta pytest (>=3.2.1)
|
||||||
:pypi:`pytest-flask-sqlalchemy-transactions` Run tests in transactions using pytest, Flask, and SQLalchemy. Aug 02, 2018 4 - Beta pytest (>=3.2.1)
|
:pypi:`pytest-flask-sqlalchemy-transactions` Run tests in transactions using pytest, Flask, and SQLalchemy. Aug 02, 2018 4 - Beta pytest (>=3.2.1)
|
||||||
:pypi:`pytest-fluent` A pytest plugin in order to provide logs via fluentd Jul 12, 2022 4 - Beta pytest
|
:pypi:`pytest-fluent` A pytest plugin in order to provide logs via fluentd Jul 12, 2022 4 - Beta pytest
|
||||||
|
@ -456,7 +457,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-historic` Custom report to display pytest historical execution records Apr 08, 2020 N/A pytest
|
:pypi:`pytest-historic` Custom report to display pytest historical execution records Apr 08, 2020 N/A pytest
|
||||||
:pypi:`pytest-historic-hook` Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report Apr 08, 2020 N/A pytest
|
:pypi:`pytest-historic-hook` Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report Apr 08, 2020 N/A pytest
|
||||||
:pypi:`pytest-homeassistant` A pytest plugin for use with homeassistant custom components. Aug 12, 2020 4 - Beta N/A
|
:pypi:`pytest-homeassistant` A pytest plugin for use with homeassistant custom components. Aug 12, 2020 4 - Beta N/A
|
||||||
:pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Aug 05, 2022 3 - Alpha pytest (==7.1.2)
|
:pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Aug 13, 2022 3 - Alpha pytest (==7.1.2)
|
||||||
:pypi:`pytest-honey` A simple plugin to use with pytest Jan 07, 2022 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-honey` A simple plugin to use with pytest Jan 07, 2022 4 - Beta pytest (>=3.5.0)
|
||||||
:pypi:`pytest-honors` Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A
|
:pypi:`pytest-honors` Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A
|
||||||
:pypi:`pytest-hoverfly` Simplify working with Hoverfly from pytest Mar 28, 2022 N/A pytest (>=5.0)
|
:pypi:`pytest-hoverfly` Simplify working with Hoverfly from pytest Mar 28, 2022 N/A pytest (>=5.0)
|
||||||
|
@ -480,7 +481,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-hylang` Pytest plugin to allow running tests written in hylang Mar 28, 2021 N/A pytest
|
:pypi:`pytest-hylang` Pytest plugin to allow running tests written in hylang Mar 28, 2021 N/A pytest
|
||||||
:pypi:`pytest-hypo-25` help hypo module for pytest Jan 12, 2020 3 - Alpha N/A
|
:pypi:`pytest-hypo-25` help hypo module for pytest Jan 12, 2020 3 - Alpha N/A
|
||||||
:pypi:`pytest-ibutsu` A plugin to sent pytest results to an Ibutsu server Aug 05, 2022 4 - Beta N/A
|
:pypi:`pytest-ibutsu` A plugin to sent pytest results to an Ibutsu server Aug 05, 2022 4 - Beta N/A
|
||||||
:pypi:`pytest-icdiff` use icdiff for better error messages in pytest assertions Apr 08, 2020 4 - Beta N/A
|
:pypi:`pytest-icdiff` use icdiff for better error messages in pytest assertions Aug 09, 2022 4 - Beta N/A
|
||||||
:pypi:`pytest-idapro` A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api Nov 03, 2018 N/A N/A
|
:pypi:`pytest-idapro` A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api Nov 03, 2018 N/A N/A
|
||||||
:pypi:`pytest-idem` A pytest plugin to help with testing idem projects Jun 29, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-idem` A pytest plugin to help with testing idem projects Jun 29, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-idempotent` Pytest plugin for testing function idempotence. Jul 25, 2022 N/A N/A
|
:pypi:`pytest-idempotent` Pytest plugin for testing function idempotence. Jul 25, 2022 N/A N/A
|
||||||
|
@ -493,7 +494,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-infrastructure` pytest stack validation prior to testing executing Apr 12, 2020 4 - Beta N/A
|
:pypi:`pytest-infrastructure` pytest stack validation prior to testing executing Apr 12, 2020 4 - Beta N/A
|
||||||
:pypi:`pytest-ini` Reuse pytest.ini to store env variables Apr 26, 2022 N/A N/A
|
:pypi:`pytest-ini` Reuse pytest.ini to store env variables Apr 26, 2022 N/A N/A
|
||||||
:pypi:`pytest-inmanta` A py.test plugin providing fixtures to simplify inmanta modules testing. May 18, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-inmanta` A py.test plugin providing fixtures to simplify inmanta modules testing. May 18, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-inmanta-extensions` Inmanta tests package Apr 12, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-inmanta-extensions` Inmanta tests package Aug 10, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-inmanta-lsm` Common fixtures for inmanta LSM related modules Jul 14, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-inmanta-lsm` Common fixtures for inmanta LSM related modules Jul 14, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-inmanta-yang` Common fixtures used in inmanta yang related modules Jun 16, 2022 4 - Beta N/A
|
:pypi:`pytest-inmanta-yang` Common fixtures used in inmanta yang related modules Jun 16, 2022 4 - Beta N/A
|
||||||
:pypi:`pytest-Inomaly` A simple image diff plugin for pytest Feb 13, 2018 4 - Beta N/A
|
:pypi:`pytest-Inomaly` A simple image diff plugin for pytest Feb 13, 2018 4 - Beta N/A
|
||||||
|
@ -504,7 +505,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-integration-mark` Automatic integration test marking and excluding plugin for pytest Jul 19, 2021 N/A pytest (>=5.2,<7.0)
|
:pypi:`pytest-integration-mark` Automatic integration test marking and excluding plugin for pytest Jul 19, 2021 N/A pytest (>=5.2,<7.0)
|
||||||
:pypi:`pytest-interactive` A pytest plugin for console based interactive test selection just after the collection phase Nov 30, 2017 3 - Alpha N/A
|
:pypi:`pytest-interactive` A pytest plugin for console based interactive test selection just after the collection phase Nov 30, 2017 3 - Alpha N/A
|
||||||
:pypi:`pytest-intercept-remote` Pytest plugin for intercepting outgoing connection requests during pytest run. May 24, 2021 4 - Beta pytest (>=4.6)
|
:pypi:`pytest-intercept-remote` Pytest plugin for intercepting outgoing connection requests during pytest run. May 24, 2021 4 - Beta pytest (>=4.6)
|
||||||
:pypi:`pytest-invenio` Pytest fixtures for Invenio. May 05, 2022 5 - Production/Stable pytest (<7,>=6)
|
:pypi:`pytest-invenio` "Pytest fixtures for Invenio." Aug 09, 2022 5 - Production/Stable pytest (<7,>=6)
|
||||||
:pypi:`pytest-involve` Run tests covering a specific file or changeset Feb 02, 2020 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-involve` Run tests covering a specific file or changeset Feb 02, 2020 4 - Beta pytest (>=3.5.0)
|
||||||
:pypi:`pytest-ipdb` A py.test plug-in to enable drop to ipdb debugger on test failure. Sep 02, 2014 2 - Pre-Alpha N/A
|
:pypi:`pytest-ipdb` A py.test plug-in to enable drop to ipdb debugger on test failure. Sep 02, 2014 2 - Pre-Alpha N/A
|
||||||
:pypi:`pytest-ipynb` THIS PROJECT IS ABANDONED Jan 29, 2019 3 - Alpha N/A
|
:pypi:`pytest-ipynb` THIS PROJECT IS ABANDONED Jan 29, 2019 3 - Alpha N/A
|
||||||
|
@ -520,13 +521,13 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-jobserver` Limit parallel tests with posix jobserver. May 15, 2019 5 - Production/Stable pytest
|
:pypi:`pytest-jobserver` Limit parallel tests with posix jobserver. May 15, 2019 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-joke` Test failures are better served with humor. Oct 08, 2019 4 - Beta pytest (>=4.2.1)
|
:pypi:`pytest-joke` Test failures are better served with humor. Oct 08, 2019 4 - Beta pytest (>=4.2.1)
|
||||||
:pypi:`pytest-json` Generate JSON test reports Jan 18, 2016 4 - Beta N/A
|
:pypi:`pytest-json` Generate JSON test reports Jan 18, 2016 4 - Beta N/A
|
||||||
:pypi:`pytest-json-fixtures` JSON output for the --fixtures flag Aug 03, 2022 4 - Beta pytest (>=7.1.0)
|
:pypi:`pytest-json-fixtures` JSON output for the --fixtures flag Aug 09, 2022 4 - Beta pytest (>=7.1.0)
|
||||||
:pypi:`pytest-jsonlint` UNKNOWN Aug 04, 2016 N/A N/A
|
:pypi:`pytest-jsonlint` UNKNOWN Aug 04, 2016 N/A N/A
|
||||||
:pypi:`pytest-json-report` A pytest plugin to report test results as JSON files Mar 15, 2022 4 - Beta pytest (>=3.8.0)
|
:pypi:`pytest-json-report` A pytest plugin to report test results as JSON files Mar 15, 2022 4 - Beta pytest (>=3.8.0)
|
||||||
:pypi:`pytest-kafka` Zookeeper, Kafka server, and Kafka consumer fixtures for Pytest Aug 24, 2021 N/A pytest
|
:pypi:`pytest-kafka` Zookeeper, Kafka server, and Kafka consumer fixtures for Pytest Aug 24, 2021 N/A pytest
|
||||||
:pypi:`pytest-kafkavents` A plugin to send pytest events to Kafka Sep 08, 2021 4 - Beta pytest
|
:pypi:`pytest-kafkavents` A plugin to send pytest events to Kafka Sep 08, 2021 4 - Beta pytest
|
||||||
:pypi:`pytest-kexi` Apr 29, 2022 N/A pytest (>=7.1.2,<8.0.0)
|
:pypi:`pytest-kexi` Apr 29, 2022 N/A pytest (>=7.1.2,<8.0.0)
|
||||||
:pypi:`pytest-kind` Kubernetes test support with KIND for pytest Jan 24, 2021 5 - Production/Stable N/A
|
:pypi:`pytest-kind` Kubernetes test support with KIND for pytest Aug 11, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-kivy` Kivy GUI tests fixtures using pytest Jul 06, 2021 4 - Beta pytest (>=3.6)
|
:pypi:`pytest-kivy` Kivy GUI tests fixtures using pytest Jul 06, 2021 4 - Beta pytest (>=3.6)
|
||||||
:pypi:`pytest-knows` A pytest plugin that can automaticly skip test case based on dependence info calculated by trace Aug 22, 2014 N/A N/A
|
:pypi:`pytest-knows` A pytest plugin that can automaticly skip test case based on dependence info calculated by trace Aug 22, 2014 N/A N/A
|
||||||
:pypi:`pytest-konira` Run Konira DSL tests with py.test Oct 09, 2011 N/A N/A
|
:pypi:`pytest-konira` Run Konira DSL tests with py.test Oct 09, 2011 N/A N/A
|
||||||
|
@ -547,6 +548,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-ligo` Jan 16, 2020 4 - Beta N/A
|
:pypi:`pytest-ligo` Jan 16, 2020 4 - Beta N/A
|
||||||
:pypi:`pytest-lineno` A pytest plugin to show the line numbers of test functions Dec 04, 2020 N/A pytest
|
:pypi:`pytest-lineno` A pytest plugin to show the line numbers of test functions Dec 04, 2020 N/A pytest
|
||||||
:pypi:`pytest-line-profiler` Profile code executed by pytest May 03, 2021 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-line-profiler` Profile code executed by pytest May 03, 2021 4 - Beta pytest (>=3.5.0)
|
||||||
|
:pypi:`pytest-line-profiler-apn` Profile code executed by pytest Aug 13, 2022 4 - Beta N/A
|
||||||
:pypi:`pytest-lisa` Pytest plugin for organizing tests. Jan 21, 2021 3 - Alpha pytest (>=6.1.2,<7.0.0)
|
:pypi:`pytest-lisa` Pytest plugin for organizing tests. Jan 21, 2021 3 - Alpha pytest (>=6.1.2,<7.0.0)
|
||||||
:pypi:`pytest-listener` A simple network listener May 28, 2019 5 - Production/Stable pytest
|
:pypi:`pytest-listener` A simple network listener May 28, 2019 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-litf` A pytest plugin that stream output in LITF format Jan 18, 2021 4 - Beta pytest (>=3.1.1)
|
:pypi:`pytest-litf` A pytest plugin that stream output in LITF format Jan 18, 2021 4 - Beta pytest (>=3.1.1)
|
||||||
|
@ -603,7 +605,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-mock-helper` Help you mock HTTP call and generate mock code Jan 24, 2018 N/A pytest
|
:pypi:`pytest-mock-helper` Help you mock HTTP call and generate mock code Jan 24, 2018 N/A pytest
|
||||||
:pypi:`pytest-mockito` Base fixtures for mockito Jul 11, 2018 4 - Beta N/A
|
:pypi:`pytest-mockito` Base fixtures for mockito Jul 11, 2018 4 - Beta N/A
|
||||||
:pypi:`pytest-mockredis` An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database. Jan 02, 2018 2 - Pre-Alpha N/A
|
:pypi:`pytest-mockredis` An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database. Jan 02, 2018 2 - Pre-Alpha N/A
|
||||||
:pypi:`pytest-mock-resources` A pytest plugin for easily instantiating reproducible mock resources. Jul 20, 2022 N/A pytest (>=1.0)
|
:pypi:`pytest-mock-resources` A pytest plugin for easily instantiating reproducible mock resources. Aug 12, 2022 N/A pytest (>=1.0)
|
||||||
:pypi:`pytest-mock-server` Mock server plugin for pytest Jan 09, 2022 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-mock-server` Mock server plugin for pytest Jan 09, 2022 4 - Beta pytest (>=3.5.0)
|
||||||
:pypi:`pytest-mockservers` A set of fixtures to test your requests to HTTP/UDP servers Mar 31, 2020 N/A pytest (>=4.3.0)
|
:pypi:`pytest-mockservers` A set of fixtures to test your requests to HTTP/UDP servers Mar 31, 2020 N/A pytest (>=4.3.0)
|
||||||
:pypi:`pytest-modified-env` Pytest plugin to fail a test if it leaves modified \`os.environ\` afterwards. Jan 29, 2022 4 - Beta N/A
|
:pypi:`pytest-modified-env` Pytest plugin to fail a test if it leaves modified \`os.environ\` afterwards. Jan 29, 2022 4 - Beta N/A
|
||||||
|
@ -642,7 +644,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-nginx-iplweb` nginx fixture for pytest - iplweb temporary fork Mar 01, 2019 5 - Production/Stable N/A
|
:pypi:`pytest-nginx-iplweb` nginx fixture for pytest - iplweb temporary fork Mar 01, 2019 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-ngrok` Jan 20, 2022 3 - Alpha pytest
|
:pypi:`pytest-ngrok` Jan 20, 2022 3 - Alpha pytest
|
||||||
:pypi:`pytest-ngsfixtures` pytest ngs fixtures Sep 06, 2019 2 - Pre-Alpha pytest (>=5.0.0)
|
:pypi:`pytest-ngsfixtures` pytest ngs fixtures Sep 06, 2019 2 - Pre-Alpha pytest (>=5.0.0)
|
||||||
:pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies Jul 21, 2022 N/A pytest (==6.2.5)
|
:pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies Aug 10, 2022 N/A pytest (==6.2.5)
|
||||||
:pypi:`pytest-nice` A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest
|
:pypi:`pytest-nice` A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest
|
||||||
:pypi:`pytest-nice-parametrize` A small snippet for nicer PyTest's Parametrize Apr 17, 2021 5 - Production/Stable N/A
|
:pypi:`pytest-nice-parametrize` A small snippet for nicer PyTest's Parametrize Apr 17, 2021 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-nlcov` Pytest plugin to get the coverage of the new lines (based on git diff) only Jul 07, 2021 N/A N/A
|
:pypi:`pytest-nlcov` Pytest plugin to get the coverage of the new lines (based on git diff) only Jul 07, 2021 N/A N/A
|
||||||
|
@ -751,7 +753,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-pydev` py.test plugin to connect to a remote debug server with PyDev or PyCharm. Nov 15, 2017 3 - Alpha N/A
|
:pypi:`pytest-pydev` py.test plugin to connect to a remote debug server with PyDev or PyCharm. Nov 15, 2017 3 - Alpha N/A
|
||||||
:pypi:`pytest-pydocstyle` pytest plugin to run pydocstyle Mar 13, 2022 3 - Alpha N/A
|
:pypi:`pytest-pydocstyle` pytest plugin to run pydocstyle Mar 13, 2022 3 - Alpha N/A
|
||||||
:pypi:`pytest-pylint` pytest plugin to check source code with pylint Nov 09, 2020 5 - Production/Stable pytest (>=5.4)
|
:pypi:`pytest-pylint` pytest plugin to check source code with pylint Nov 09, 2020 5 - Production/Stable pytest (>=5.4)
|
||||||
:pypi:`pytest-pyodide` "Pytest plugin for testing applications that use Pyodide" Aug 04, 2022 N/A pytest
|
:pypi:`pytest-pyodide` "Pytest plugin for testing applications that use Pyodide" Aug 10, 2022 N/A pytest
|
||||||
:pypi:`pytest-pypi` Easily test your HTTP library against a local copy of pypi Mar 04, 2018 3 - Alpha N/A
|
:pypi:`pytest-pypi` Easily test your HTTP library against a local copy of pypi Mar 04, 2018 3 - Alpha N/A
|
||||||
:pypi:`pytest-pypom-navigation` Core engine for cookiecutter-qa and pytest-play packages Feb 18, 2019 4 - Beta pytest (>=3.0.7)
|
:pypi:`pytest-pypom-navigation` Core engine for cookiecutter-qa and pytest-play packages Feb 18, 2019 4 - Beta pytest (>=3.0.7)
|
||||||
:pypi:`pytest-pyppeteer` A plugin to run pyppeteer in pytest Apr 28, 2022 N/A pytest (>=6.2.5,<7.0.0)
|
:pypi:`pytest-pyppeteer` A plugin to run pyppeteer in pytest Apr 28, 2022 N/A pytest (>=6.2.5,<7.0.0)
|
||||||
|
@ -823,18 +825,20 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-rerun` Re-run only changed files in specified branch Jul 08, 2019 N/A pytest (>=3.6)
|
:pypi:`pytest-rerun` Re-run only changed files in specified branch Jul 08, 2019 N/A pytest (>=3.6)
|
||||||
:pypi:`pytest-rerunfailures` pytest plugin to re-run tests to eliminate flaky failures Sep 17, 2021 5 - Production/Stable pytest (>=5.3)
|
:pypi:`pytest-rerunfailures` pytest plugin to re-run tests to eliminate flaky failures Sep 17, 2021 5 - Production/Stable pytest (>=5.3)
|
||||||
:pypi:`pytest-rerunfailures-all-logs` pytest plugin to re-run tests to eliminate flaky failures Mar 07, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-rerunfailures-all-logs` pytest plugin to re-run tests to eliminate flaky failures Mar 07, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-resilient-circuits` Resilient Circuits fixtures for PyTest. Jul 07, 2022 N/A N/A
|
:pypi:`pytest-resilient-circuits` Resilient Circuits fixtures for PyTest. Aug 12, 2022 N/A N/A
|
||||||
:pypi:`pytest-resource` Load resource fixture plugin to use with pytest Nov 14, 2018 4 - Beta N/A
|
:pypi:`pytest-resource` Load resource fixture plugin to use with pytest Nov 14, 2018 4 - Beta N/A
|
||||||
:pypi:`pytest-resource-path` Provides path for uniform access to test resources in isolated directory May 01, 2021 5 - Production/Stable pytest (>=3.5.0)
|
:pypi:`pytest-resource-path` Provides path for uniform access to test resources in isolated directory May 01, 2021 5 - Production/Stable pytest (>=3.5.0)
|
||||||
:pypi:`pytest-responsemock` Simplified requests calls mocking for pytest Mar 10, 2022 5 - Production/Stable N/A
|
:pypi:`pytest-responsemock` Simplified requests calls mocking for pytest Mar 10, 2022 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-responses` py.test integration for responses Apr 26, 2021 N/A pytest (>=2.5)
|
:pypi:`pytest-responses` py.test integration for responses Apr 26, 2021 N/A pytest (>=2.5)
|
||||||
|
:pypi:`pytest-rest-api` Aug 08, 2022 N/A pytest (>=7.1.2,<8.0.0)
|
||||||
:pypi:`pytest-restrict` Pytest plugin to restrict the test types allowed May 11, 2022 5 - Production/Stable pytest
|
:pypi:`pytest-restrict` Pytest plugin to restrict the test types allowed May 11, 2022 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-rethinkdb` A RethinkDB plugin for pytest. Jul 24, 2016 4 - Beta N/A
|
:pypi:`pytest-rethinkdb` A RethinkDB plugin for pytest. Jul 24, 2016 4 - Beta N/A
|
||||||
:pypi:`pytest-retry` Adds the ability to retry flaky tests in CI environments Aug 05, 2022 N/A pytest (>=7.0.0)
|
:pypi:`pytest-retry` Adds the ability to retry flaky tests in CI environments Aug 11, 2022 N/A pytest (>=7.0.0)
|
||||||
:pypi:`pytest-reverse` Pytest plugin to reverse test order. May 11, 2022 5 - Production/Stable pytest
|
:pypi:`pytest-reverse` Pytest plugin to reverse test order. May 11, 2022 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-rich` Leverage rich for richer test session output Mar 03, 2022 4 - Beta pytest (>=7.0)
|
:pypi:`pytest-rich` Leverage rich for richer test session output Mar 03, 2022 4 - Beta pytest (>=7.0)
|
||||||
:pypi:`pytest-rich-reporter` A pytest plugin using Rich for beautiful test result formatting. Feb 17, 2022 1 - Planning pytest (>=5.0.0)
|
:pypi:`pytest-rich-reporter` A pytest plugin using Rich for beautiful test result formatting. Feb 17, 2022 1 - Planning pytest (>=5.0.0)
|
||||||
:pypi:`pytest-ringo` pytest plugin to test webapplications using the Ringo webframework Sep 27, 2017 3 - Alpha N/A
|
:pypi:`pytest-ringo` pytest plugin to test webapplications using the Ringo webframework Sep 27, 2017 3 - Alpha N/A
|
||||||
|
:pypi:`pytest-rmsis` Sycronise pytest results to Jira RMsis Aug 10, 2022 N/A pytest (>=5.3.5)
|
||||||
:pypi:`pytest-rng` Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest
|
:pypi:`pytest-rng` Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-roast` pytest plugin for ROAST configuration override and fixtures Jul 29, 2021 5 - Production/Stable pytest
|
:pypi:`pytest-roast` pytest plugin for ROAST configuration override and fixtures Jul 29, 2021 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-rocketchat` Pytest to Rocket.Chat reporting plugin Apr 18, 2021 5 - Production/Stable N/A
|
:pypi:`pytest-rocketchat` Pytest to Rocket.Chat reporting plugin Apr 18, 2021 5 - Production/Stable N/A
|
||||||
|
@ -928,6 +932,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-splunk-env` pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud Oct 22, 2020 N/A pytest (>=6.1.1,<7.0.0)
|
:pypi:`pytest-splunk-env` pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud Oct 22, 2020 N/A pytest (>=6.1.1,<7.0.0)
|
||||||
:pypi:`pytest-sqitch` sqitch for pytest Apr 06, 2020 4 - Beta N/A
|
:pypi:`pytest-sqitch` sqitch for pytest Apr 06, 2020 4 - Beta N/A
|
||||||
:pypi:`pytest-sqlalchemy` pytest plugin with sqlalchemy related fixtures Mar 13, 2018 3 - Alpha N/A
|
:pypi:`pytest-sqlalchemy` pytest plugin with sqlalchemy related fixtures Mar 13, 2018 3 - Alpha N/A
|
||||||
|
:pypi:`pytest-sqlalchemy-mock` pytest sqlalchemy plugin for mock Aug 10, 2022 3 - Alpha pytest (>=2.0)
|
||||||
:pypi:`pytest-sql-bigquery` Yet another SQL-testing framework for BigQuery provided by pytest plugin Dec 19, 2019 N/A pytest
|
:pypi:`pytest-sql-bigquery` Yet another SQL-testing framework for BigQuery provided by pytest plugin Dec 19, 2019 N/A pytest
|
||||||
:pypi:`pytest-squadcast` Pytest report plugin for Squadcast Feb 22, 2022 5 - Production/Stable pytest
|
:pypi:`pytest-squadcast` Pytest report plugin for Squadcast Feb 22, 2022 5 - Production/Stable pytest
|
||||||
:pypi:`pytest-srcpaths` Add paths to sys.path Oct 15, 2021 N/A N/A
|
:pypi:`pytest-srcpaths` Add paths to sys.path Oct 15, 2021 N/A N/A
|
||||||
|
@ -988,7 +993,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-testrail-client` pytest plugin for Testrail Sep 29, 2020 5 - Production/Stable N/A
|
:pypi:`pytest-testrail-client` pytest plugin for Testrail Sep 29, 2020 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-testrail-e2e` pytest plugin for creating TestRail runs and adding results Oct 11, 2021 N/A pytest (>=3.6)
|
:pypi:`pytest-testrail-e2e` pytest plugin for creating TestRail runs and adding results Oct 11, 2021 N/A pytest (>=3.6)
|
||||||
:pypi:`pytest-testrail-integrator` Pytest plugin for sending report to testrail system. Aug 01, 2022 N/A pytest (>=6.2.5)
|
:pypi:`pytest-testrail-integrator` Pytest plugin for sending report to testrail system. Aug 01, 2022 N/A pytest (>=6.2.5)
|
||||||
:pypi:`pytest-testrail-ns` pytest plugin for creating TestRail runs and adding results Jul 26, 2022 N/A pytest (>=3.6)
|
:pypi:`pytest-testrail-ns` pytest plugin for creating TestRail runs and adding results Aug 12, 2022 N/A N/A
|
||||||
:pypi:`pytest-testrail-plugin` PyTest plugin for TestRail Apr 21, 2020 3 - Alpha pytest
|
:pypi:`pytest-testrail-plugin` PyTest plugin for TestRail Apr 21, 2020 3 - Alpha pytest
|
||||||
:pypi:`pytest-testrail-reporter` Sep 10, 2018 N/A N/A
|
:pypi:`pytest-testrail-reporter` Sep 10, 2018 N/A N/A
|
||||||
:pypi:`pytest-testreport` May 23, 2022 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-testreport` May 23, 2022 4 - Beta pytest (>=3.5.0)
|
||||||
|
@ -1014,7 +1019,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-tm4j-reporter` Cloud Jira Test Management (TM4J) PyTest reporter plugin Sep 01, 2020 N/A pytest
|
:pypi:`pytest-tm4j-reporter` Cloud Jira Test Management (TM4J) PyTest reporter plugin Sep 01, 2020 N/A pytest
|
||||||
:pypi:`pytest-tmnet` A small example package Mar 01, 2022 N/A N/A
|
:pypi:`pytest-tmnet` A small example package Mar 01, 2022 N/A N/A
|
||||||
:pypi:`pytest-tmp-files` Utilities to create temporary file hierarchies in pytest. Apr 03, 2022 N/A pytest
|
:pypi:`pytest-tmp-files` Utilities to create temporary file hierarchies in pytest. Apr 03, 2022 N/A pytest
|
||||||
:pypi:`pytest-tmreport` this is a vue-element ui report for pytest Nov 17, 2021 N/A N/A
|
:pypi:`pytest-tmreport` this is a vue-element ui report for pytest Aug 12, 2022 N/A N/A
|
||||||
:pypi:`pytest-todo` A small plugin for the pytest testing framework, marking TODO comments as failure May 23, 2019 4 - Beta pytest
|
:pypi:`pytest-todo` A small plugin for the pytest testing framework, marking TODO comments as failure May 23, 2019 4 - Beta pytest
|
||||||
:pypi:`pytest-tomato` Mar 01, 2019 5 - Production/Stable N/A
|
:pypi:`pytest-tomato` Mar 01, 2019 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-toolbelt` This is just a collection of utilities for pytest, but don't really belong in pytest proper. Aug 12, 2019 3 - Alpha N/A
|
:pypi:`pytest-toolbelt` This is just a collection of utilities for pytest, but don't really belong in pytest proper. Aug 12, 2019 3 - Alpha N/A
|
||||||
|
@ -1036,7 +1041,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-tspwplib` A simple plugin to use with tspwplib Jan 08, 2021 4 - Beta pytest (>=3.5.0)
|
:pypi:`pytest-tspwplib` A simple plugin to use with tspwplib Jan 08, 2021 4 - Beta pytest (>=3.5.0)
|
||||||
:pypi:`pytest-tst` Customize pytest options, output and exit code to make it compatible with tst Apr 27, 2022 N/A pytest (>=5.0.0)
|
:pypi:`pytest-tst` Customize pytest options, output and exit code to make it compatible with tst Apr 27, 2022 N/A pytest (>=5.0.0)
|
||||||
:pypi:`pytest-tstcls` Test Class Base Mar 23, 2020 5 - Production/Stable N/A
|
:pypi:`pytest-tstcls` Test Class Base Mar 23, 2020 5 - Production/Stable N/A
|
||||||
:pypi:`pytest-tui` Text User Interface (TUI) for Pytest, automatically launched after your test run is finished Aug 03, 2022 4 - Beta pytest (>=6.2.5)
|
:pypi:`pytest-tui` Text User Interface (TUI) for Pytest, with optional auto-launch and HTML export Aug 13, 2022 4 - Beta pytest (>=6.2.5)
|
||||||
:pypi:`pytest-twilio-conversations-client-mock` Aug 02, 2022 N/A N/A
|
:pypi:`pytest-twilio-conversations-client-mock` Aug 02, 2022 N/A N/A
|
||||||
:pypi:`pytest-twisted` A twisted plugin for pytest. Aug 30, 2021 5 - Production/Stable pytest (>=2.3)
|
:pypi:`pytest-twisted` A twisted plugin for pytest. Aug 30, 2021 5 - Production/Stable pytest (>=2.3)
|
||||||
:pypi:`pytest-typechecker` Run type checkers on specified test files Feb 04, 2022 N/A pytest (>=6.2.5,<7.0.0)
|
:pypi:`pytest-typechecker` Run type checkers on specified test files Feb 04, 2022 N/A pytest (>=6.2.5,<7.0.0)
|
||||||
|
@ -1106,6 +1111,7 @@ This list contains 1094 plugins.
|
||||||
:pypi:`pytest-yapf` Run yapf Jul 06, 2017 4 - Beta pytest (>=3.1.1)
|
:pypi:`pytest-yapf` Run yapf Jul 06, 2017 4 - Beta pytest (>=3.1.1)
|
||||||
:pypi:`pytest-yapf3` Validate your Python file format with yapf Aug 03, 2020 5 - Production/Stable pytest (>=5.4)
|
:pypi:`pytest-yapf3` Validate your Python file format with yapf Aug 03, 2020 5 - Production/Stable pytest (>=5.4)
|
||||||
:pypi:`pytest-yield` PyTest plugin to run tests concurrently, each \`yield\` switch context to other one Jan 23, 2019 N/A N/A
|
:pypi:`pytest-yield` PyTest plugin to run tests concurrently, each \`yield\` switch context to other one Jan 23, 2019 N/A N/A
|
||||||
|
:pypi:`pytest-yls` Pytest plugin to test the YLS as a whole. Aug 08, 2022 N/A pytest (>=7.1.2,<8.0.0)
|
||||||
:pypi:`pytest-yuk` Display tests you are uneasy with, using 🤢/🤮 for pass/fail of tests marked with yuk. Mar 26, 2021 N/A N/A
|
:pypi:`pytest-yuk` Display tests you are uneasy with, using 🤢/🤮 for pass/fail of tests marked with yuk. Mar 26, 2021 N/A N/A
|
||||||
:pypi:`pytest-zafira` A Zafira plugin for pytest Sep 18, 2019 5 - Production/Stable pytest (==4.1.1)
|
:pypi:`pytest-zafira` A Zafira plugin for pytest Sep 18, 2019 5 - Production/Stable pytest (==4.1.1)
|
||||||
:pypi:`pytest-zap` OWASP ZAP plugin for py.test. May 12, 2014 4 - Beta N/A
|
:pypi:`pytest-zap` OWASP ZAP plugin for py.test. May 12, 2014 4 - Beta N/A
|
||||||
|
@ -2399,7 +2405,7 @@ This list contains 1094 plugins.
|
||||||
Use pytest's runner to discover and execute C++ tests
|
Use pytest's runner to discover and execute C++ tests
|
||||||
|
|
||||||
:pypi:`pytest-cppython`
|
:pypi:`pytest-cppython`
|
||||||
*last release*: Jun 08, 2022,
|
*last release*: Aug 13, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -3596,7 +3602,7 @@ This list contains 1094 plugins.
|
||||||
A pytest plugin that helps better distinguishing real test failures from setup flakiness.
|
A pytest plugin that helps better distinguishing real test failures from setup flakiness.
|
||||||
|
|
||||||
:pypi:`pytest-fail-slow`
|
:pypi:`pytest-fail-slow`
|
||||||
*last release*: Apr 25, 2022,
|
*last release*: Aug 13, 2022,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: pytest (>=6.0)
|
*requires*: pytest (>=6.0)
|
||||||
|
|
||||||
|
@ -3840,6 +3846,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
A set of py.test fixtures to test Flask applications.
|
A set of py.test fixtures to test Flask applications.
|
||||||
|
|
||||||
|
:pypi:`pytest-flask-ligand`
|
||||||
|
*last release*: Aug 09, 2022,
|
||||||
|
*status*: 4 - Beta,
|
||||||
|
*requires*: pytest (~=7.1)
|
||||||
|
|
||||||
|
Pytest fixtures and helper functions to use for testing flask-ligand microservices.
|
||||||
|
|
||||||
:pypi:`pytest-flask-sqlalchemy`
|
:pypi:`pytest-flask-sqlalchemy`
|
||||||
*last release*: Apr 30, 2022,
|
*last release*: Apr 30, 2022,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
|
@ -4184,7 +4197,7 @@ This list contains 1094 plugins.
|
||||||
A pytest plugin for use with homeassistant custom components.
|
A pytest plugin for use with homeassistant custom components.
|
||||||
|
|
||||||
:pypi:`pytest-homeassistant-custom-component`
|
:pypi:`pytest-homeassistant-custom-component`
|
||||||
*last release*: Aug 05, 2022,
|
*last release*: Aug 13, 2022,
|
||||||
*status*: 3 - Alpha,
|
*status*: 3 - Alpha,
|
||||||
*requires*: pytest (==7.1.2)
|
*requires*: pytest (==7.1.2)
|
||||||
|
|
||||||
|
@ -4352,7 +4365,7 @@ This list contains 1094 plugins.
|
||||||
A plugin to sent pytest results to an Ibutsu server
|
A plugin to sent pytest results to an Ibutsu server
|
||||||
|
|
||||||
:pypi:`pytest-icdiff`
|
:pypi:`pytest-icdiff`
|
||||||
*last release*: Apr 08, 2020,
|
*last release*: Aug 09, 2022,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -4443,7 +4456,7 @@ This list contains 1094 plugins.
|
||||||
A py.test plugin providing fixtures to simplify inmanta modules testing.
|
A py.test plugin providing fixtures to simplify inmanta modules testing.
|
||||||
|
|
||||||
:pypi:`pytest-inmanta-extensions`
|
:pypi:`pytest-inmanta-extensions`
|
||||||
*last release*: Apr 12, 2022,
|
*last release*: Aug 10, 2022,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -4520,11 +4533,11 @@ This list contains 1094 plugins.
|
||||||
Pytest plugin for intercepting outgoing connection requests during pytest run.
|
Pytest plugin for intercepting outgoing connection requests during pytest run.
|
||||||
|
|
||||||
:pypi:`pytest-invenio`
|
:pypi:`pytest-invenio`
|
||||||
*last release*: May 05, 2022,
|
*last release*: Aug 09, 2022,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: pytest (<7,>=6)
|
*requires*: pytest (<7,>=6)
|
||||||
|
|
||||||
Pytest fixtures for Invenio.
|
"Pytest fixtures for Invenio."
|
||||||
|
|
||||||
:pypi:`pytest-involve`
|
:pypi:`pytest-involve`
|
||||||
*last release*: Feb 02, 2020,
|
*last release*: Feb 02, 2020,
|
||||||
|
@ -4632,7 +4645,7 @@ This list contains 1094 plugins.
|
||||||
Generate JSON test reports
|
Generate JSON test reports
|
||||||
|
|
||||||
:pypi:`pytest-json-fixtures`
|
:pypi:`pytest-json-fixtures`
|
||||||
*last release*: Aug 03, 2022,
|
*last release*: Aug 09, 2022,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: pytest (>=7.1.0)
|
*requires*: pytest (>=7.1.0)
|
||||||
|
|
||||||
|
@ -4674,7 +4687,7 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
|
|
||||||
:pypi:`pytest-kind`
|
:pypi:`pytest-kind`
|
||||||
*last release*: Jan 24, 2021,
|
*last release*: Aug 11, 2022,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -4820,6 +4833,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
Profile code executed by pytest
|
Profile code executed by pytest
|
||||||
|
|
||||||
|
:pypi:`pytest-line-profiler-apn`
|
||||||
|
*last release*: Aug 13, 2022,
|
||||||
|
*status*: 4 - Beta,
|
||||||
|
*requires*: N/A
|
||||||
|
|
||||||
|
Profile code executed by pytest
|
||||||
|
|
||||||
:pypi:`pytest-lisa`
|
:pypi:`pytest-lisa`
|
||||||
*last release*: Jan 21, 2021,
|
*last release*: Jan 21, 2021,
|
||||||
*status*: 3 - Alpha,
|
*status*: 3 - Alpha,
|
||||||
|
@ -5213,7 +5233,7 @@ This list contains 1094 plugins.
|
||||||
An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database.
|
An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database.
|
||||||
|
|
||||||
:pypi:`pytest-mock-resources`
|
:pypi:`pytest-mock-resources`
|
||||||
*last release*: Jul 20, 2022,
|
*last release*: Aug 12, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (>=1.0)
|
*requires*: pytest (>=1.0)
|
||||||
|
|
||||||
|
@ -5486,7 +5506,7 @@ This list contains 1094 plugins.
|
||||||
pytest ngs fixtures
|
pytest ngs fixtures
|
||||||
|
|
||||||
:pypi:`pytest-nhsd-apim`
|
:pypi:`pytest-nhsd-apim`
|
||||||
*last release*: Jul 21, 2022,
|
*last release*: Aug 10, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (==6.2.5)
|
*requires*: pytest (==6.2.5)
|
||||||
|
|
||||||
|
@ -6249,7 +6269,7 @@ This list contains 1094 plugins.
|
||||||
pytest plugin to check source code with pylint
|
pytest plugin to check source code with pylint
|
||||||
|
|
||||||
:pypi:`pytest-pyodide`
|
:pypi:`pytest-pyodide`
|
||||||
*last release*: Aug 04, 2022,
|
*last release*: Aug 10, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest
|
*requires*: pytest
|
||||||
|
|
||||||
|
@ -6753,7 +6773,7 @@ This list contains 1094 plugins.
|
||||||
pytest plugin to re-run tests to eliminate flaky failures
|
pytest plugin to re-run tests to eliminate flaky failures
|
||||||
|
|
||||||
:pypi:`pytest-resilient-circuits`
|
:pypi:`pytest-resilient-circuits`
|
||||||
*last release*: Jul 07, 2022,
|
*last release*: Aug 12, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -6787,6 +6807,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
py.test integration for responses
|
py.test integration for responses
|
||||||
|
|
||||||
|
:pypi:`pytest-rest-api`
|
||||||
|
*last release*: Aug 08, 2022,
|
||||||
|
*status*: N/A,
|
||||||
|
*requires*: pytest (>=7.1.2,<8.0.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:pypi:`pytest-restrict`
|
:pypi:`pytest-restrict`
|
||||||
*last release*: May 11, 2022,
|
*last release*: May 11, 2022,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
|
@ -6802,7 +6829,7 @@ This list contains 1094 plugins.
|
||||||
A RethinkDB plugin for pytest.
|
A RethinkDB plugin for pytest.
|
||||||
|
|
||||||
:pypi:`pytest-retry`
|
:pypi:`pytest-retry`
|
||||||
*last release*: Aug 05, 2022,
|
*last release*: Aug 11, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (>=7.0.0)
|
*requires*: pytest (>=7.0.0)
|
||||||
|
|
||||||
|
@ -6836,6 +6863,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
pytest plugin to test webapplications using the Ringo webframework
|
pytest plugin to test webapplications using the Ringo webframework
|
||||||
|
|
||||||
|
:pypi:`pytest-rmsis`
|
||||||
|
*last release*: Aug 10, 2022,
|
||||||
|
*status*: N/A,
|
||||||
|
*requires*: pytest (>=5.3.5)
|
||||||
|
|
||||||
|
Sycronise pytest results to Jira RMsis
|
||||||
|
|
||||||
:pypi:`pytest-rng`
|
:pypi:`pytest-rng`
|
||||||
*last release*: Aug 08, 2019,
|
*last release*: Aug 08, 2019,
|
||||||
*status*: 5 - Production/Stable,
|
*status*: 5 - Production/Stable,
|
||||||
|
@ -7487,6 +7521,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
pytest plugin with sqlalchemy related fixtures
|
pytest plugin with sqlalchemy related fixtures
|
||||||
|
|
||||||
|
:pypi:`pytest-sqlalchemy-mock`
|
||||||
|
*last release*: Aug 10, 2022,
|
||||||
|
*status*: 3 - Alpha,
|
||||||
|
*requires*: pytest (>=2.0)
|
||||||
|
|
||||||
|
pytest sqlalchemy plugin for mock
|
||||||
|
|
||||||
:pypi:`pytest-sql-bigquery`
|
:pypi:`pytest-sql-bigquery`
|
||||||
*last release*: Dec 19, 2019,
|
*last release*: Dec 19, 2019,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
|
@ -7908,9 +7949,9 @@ This list contains 1094 plugins.
|
||||||
Pytest plugin for sending report to testrail system.
|
Pytest plugin for sending report to testrail system.
|
||||||
|
|
||||||
:pypi:`pytest-testrail-ns`
|
:pypi:`pytest-testrail-ns`
|
||||||
*last release*: Jul 26, 2022,
|
*last release*: Aug 12, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: pytest (>=3.6)
|
*requires*: N/A
|
||||||
|
|
||||||
pytest plugin for creating TestRail runs and adding results
|
pytest plugin for creating TestRail runs and adding results
|
||||||
|
|
||||||
|
@ -8090,7 +8131,7 @@ This list contains 1094 plugins.
|
||||||
Utilities to create temporary file hierarchies in pytest.
|
Utilities to create temporary file hierarchies in pytest.
|
||||||
|
|
||||||
:pypi:`pytest-tmreport`
|
:pypi:`pytest-tmreport`
|
||||||
*last release*: Nov 17, 2021,
|
*last release*: Aug 12, 2022,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
*requires*: N/A
|
*requires*: N/A
|
||||||
|
|
||||||
|
@ -8244,11 +8285,11 @@ This list contains 1094 plugins.
|
||||||
Test Class Base
|
Test Class Base
|
||||||
|
|
||||||
:pypi:`pytest-tui`
|
:pypi:`pytest-tui`
|
||||||
*last release*: Aug 03, 2022,
|
*last release*: Aug 13, 2022,
|
||||||
*status*: 4 - Beta,
|
*status*: 4 - Beta,
|
||||||
*requires*: pytest (>=6.2.5)
|
*requires*: pytest (>=6.2.5)
|
||||||
|
|
||||||
Text User Interface (TUI) for Pytest, automatically launched after your test run is finished
|
Text User Interface (TUI) for Pytest, with optional auto-launch and HTML export
|
||||||
|
|
||||||
:pypi:`pytest-twilio-conversations-client-mock`
|
:pypi:`pytest-twilio-conversations-client-mock`
|
||||||
*last release*: Aug 02, 2022,
|
*last release*: Aug 02, 2022,
|
||||||
|
@ -8733,6 +8774,13 @@ This list contains 1094 plugins.
|
||||||
|
|
||||||
PyTest plugin to run tests concurrently, each \`yield\` switch context to other one
|
PyTest plugin to run tests concurrently, each \`yield\` switch context to other one
|
||||||
|
|
||||||
|
:pypi:`pytest-yls`
|
||||||
|
*last release*: Aug 08, 2022,
|
||||||
|
*status*: N/A,
|
||||||
|
*requires*: pytest (>=7.1.2,<8.0.0)
|
||||||
|
|
||||||
|
Pytest plugin to test the YLS as a whole.
|
||||||
|
|
||||||
:pypi:`pytest-yuk`
|
:pypi:`pytest-yuk`
|
||||||
*last release*: Mar 26, 2021,
|
*last release*: Mar 26, 2021,
|
||||||
*status*: N/A,
|
*status*: N/A,
|
||||||
|
|
|
@ -102,7 +102,7 @@ pytest.deprecated_call
|
||||||
|
|
||||||
**Tutorial**: :ref:`ensuring_function_triggers`
|
**Tutorial**: :ref:`ensuring_function_triggers`
|
||||||
|
|
||||||
.. autofunction:: pytest.deprecated_call()
|
.. autofunction:: pytest.deprecated_call([match])
|
||||||
:with:
|
:with:
|
||||||
|
|
||||||
pytest.register_assert_rewrite
|
pytest.register_assert_rewrite
|
||||||
|
@ -529,6 +529,7 @@ New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`.
|
||||||
|
|
||||||
.. autoclass:: pytest.Testdir()
|
.. autoclass:: pytest.Testdir()
|
||||||
:members:
|
:members:
|
||||||
|
:noindex: TimeoutExpired
|
||||||
|
|
||||||
|
|
||||||
.. fixture:: recwarn
|
.. fixture:: recwarn
|
||||||
|
|
|
@ -2,9 +2,6 @@ pallets-sphinx-themes
|
||||||
pluggy>=1.0
|
pluggy>=1.0
|
||||||
pygments-pytest>=2.2.0
|
pygments-pytest>=2.2.0
|
||||||
sphinx-removed-in>=0.2.0
|
sphinx-removed-in>=0.2.0
|
||||||
sphinx>=3.1,<4
|
sphinx>=5,<6
|
||||||
sphinxcontrib-trio
|
sphinxcontrib-trio
|
||||||
sphinxcontrib-svg2pdfconverter
|
sphinxcontrib-svg2pdfconverter
|
||||||
|
|
||||||
# XXX: sphinx<4 is broken with latest jinja2
|
|
||||||
jinja2<3.1
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ requires = [
|
||||||
# sync with setup.py until we discard non-pep-517/518
|
# sync with setup.py until we discard non-pep-517/518
|
||||||
"setuptools>=45.0",
|
"setuptools>=45.0",
|
||||||
"setuptools-scm[toml]>=6.2.3",
|
"setuptools-scm[toml]>=6.2.3",
|
||||||
"wheel",
|
|
||||||
]
|
]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ install_requires =
|
||||||
pluggy>=0.12,<2.0
|
pluggy>=0.12,<2.0
|
||||||
py>=1.8.2
|
py>=1.8.2
|
||||||
colorama;sys_platform=="win32"
|
colorama;sys_platform=="win32"
|
||||||
|
exceptiongroup>=1.0.0rc8;python_version<"3.11"
|
||||||
importlib-metadata>=0.12;python_version<"3.8"
|
importlib-metadata>=0.12;python_version<"3.8"
|
||||||
tomli>=1.0.0;python_version<"3.11"
|
tomli>=1.0.0;python_version<"3.11"
|
||||||
python_requires = >=3.7
|
python_requires = >=3.7
|
||||||
|
|
|
@ -56,6 +56,9 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
||||||
|
|
||||||
|
if sys.version_info[:2] < (3, 11):
|
||||||
|
from exceptiongroup import BaseExceptionGroup
|
||||||
|
|
||||||
|
|
||||||
class Code:
|
class Code:
|
||||||
"""Wrapper around Python code objects."""
|
"""Wrapper around Python code objects."""
|
||||||
|
@ -924,6 +927,20 @@ class FormattedExcinfo:
|
||||||
while e is not None and id(e) not in seen:
|
while e is not None and id(e) not in seen:
|
||||||
seen.add(id(e))
|
seen.add(id(e))
|
||||||
if excinfo_:
|
if excinfo_:
|
||||||
|
# Fall back to native traceback as a temporary workaround until
|
||||||
|
# full support for exception groups added to ExceptionInfo.
|
||||||
|
# See https://github.com/pytest-dev/pytest/issues/9159
|
||||||
|
if isinstance(e, BaseExceptionGroup):
|
||||||
|
reprtraceback: Union[
|
||||||
|
ReprTracebackNative, ReprTraceback
|
||||||
|
] = ReprTracebackNative(
|
||||||
|
traceback.format_exception(
|
||||||
|
type(excinfo_.value),
|
||||||
|
excinfo_.value,
|
||||||
|
excinfo_.traceback[0]._rawentry,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
reprtraceback = self.repr_traceback(excinfo_)
|
reprtraceback = self.repr_traceback(excinfo_)
|
||||||
reprcrash: Optional[ReprFileLocation] = (
|
reprcrash: Optional[ReprFileLocation] = (
|
||||||
excinfo_._getreprcrash() if self.style != "value" else None
|
excinfo_._getreprcrash() if self.style != "value" else None
|
||||||
|
|
|
@ -53,7 +53,7 @@ def register_assert_rewrite(*names: str) -> None:
|
||||||
actually imported, usually in your __init__.py if you are a plugin
|
actually imported, usually in your __init__.py if you are a plugin
|
||||||
using a package.
|
using a package.
|
||||||
|
|
||||||
:raises TypeError: If the given module names are not strings.
|
:param names: The module names to register.
|
||||||
"""
|
"""
|
||||||
for name in names:
|
for name in names:
|
||||||
if not isinstance(name, str):
|
if not isinstance(name, str):
|
||||||
|
|
|
@ -20,6 +20,16 @@ from typing import Union
|
||||||
import attr
|
import attr
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
# Workaround for https://github.com/sphinx-doc/sphinx/issues/10351.
|
||||||
|
# If `overload` is imported from `compat` instead of from `typing`,
|
||||||
|
# Sphinx doesn't recognize it as `overload` and the API docs for
|
||||||
|
# overloaded functions look good again. But type checkers handle
|
||||||
|
# it fine.
|
||||||
|
# fmt: on
|
||||||
|
if True:
|
||||||
|
from typing import overload as overload
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing_extensions import Final
|
from typing_extensions import Final
|
||||||
|
|
||||||
|
@ -345,7 +355,6 @@ else:
|
||||||
if sys.version_info >= (3, 8):
|
if sys.version_info >= (3, 8):
|
||||||
from functools import cached_property as cached_property
|
from functools import cached_property as cached_property
|
||||||
else:
|
else:
|
||||||
from typing import overload
|
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
class cached_property(Generic[_S, _T]):
|
class cached_property(Generic[_S, _T]):
|
||||||
|
|
|
@ -66,14 +66,15 @@ class Parser:
|
||||||
) -> "OptionGroup":
|
) -> "OptionGroup":
|
||||||
"""Get (or create) a named option Group.
|
"""Get (or create) a named option Group.
|
||||||
|
|
||||||
:name: Name of the option group.
|
:param name: Name of the option group.
|
||||||
:description: Long description for --help output.
|
:param description: Long description for --help output.
|
||||||
:after: Name of another group, used for ordering --help output.
|
:param after: Name of another group, used for ordering --help output.
|
||||||
|
:returns: The option group.
|
||||||
|
|
||||||
The returned group object has an ``addoption`` method with the same
|
The returned group object has an ``addoption`` method with the same
|
||||||
signature as :func:`parser.addoption <pytest.Parser.addoption>` but
|
signature as :func:`parser.addoption <pytest.Parser.addoption>` but
|
||||||
will be shown in the respective group in the output of
|
will be shown in the respective group in the output of
|
||||||
``pytest. --help``.
|
``pytest --help``.
|
||||||
"""
|
"""
|
||||||
for group in self._groups:
|
for group in self._groups:
|
||||||
if group.name == name:
|
if group.name == name:
|
||||||
|
@ -89,10 +90,11 @@ class Parser:
|
||||||
def addoption(self, *opts: str, **attrs: Any) -> None:
|
def addoption(self, *opts: str, **attrs: Any) -> None:
|
||||||
"""Register a command line option.
|
"""Register a command line option.
|
||||||
|
|
||||||
:opts: Option names, can be short or long options.
|
:param opts:
|
||||||
:attrs: Same attributes which the ``add_argument()`` function of the
|
Option names, can be short or long options.
|
||||||
`argparse library <https://docs.python.org/library/argparse.html>`_
|
:param attrs:
|
||||||
accepts.
|
Same attributes as the argparse library's :py:func:`add_argument()
|
||||||
|
<argparse.ArgumentParser.add_argument>` function accepts.
|
||||||
|
|
||||||
After command line parsing, options are available on the pytest config
|
After command line parsing, options are available on the pytest config
|
||||||
object via ``config.option.NAME`` where ``NAME`` is usually set
|
object via ``config.option.NAME`` where ``NAME`` is usually set
|
||||||
|
@ -148,7 +150,10 @@ class Parser:
|
||||||
args: Sequence[Union[str, "os.PathLike[str]"]],
|
args: Sequence[Union[str, "os.PathLike[str]"]],
|
||||||
namespace: Optional[argparse.Namespace] = None,
|
namespace: Optional[argparse.Namespace] = None,
|
||||||
) -> argparse.Namespace:
|
) -> argparse.Namespace:
|
||||||
"""Parse and return a namespace object with known arguments at this point."""
|
"""Parse the known arguments at this point.
|
||||||
|
|
||||||
|
:returns: An argparse namespace object.
|
||||||
|
"""
|
||||||
return self.parse_known_and_unknown_args(args, namespace=namespace)[0]
|
return self.parse_known_and_unknown_args(args, namespace=namespace)[0]
|
||||||
|
|
||||||
def parse_known_and_unknown_args(
|
def parse_known_and_unknown_args(
|
||||||
|
@ -156,8 +161,13 @@ class Parser:
|
||||||
args: Sequence[Union[str, "os.PathLike[str]"]],
|
args: Sequence[Union[str, "os.PathLike[str]"]],
|
||||||
namespace: Optional[argparse.Namespace] = None,
|
namespace: Optional[argparse.Namespace] = None,
|
||||||
) -> Tuple[argparse.Namespace, List[str]]:
|
) -> Tuple[argparse.Namespace, List[str]]:
|
||||||
"""Parse and return a namespace object with known arguments, and
|
"""Parse the known arguments at this point, and also return the
|
||||||
the remaining arguments unknown at this point."""
|
remaining unknown arguments.
|
||||||
|
|
||||||
|
:returns:
|
||||||
|
A tuple containing an argparse namespace object for the known
|
||||||
|
arguments, and a list of the unknown arguments.
|
||||||
|
"""
|
||||||
optparser = self._getparser()
|
optparser = self._getparser()
|
||||||
strargs = [os.fspath(x) for x in args]
|
strargs = [os.fspath(x) for x in args]
|
||||||
return optparser.parse_known_args(strargs, namespace=namespace)
|
return optparser.parse_known_args(strargs, namespace=namespace)
|
||||||
|
@ -173,9 +183,9 @@ class Parser:
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register an ini-file option.
|
"""Register an ini-file option.
|
||||||
|
|
||||||
:name:
|
:param name:
|
||||||
Name of the ini-variable.
|
Name of the ini-variable.
|
||||||
:type:
|
:param type:
|
||||||
Type of the variable. Can be:
|
Type of the variable. Can be:
|
||||||
|
|
||||||
* ``string``: a string
|
* ``string``: a string
|
||||||
|
@ -189,7 +199,7 @@ class Parser:
|
||||||
The ``paths`` variable type.
|
The ``paths`` variable type.
|
||||||
|
|
||||||
Defaults to ``string`` if ``None`` or not passed.
|
Defaults to ``string`` if ``None`` or not passed.
|
||||||
:default:
|
:param default:
|
||||||
Default value if no ini-file option exists but is queried.
|
Default value if no ini-file option exists but is queried.
|
||||||
|
|
||||||
The value of ini-variables can be retrieved via a call to
|
The value of ini-variables can be retrieved via a call to
|
||||||
|
@ -354,24 +364,30 @@ class OptionGroup:
|
||||||
self.options: List[Argument] = []
|
self.options: List[Argument] = []
|
||||||
self.parser = parser
|
self.parser = parser
|
||||||
|
|
||||||
def addoption(self, *optnames: str, **attrs: Any) -> None:
|
def addoption(self, *opts: str, **attrs: Any) -> None:
|
||||||
"""Add an option to this group.
|
"""Add an option to this group.
|
||||||
|
|
||||||
If a shortened version of a long option is specified, it will
|
If a shortened version of a long option is specified, it will
|
||||||
be suppressed in the help. ``addoption('--twowords', '--two-words')``
|
be suppressed in the help. ``addoption('--twowords', '--two-words')``
|
||||||
results in help showing ``--two-words`` only, but ``--twowords`` gets
|
results in help showing ``--two-words`` only, but ``--twowords`` gets
|
||||||
accepted **and** the automatic destination is in ``args.twowords``.
|
accepted **and** the automatic destination is in ``args.twowords``.
|
||||||
|
|
||||||
|
:param opts:
|
||||||
|
Option names, can be short or long options.
|
||||||
|
:param attrs:
|
||||||
|
Same attributes as the argparse library's :py:func:`add_argument()
|
||||||
|
<argparse.ArgumentParser.add_argument>` function accepts.
|
||||||
"""
|
"""
|
||||||
conflict = set(optnames).intersection(
|
conflict = set(opts).intersection(
|
||||||
name for opt in self.options for name in opt.names()
|
name for opt in self.options for name in opt.names()
|
||||||
)
|
)
|
||||||
if conflict:
|
if conflict:
|
||||||
raise ValueError("option names %s already added" % conflict)
|
raise ValueError("option names %s already added" % conflict)
|
||||||
option = Argument(*optnames, **attrs)
|
option = Argument(*opts, **attrs)
|
||||||
self._addoption_instance(option, shortupper=False)
|
self._addoption_instance(option, shortupper=False)
|
||||||
|
|
||||||
def _addoption(self, *optnames: str, **attrs: Any) -> None:
|
def _addoption(self, *opts: str, **attrs: Any) -> None:
|
||||||
option = Argument(*optnames, **attrs)
|
option = Argument(*opts, **attrs)
|
||||||
self._addoption_instance(option, shortupper=True)
|
self._addoption_instance(option, shortupper=True)
|
||||||
|
|
||||||
def _addoption_instance(self, option: "Argument", shortupper: bool = False) -> None:
|
def _addoption_instance(self, option: "Argument", shortupper: bool = False) -> None:
|
||||||
|
|
|
@ -20,7 +20,6 @@ from typing import List
|
||||||
from typing import MutableMapping
|
from typing import MutableMapping
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import overload
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
@ -48,6 +47,7 @@ from _pytest.compat import getimfunc
|
||||||
from _pytest.compat import getlocation
|
from _pytest.compat import getlocation
|
||||||
from _pytest.compat import is_generator
|
from _pytest.compat import is_generator
|
||||||
from _pytest.compat import NOTSET
|
from _pytest.compat import NOTSET
|
||||||
|
from _pytest.compat import overload
|
||||||
from _pytest.compat import safe_getattr
|
from _pytest.compat import safe_getattr
|
||||||
from _pytest.config import _PluggyPlugin
|
from _pytest.config import _PluggyPlugin
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
|
@ -513,8 +513,8 @@ class FixtureRequest:
|
||||||
return self._pyfuncitem.session # type: ignore[no-any-return]
|
return self._pyfuncitem.session # type: ignore[no-any-return]
|
||||||
|
|
||||||
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
||||||
"""Add finalizer/teardown function to be called after the last test
|
"""Add finalizer/teardown function to be called without arguments after
|
||||||
within the requesting test context finished execution."""
|
the last test within the requesting test context finished execution."""
|
||||||
# XXX usually this method is shadowed by fixturedef specific ones.
|
# XXX usually this method is shadowed by fixturedef specific ones.
|
||||||
self._addfinalizer(finalizer, scope=self.scope)
|
self._addfinalizer(finalizer, scope=self.scope)
|
||||||
|
|
||||||
|
@ -529,13 +529,16 @@ class FixtureRequest:
|
||||||
on all function invocations.
|
on all function invocations.
|
||||||
|
|
||||||
:param marker:
|
:param marker:
|
||||||
A :class:`pytest.MarkDecorator` object created by a call
|
An object created by a call to ``pytest.mark.NAME(...)``.
|
||||||
to ``pytest.mark.NAME(...)``.
|
|
||||||
"""
|
"""
|
||||||
self.node.add_marker(marker)
|
self.node.add_marker(marker)
|
||||||
|
|
||||||
def raiseerror(self, msg: Optional[str]) -> NoReturn:
|
def raiseerror(self, msg: Optional[str]) -> NoReturn:
|
||||||
"""Raise a FixtureLookupError with the given message."""
|
"""Raise a FixtureLookupError exception.
|
||||||
|
|
||||||
|
:param msg:
|
||||||
|
An optional custom error message.
|
||||||
|
"""
|
||||||
raise self._fixturemanager.FixtureLookupError(None, self, msg)
|
raise self._fixturemanager.FixtureLookupError(None, self, msg)
|
||||||
|
|
||||||
def _fillfixtures(self) -> None:
|
def _fillfixtures(self) -> None:
|
||||||
|
@ -557,6 +560,8 @@ class FixtureRequest:
|
||||||
phase, but during the test teardown phase a fixture's value may not
|
phase, but during the test teardown phase a fixture's value may not
|
||||||
be available.
|
be available.
|
||||||
|
|
||||||
|
:param argname:
|
||||||
|
The fixture name.
|
||||||
:raises pytest.FixtureLookupError:
|
:raises pytest.FixtureLookupError:
|
||||||
If the given fixture could not be found.
|
If the given fixture could not be found.
|
||||||
"""
|
"""
|
||||||
|
@ -768,8 +773,8 @@ class SubRequest(FixtureRequest):
|
||||||
return f"<SubRequest {self.fixturename!r} for {self._pyfuncitem!r}>"
|
return f"<SubRequest {self.fixturename!r} for {self._pyfuncitem!r}>"
|
||||||
|
|
||||||
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
||||||
"""Add finalizer/teardown function to be called after the last test
|
"""Add finalizer/teardown function to be called without arguments after
|
||||||
within the requesting test context finished execution."""
|
the last test within the requesting test context finished execution."""
|
||||||
self._fixturedef.addfinalizer(finalizer)
|
self._fixturedef.addfinalizer(finalizer)
|
||||||
|
|
||||||
def _schedule_finalizers(
|
def _schedule_finalizers(
|
||||||
|
@ -1226,7 +1231,7 @@ def fixture(
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def fixture(
|
def fixture( # noqa: F811
|
||||||
fixture_function: None = ...,
|
fixture_function: None = ...,
|
||||||
*,
|
*,
|
||||||
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ...,
|
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ...,
|
||||||
|
@ -1240,7 +1245,7 @@ def fixture(
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def fixture(
|
def fixture( # noqa: F811
|
||||||
fixture_function: Optional[FixtureFunction] = None,
|
fixture_function: Optional[FixtureFunction] = None,
|
||||||
*,
|
*,
|
||||||
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function",
|
scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = "function",
|
||||||
|
|
|
@ -143,7 +143,7 @@ def pytest_configure(config: "Config") -> None:
|
||||||
def pytest_cmdline_parse(
|
def pytest_cmdline_parse(
|
||||||
pluginmanager: "PytestPluginManager", args: List[str]
|
pluginmanager: "PytestPluginManager", args: List[str]
|
||||||
) -> Optional["Config"]:
|
) -> Optional["Config"]:
|
||||||
"""Return an initialized config object, parsing the specified args.
|
"""Return an initialized :class:`~pytest.Config`, parsing the specified args.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
|
@ -152,8 +152,9 @@ def pytest_cmdline_parse(
|
||||||
``plugins`` arg when using `pytest.main`_ to perform an in-process
|
``plugins`` arg when using `pytest.main`_ to perform an in-process
|
||||||
test run.
|
test run.
|
||||||
|
|
||||||
:param pytest.PytestPluginManager pluginmanager: The pytest plugin manager.
|
:param pluginmanager: The pytest plugin manager.
|
||||||
:param List[str] args: List of arguments passed on the command line.
|
:param args: List of arguments passed on the command line.
|
||||||
|
:returns: A pytest config object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,8 +168,8 @@ def pytest_cmdline_preparse(config: "Config", args: List[str]) -> None:
|
||||||
.. note::
|
.. note::
|
||||||
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param List[str] args: Arguments passed on the command line.
|
:param args: Arguments passed on the command line.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,7 +180,8 @@ def pytest_cmdline_main(config: "Config") -> Optional[Union["ExitCode", int]]:
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
|
:returns: The exit code.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,9 +194,9 @@ def pytest_load_initial_conftests(
|
||||||
.. note::
|
.. note::
|
||||||
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
||||||
|
|
||||||
:param pytest.Config early_config: The pytest config object.
|
:param early_config: The pytest config object.
|
||||||
:param List[str] args: Arguments passed on the command line.
|
:param args: Arguments passed on the command line.
|
||||||
:param pytest.Parser parser: To add command line options.
|
:param parser: To add command line options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +238,7 @@ def pytest_collection(session: "Session") -> Optional[object]:
|
||||||
for example the terminal plugin uses it to start displaying the collection
|
for example the terminal plugin uses it to start displaying the collection
|
||||||
counter (and returns `None`).
|
counter (and returns `None`).
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,16 +248,16 @@ def pytest_collection_modifyitems(
|
||||||
"""Called after collection has been performed. May filter or re-order
|
"""Called after collection has been performed. May filter or re-order
|
||||||
the items in-place.
|
the items in-place.
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param List[pytest.Item] items: List of item objects.
|
:param items: List of item objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_collection_finish(session: "Session") -> None:
|
def pytest_collection_finish(session: "Session") -> None:
|
||||||
"""Called after collection has been performed and modified.
|
"""Called after collection has been performed and modified.
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -270,9 +272,9 @@ def pytest_ignore_collect(
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
:param pathlib.Path collection_path : The path to analyze.
|
:param collection_path: The path to analyze.
|
||||||
:param LEGACY_PATH path: The path to analyze (deprecated).
|
:param path: The path to analyze (deprecated).
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
|
|
||||||
.. versionchanged:: 7.0.0
|
.. versionchanged:: 7.0.0
|
||||||
The ``collection_path`` parameter was added as a :class:`pathlib.Path`
|
The ``collection_path`` parameter was added as a :class:`pathlib.Path`
|
||||||
|
@ -284,12 +286,12 @@ def pytest_ignore_collect(
|
||||||
def pytest_collect_file(
|
def pytest_collect_file(
|
||||||
file_path: Path, path: "LEGACY_PATH", parent: "Collector"
|
file_path: Path, path: "LEGACY_PATH", parent: "Collector"
|
||||||
) -> "Optional[Collector]":
|
) -> "Optional[Collector]":
|
||||||
"""Create a Collector for the given path, or None if not relevant.
|
"""Create a :class:`~pytest.Collector` for the given path, or None if not relevant.
|
||||||
|
|
||||||
The new node needs to have the specified ``parent`` as a parent.
|
The new node needs to have the specified ``parent`` as a parent.
|
||||||
|
|
||||||
:param pathlib.Path file_path: The path to analyze.
|
:param file_path: The path to analyze.
|
||||||
:param LEGACY_PATH path: The path to collect (deprecated).
|
:param path: The path to collect (deprecated).
|
||||||
|
|
||||||
.. versionchanged:: 7.0.0
|
.. versionchanged:: 7.0.0
|
||||||
The ``file_path`` parameter was added as a :class:`pathlib.Path`
|
The ``file_path`` parameter was added as a :class:`pathlib.Path`
|
||||||
|
@ -302,21 +304,36 @@ def pytest_collect_file(
|
||||||
|
|
||||||
|
|
||||||
def pytest_collectstart(collector: "Collector") -> None:
|
def pytest_collectstart(collector: "Collector") -> None:
|
||||||
"""Collector starts collecting."""
|
"""Collector starts collecting.
|
||||||
|
|
||||||
|
:param collector:
|
||||||
|
The collector.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_itemcollected(item: "Item") -> None:
|
def pytest_itemcollected(item: "Item") -> None:
|
||||||
"""We just collected a test item."""
|
"""We just collected a test item.
|
||||||
|
|
||||||
|
:param item:
|
||||||
|
The item.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_collectreport(report: "CollectReport") -> None:
|
def pytest_collectreport(report: "CollectReport") -> None:
|
||||||
"""Collector finished collecting."""
|
"""Collector finished collecting.
|
||||||
|
|
||||||
|
:param report:
|
||||||
|
The collect report.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_deselected(items: Sequence["Item"]) -> None:
|
def pytest_deselected(items: Sequence["Item"]) -> None:
|
||||||
"""Called for deselected test items, e.g. by keyword.
|
"""Called for deselected test items, e.g. by keyword.
|
||||||
|
|
||||||
May be called multiple times.
|
May be called multiple times.
|
||||||
|
|
||||||
|
:param items:
|
||||||
|
The items.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,6 +343,9 @@ def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectRepor
|
||||||
a :class:`~pytest.CollectReport`.
|
a :class:`~pytest.CollectReport`.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
|
:param collector:
|
||||||
|
The collector.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,16 +358,16 @@ def pytest_make_collect_report(collector: "Collector") -> "Optional[CollectRepor
|
||||||
def pytest_pycollect_makemodule(
|
def pytest_pycollect_makemodule(
|
||||||
module_path: Path, path: "LEGACY_PATH", parent
|
module_path: Path, path: "LEGACY_PATH", parent
|
||||||
) -> Optional["Module"]:
|
) -> Optional["Module"]:
|
||||||
"""Return a Module collector or None for the given path.
|
"""Return a :class:`pytest.Module` collector or None for the given path.
|
||||||
|
|
||||||
This hook will be called for each matching test module path.
|
This hook will be called for each matching test module path.
|
||||||
The pytest_collect_file hook needs to be used if you want to
|
The :hook:`pytest_collect_file` hook needs to be used if you want to
|
||||||
create test modules for files that do not match as a test module.
|
create test modules for files that do not match as a test module.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
:param pathlib.Path module_path: The path of the module to collect.
|
:param module_path: The path of the module to collect.
|
||||||
:param LEGACY_PATH path: The path of the module to collect (deprecated).
|
:param path: The path of the module to collect (deprecated).
|
||||||
|
|
||||||
.. versionchanged:: 7.0.0
|
.. versionchanged:: 7.0.0
|
||||||
The ``module_path`` parameter was added as a :class:`pathlib.Path`
|
The ``module_path`` parameter was added as a :class:`pathlib.Path`
|
||||||
|
@ -364,6 +384,15 @@ def pytest_pycollect_makeitem(
|
||||||
"""Return a custom item/collector for a Python object in a module, or None.
|
"""Return a custom item/collector for a Python object in a module, or None.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
|
:param collector:
|
||||||
|
The module/class collector.
|
||||||
|
:param name:
|
||||||
|
The name of the object in the module/class.
|
||||||
|
:param obj:
|
||||||
|
The object.
|
||||||
|
:returns:
|
||||||
|
The created items/collectors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -372,11 +401,18 @@ def pytest_pyfunc_call(pyfuncitem: "Function") -> Optional[object]:
|
||||||
"""Call underlying test function.
|
"""Call underlying test function.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
|
:param pyfuncitem:
|
||||||
|
The function item.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc: "Metafunc") -> None:
|
def pytest_generate_tests(metafunc: "Metafunc") -> None:
|
||||||
"""Generate (multiple) parametrized calls to a test function."""
|
"""Generate (multiple) parametrized calls to a test function.
|
||||||
|
|
||||||
|
:param metafunc:
|
||||||
|
The :class:`~pytest.Metafunc` helper for the test function.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@hookspec(firstresult=True)
|
@hookspec(firstresult=True)
|
||||||
|
@ -391,7 +427,7 @@ def pytest_make_parametrize_id(
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param val: The parametrized value.
|
:param val: The parametrized value.
|
||||||
:param str argname: The automatic parameter name produced by pytest.
|
:param str argname: The automatic parameter name produced by pytest.
|
||||||
"""
|
"""
|
||||||
|
@ -416,7 +452,7 @@ def pytest_runtestloop(session: "Session") -> Optional[object]:
|
||||||
If at any point ``session.shouldfail`` or ``session.shouldstop`` are set, the
|
If at any point ``session.shouldfail`` or ``session.shouldstop`` are set, the
|
||||||
loop is terminated after the runtest protocol for the current item is finished.
|
loop is terminated after the runtest protocol for the current item is finished.
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
The return value is not used, but only stops further processing.
|
The return value is not used, but only stops further processing.
|
||||||
|
@ -468,7 +504,7 @@ def pytest_runtest_logstart(
|
||||||
|
|
||||||
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
||||||
|
|
||||||
:param str nodeid: Full node ID of the item.
|
:param nodeid: Full node ID of the item.
|
||||||
:param location: A tuple of ``(filename, lineno, testname)``.
|
:param location: A tuple of ``(filename, lineno, testname)``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -480,7 +516,7 @@ def pytest_runtest_logfinish(
|
||||||
|
|
||||||
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
||||||
|
|
||||||
:param str nodeid: Full node ID of the item.
|
:param nodeid: Full node ID of the item.
|
||||||
:param location: A tuple of ``(filename, lineno, testname)``.
|
:param location: A tuple of ``(filename, lineno, testname)``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -492,6 +528,9 @@ def pytest_runtest_setup(item: "Item") -> None:
|
||||||
parents (which haven't been setup yet). This includes obtaining the
|
parents (which haven't been setup yet). This includes obtaining the
|
||||||
values of fixtures required by the item (which haven't been obtained
|
values of fixtures required by the item (which haven't been obtained
|
||||||
yet).
|
yet).
|
||||||
|
|
||||||
|
:param item:
|
||||||
|
The item.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -499,6 +538,9 @@ def pytest_runtest_call(item: "Item") -> None:
|
||||||
"""Called to run the test for test item (the call phase).
|
"""Called to run the test for test item (the call phase).
|
||||||
|
|
||||||
The default implementation calls ``item.runtest()``.
|
The default implementation calls ``item.runtest()``.
|
||||||
|
|
||||||
|
:param item:
|
||||||
|
The item.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -510,6 +552,8 @@ def pytest_runtest_teardown(item: "Item", nextitem: Optional["Item"]) -> None:
|
||||||
includes running the teardown phase of fixtures required by the item (if
|
includes running the teardown phase of fixtures required by the item (if
|
||||||
they go out of scope).
|
they go out of scope).
|
||||||
|
|
||||||
|
:param item:
|
||||||
|
The item.
|
||||||
:param nextitem:
|
:param nextitem:
|
||||||
The scheduled-to-be-next test item (None if no further test item is
|
The scheduled-to-be-next test item (None if no further test item is
|
||||||
scheduled). This argument is used to perform exact teardowns, i.e.
|
scheduled). This argument is used to perform exact teardowns, i.e.
|
||||||
|
@ -527,6 +571,7 @@ def pytest_runtest_makereport(
|
||||||
|
|
||||||
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
See :hook:`pytest_runtest_protocol` for a description of the runtest protocol.
|
||||||
|
|
||||||
|
:param item: The item.
|
||||||
:param call: The :class:`~pytest.CallInfo` for the phase.
|
:param call: The :class:`~pytest.CallInfo` for the phase.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
@ -547,7 +592,11 @@ def pytest_report_to_serializable(
|
||||||
report: Union["CollectReport", "TestReport"],
|
report: Union["CollectReport", "TestReport"],
|
||||||
) -> Optional[Dict[str, Any]]:
|
) -> Optional[Dict[str, Any]]:
|
||||||
"""Serialize the given report object into a data structure suitable for
|
"""Serialize the given report object into a data structure suitable for
|
||||||
sending over the wire, e.g. converted to JSON."""
|
sending over the wire, e.g. converted to JSON.
|
||||||
|
|
||||||
|
:param config: The pytest config object.
|
||||||
|
:param report: The report.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
@hookspec(firstresult=True)
|
@hookspec(firstresult=True)
|
||||||
|
@ -556,7 +605,10 @@ def pytest_report_from_serializable(
|
||||||
data: Dict[str, Any],
|
data: Dict[str, Any],
|
||||||
) -> Optional[Union["CollectReport", "TestReport"]]:
|
) -> Optional[Union["CollectReport", "TestReport"]]:
|
||||||
"""Restore a report object previously serialized with
|
"""Restore a report object previously serialized with
|
||||||
:hook:`pytest_report_to_serializable`."""
|
:hook:`pytest_report_to_serializable`.
|
||||||
|
|
||||||
|
:param config: The pytest config object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
@ -570,7 +622,12 @@ def pytest_fixture_setup(
|
||||||
) -> Optional[object]:
|
) -> Optional[object]:
|
||||||
"""Perform fixture setup execution.
|
"""Perform fixture setup execution.
|
||||||
|
|
||||||
:returns: The return value of the call to the fixture function.
|
:param fixturdef:
|
||||||
|
The fixture definition object.
|
||||||
|
:param request:
|
||||||
|
The fixture request object.
|
||||||
|
:returns:
|
||||||
|
The return value of the call to the fixture function.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
|
|
||||||
|
@ -586,7 +643,13 @@ def pytest_fixture_post_finalizer(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called after fixture teardown, but before the cache is cleared, so
|
"""Called after fixture teardown, but before the cache is cleared, so
|
||||||
the fixture result ``fixturedef.cached_result`` is still available (not
|
the fixture result ``fixturedef.cached_result`` is still available (not
|
||||||
``None``)."""
|
``None``).
|
||||||
|
|
||||||
|
:param fixturdef:
|
||||||
|
The fixture definition object.
|
||||||
|
:param request:
|
||||||
|
The fixture request object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
@ -598,7 +661,7 @@ def pytest_sessionstart(session: "Session") -> None:
|
||||||
"""Called after the ``Session`` object has been created and before performing collection
|
"""Called after the ``Session`` object has been created and before performing collection
|
||||||
and entering the run test loop.
|
and entering the run test loop.
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -608,15 +671,15 @@ def pytest_sessionfinish(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called after whole test run finished, right before returning the exit status to the system.
|
"""Called after whole test run finished, right before returning the exit status to the system.
|
||||||
|
|
||||||
:param pytest.Session session: The pytest session object.
|
:param session: The pytest session object.
|
||||||
:param int exitstatus: The status which pytest will return to the system.
|
:param exitstatus: The status which pytest will return to the system.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config: "Config") -> None:
|
def pytest_unconfigure(config: "Config") -> None:
|
||||||
"""Called before test process is exited.
|
"""Called before test process is exited.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -635,7 +698,10 @@ def pytest_assertrepr_compare(
|
||||||
*in* a string will be escaped. Note that all but the first line will
|
*in* a string will be escaped. Note that all but the first line will
|
||||||
be indented slightly, the intention is for the first line to be a summary.
|
be indented slightly, the intention is for the first line to be a summary.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
|
:param op: The operator, e.g. `"=="`, `"!="`, `"not in"`.
|
||||||
|
:param left: The left operand.
|
||||||
|
:param right: The right operand.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -660,10 +726,10 @@ def pytest_assertion_pass(item: "Item", lineno: int, orig: str, expl: str) -> No
|
||||||
You need to **clean the .pyc** files in your project directory and interpreter libraries
|
You need to **clean the .pyc** files in your project directory and interpreter libraries
|
||||||
when enabling this option, as assertions will require to be re-written.
|
when enabling this option, as assertions will require to be re-written.
|
||||||
|
|
||||||
:param pytest.Item item: pytest item object of current test.
|
:param item: pytest item object of current test.
|
||||||
:param int lineno: Line number of the assert statement.
|
:param lineno: Line number of the assert statement.
|
||||||
:param str orig: String with the original assertion.
|
:param orig: String with the original assertion.
|
||||||
:param str expl: String with the assert explanation.
|
:param expl: String with the assert explanation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -677,9 +743,9 @@ def pytest_report_header(
|
||||||
) -> Union[str, List[str]]:
|
) -> Union[str, List[str]]:
|
||||||
"""Return a string or list of strings to be displayed as header info for terminal reporting.
|
"""Return a string or list of strings to be displayed as header info for terminal reporting.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param Path start_path: The starting dir.
|
:param start_path: The starting dir.
|
||||||
:param LEGACY_PATH startdir: The starting dir (deprecated).
|
:param startdir: The starting dir (deprecated).
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -714,9 +780,9 @@ def pytest_report_collectionfinish(
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param Path start_path: The starting dir.
|
:param start_path: The starting dir.
|
||||||
:param LEGACY_PATH startdir: The starting dir (deprecated).
|
:param startdir: The starting dir (deprecated).
|
||||||
:param items: List of pytest items that are going to be executed; this list should not be modified.
|
:param items: List of pytest items that are going to be executed; this list should not be modified.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -755,6 +821,7 @@ def pytest_report_teststatus(
|
||||||
|
|
||||||
:param report: The report object whose status is to be returned.
|
:param report: The report object whose status is to be returned.
|
||||||
:param config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
|
:returns: The test status.
|
||||||
|
|
||||||
Stops at first non-None result, see :ref:`firstresult`.
|
Stops at first non-None result, see :ref:`firstresult`.
|
||||||
"""
|
"""
|
||||||
|
@ -767,9 +834,9 @@ def pytest_terminal_summary(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Add a section to terminal summary reporting.
|
"""Add a section to terminal summary reporting.
|
||||||
|
|
||||||
:param _pytest.terminal.TerminalReporter terminalreporter: The internal terminal reporter object.
|
:param terminalreporter: The internal terminal reporter object.
|
||||||
:param int exitstatus: The exit status that will be reported back to the OS.
|
:param exitstatus: The exit status that will be reported back to the OS.
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
|
|
||||||
.. versionadded:: 4.2
|
.. versionadded:: 4.2
|
||||||
The ``config`` parameter.
|
The ``config`` parameter.
|
||||||
|
@ -785,21 +852,21 @@ def pytest_warning_recorded(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Process a warning captured by the internal pytest warnings plugin.
|
"""Process a warning captured by the internal pytest warnings plugin.
|
||||||
|
|
||||||
:param warnings.WarningMessage warning_message:
|
:param warning_message:
|
||||||
The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains
|
The captured warning. This is the same object produced by :py:func:`warnings.catch_warnings`, and contains
|
||||||
the same attributes as the parameters of :py:func:`warnings.showwarning`.
|
the same attributes as the parameters of :py:func:`warnings.showwarning`.
|
||||||
|
|
||||||
:param str when:
|
:param when:
|
||||||
Indicates when the warning was captured. Possible values:
|
Indicates when the warning was captured. Possible values:
|
||||||
|
|
||||||
* ``"config"``: during pytest configuration/initialization stage.
|
* ``"config"``: during pytest configuration/initialization stage.
|
||||||
* ``"collect"``: during test collection.
|
* ``"collect"``: during test collection.
|
||||||
* ``"runtest"``: during test execution.
|
* ``"runtest"``: during test execution.
|
||||||
|
|
||||||
:param str nodeid:
|
:param nodeid:
|
||||||
Full id of the item.
|
Full id of the item.
|
||||||
|
|
||||||
:param tuple|None location:
|
:param location:
|
||||||
When available, holds information about the execution context of the captured
|
When available, holds information about the execution context of the captured
|
||||||
warning (filename, linenumber, function). ``function`` evaluates to <module>
|
warning (filename, linenumber, function). ``function`` evaluates to <module>
|
||||||
when the execution context is at the module level.
|
when the execution context is at the module level.
|
||||||
|
@ -824,7 +891,7 @@ def pytest_markeval_namespace(config: "Config") -> Dict[str, Any]:
|
||||||
|
|
||||||
.. versionadded:: 6.2
|
.. versionadded:: 6.2
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:returns: A dictionary of additional globals to add.
|
:returns: A dictionary of additional globals to add.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -842,13 +909,19 @@ def pytest_internalerror(
|
||||||
|
|
||||||
Return True to suppress the fallback handling of printing an
|
Return True to suppress the fallback handling of printing an
|
||||||
INTERNALERROR message directly to sys.stderr.
|
INTERNALERROR message directly to sys.stderr.
|
||||||
|
|
||||||
|
:param excrepr: The exception repr object.
|
||||||
|
:param excinfo: The exception info.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_keyboard_interrupt(
|
def pytest_keyboard_interrupt(
|
||||||
excinfo: "ExceptionInfo[Union[KeyboardInterrupt, Exit]]",
|
excinfo: "ExceptionInfo[Union[KeyboardInterrupt, Exit]]",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Called for keyboard interrupt."""
|
"""Called for keyboard interrupt.
|
||||||
|
|
||||||
|
:param excinfo: The exception info.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_exception_interact(
|
def pytest_exception_interact(
|
||||||
|
@ -867,6 +940,13 @@ def pytest_exception_interact(
|
||||||
|
|
||||||
This hook is not called if the exception that was raised is an internal
|
This hook is not called if the exception that was raised is an internal
|
||||||
exception like ``skip.Exception``.
|
exception like ``skip.Exception``.
|
||||||
|
|
||||||
|
:param node:
|
||||||
|
The item or collector.
|
||||||
|
:param call:
|
||||||
|
The call information. Contains the exception.
|
||||||
|
:param report:
|
||||||
|
The collection or test report.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -876,8 +956,8 @@ def pytest_enter_pdb(config: "Config", pdb: "pdb.Pdb") -> None:
|
||||||
Can be used by plugins to take special action just before the python
|
Can be used by plugins to take special action just before the python
|
||||||
debugger enters interactive mode.
|
debugger enters interactive mode.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param pdb.Pdb pdb: The Pdb instance.
|
:param pdb: The Pdb instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -887,6 +967,6 @@ def pytest_leave_pdb(config: "Config", pdb: "pdb.Pdb") -> None:
|
||||||
Can be used by plugins to take special action just after the python
|
Can be used by plugins to take special action just after the python
|
||||||
debugger leaves interactive mode.
|
debugger leaves interactive mode.
|
||||||
|
|
||||||
:param pytest.Config config: The pytest config object.
|
:param config: The pytest config object.
|
||||||
:param pdb.Pdb pdb: The Pdb instance.
|
:param pdb: The Pdb instance.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -231,7 +231,7 @@ class _NodeReporter:
|
||||||
msg = f'failed on teardown with "{reason}"'
|
msg = f'failed on teardown with "{reason}"'
|
||||||
else:
|
else:
|
||||||
msg = f'failed on setup with "{reason}"'
|
msg = f'failed on setup with "{reason}"'
|
||||||
self._add_simple("error", msg, str(report.longrepr))
|
self._add_simple("error", bin_xml_escape(msg), str(report.longrepr))
|
||||||
|
|
||||||
def append_skipped(self, report: TestReport) -> None:
|
def append_skipped(self, report: TestReport) -> None:
|
||||||
if hasattr(report, "wasxfail"):
|
if hasattr(report, "wasxfail"):
|
||||||
|
@ -354,7 +354,10 @@ def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object]
|
||||||
record_testsuite_property("ARCH", "PPC")
|
record_testsuite_property("ARCH", "PPC")
|
||||||
record_testsuite_property("STORAGE_TYPE", "CEPH")
|
record_testsuite_property("STORAGE_TYPE", "CEPH")
|
||||||
|
|
||||||
``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.
|
:param name:
|
||||||
|
The property name.
|
||||||
|
:param value:
|
||||||
|
The property value. Will be converted to a string.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ from _pytest.terminal import TerminalReporter
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
logging_StreamHandler = logging.StreamHandler[StringIO]
|
logging_StreamHandler = logging.StreamHandler[StringIO]
|
||||||
|
|
||||||
|
from typing_extensions import Literal
|
||||||
else:
|
else:
|
||||||
logging_StreamHandler = logging.StreamHandler
|
logging_StreamHandler = logging.StreamHandler
|
||||||
|
|
||||||
|
@ -382,20 +384,19 @@ class LogCaptureFixture:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def handler(self) -> LogCaptureHandler:
|
def handler(self) -> LogCaptureHandler:
|
||||||
"""Get the logging handler used by the fixture.
|
"""Get the logging handler used by the fixture."""
|
||||||
|
|
||||||
:rtype: LogCaptureHandler
|
|
||||||
"""
|
|
||||||
return self._item.stash[caplog_handler_key]
|
return self._item.stash[caplog_handler_key]
|
||||||
|
|
||||||
def get_records(self, when: str) -> List[logging.LogRecord]:
|
def get_records(
|
||||||
|
self, when: "Literal['setup', 'call', 'teardown']"
|
||||||
|
) -> List[logging.LogRecord]:
|
||||||
"""Get the logging records for one of the possible test phases.
|
"""Get the logging records for one of the possible test phases.
|
||||||
|
|
||||||
:param str when:
|
:param when:
|
||||||
Which test phase to obtain the records from. Valid values are: "setup", "call" and "teardown".
|
Which test phase to obtain the records from.
|
||||||
|
Valid values are: "setup", "call" and "teardown".
|
||||||
|
|
||||||
:returns: The list of captured records at the given stage.
|
:returns: The list of captured records at the given stage.
|
||||||
:rtype: List[logging.LogRecord]
|
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
"""
|
"""
|
||||||
|
@ -452,8 +453,8 @@ class LogCaptureFixture:
|
||||||
The levels of the loggers changed by this function will be
|
The levels of the loggers changed by this function will be
|
||||||
restored to their initial values at the end of the test.
|
restored to their initial values at the end of the test.
|
||||||
|
|
||||||
:param int level: The level.
|
:param level: The level.
|
||||||
:param str logger: The logger to update. If not given, the root logger.
|
:param logger: The logger to update. If not given, the root logger.
|
||||||
"""
|
"""
|
||||||
logger_obj = logging.getLogger(logger)
|
logger_obj = logging.getLogger(logger)
|
||||||
# Save the original log-level to restore it during teardown.
|
# Save the original log-level to restore it during teardown.
|
||||||
|
@ -471,8 +472,8 @@ class LogCaptureFixture:
|
||||||
the end of the 'with' statement the level is restored to its original
|
the end of the 'with' statement the level is restored to its original
|
||||||
value.
|
value.
|
||||||
|
|
||||||
:param int level: The level.
|
:param level: The level.
|
||||||
:param str logger: The logger to update. If not given, the root logger.
|
:param logger: The logger to update. If not given, the root logger.
|
||||||
"""
|
"""
|
||||||
logger_obj = logging.getLogger(logger)
|
logger_obj = logging.getLogger(logger)
|
||||||
orig_level = logger_obj.level
|
orig_level = logger_obj.level
|
||||||
|
|
|
@ -12,7 +12,6 @@ from typing import FrozenSet
|
||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import overload
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
@ -25,6 +24,7 @@ import attr
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
|
from _pytest.compat import overload
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.config import directory_arg
|
from _pytest.config import directory_arg
|
||||||
from _pytest.config import ExitCode
|
from _pytest.config import ExitCode
|
||||||
|
@ -597,12 +597,12 @@ class Session(nodes.FSCollector):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def perform_collect(
|
def perform_collect( # noqa: F811
|
||||||
self, args: Optional[Sequence[str]] = ..., genitems: bool = ...
|
self, args: Optional[Sequence[str]] = ..., genitems: bool = ...
|
||||||
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
|
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
|
||||||
...
|
...
|
||||||
|
|
||||||
def perform_collect(
|
def perform_collect( # noqa: F811
|
||||||
self, args: Optional[Sequence[str]] = None, genitems: bool = True
|
self, args: Optional[Sequence[str]] = None, genitems: bool = True
|
||||||
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
|
) -> Sequence[Union[nodes.Item, nodes.Collector]]:
|
||||||
"""Perform the collection phase for this session.
|
"""Perform the collection phase for this session.
|
||||||
|
|
|
@ -62,8 +62,8 @@ def param(
|
||||||
assert eval(test_input) == expected
|
assert eval(test_input) == expected
|
||||||
|
|
||||||
:param values: Variable args of the values of the parameter set, in order.
|
:param values: Variable args of the values of the parameter set, in order.
|
||||||
:keyword marks: A single mark or a list of marks to be applied to this parameter set.
|
:param marks: A single mark or a list of marks to be applied to this parameter set.
|
||||||
:keyword str id: The id to attribute to this parameter set.
|
:param id: The id to attribute to this parameter set.
|
||||||
"""
|
"""
|
||||||
return ParameterSet.param(*values, marks=marks, id=id)
|
return ParameterSet.param(*values, marks=marks, id=id)
|
||||||
|
|
||||||
|
|
|
@ -126,12 +126,12 @@ class ParameterSet(NamedTuple):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_parametrize_args(
|
def _parse_parametrize_args(
|
||||||
argnames: Union[str, List[str], Tuple[str, ...]],
|
argnames: Union[str, Sequence[str]],
|
||||||
argvalues: Iterable[Union["ParameterSet", Sequence[object], object]],
|
argvalues: Iterable[Union["ParameterSet", Sequence[object], object]],
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Tuple[Union[List[str], Tuple[str, ...]], bool]:
|
) -> Tuple[Sequence[str], bool]:
|
||||||
if not isinstance(argnames, (tuple, list)):
|
if isinstance(argnames, str):
|
||||||
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
||||||
force_tuple = len(argnames) == 1
|
force_tuple = len(argnames) == 1
|
||||||
else:
|
else:
|
||||||
|
@ -150,12 +150,12 @@ class ParameterSet(NamedTuple):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _for_parametrize(
|
def _for_parametrize(
|
||||||
cls,
|
cls,
|
||||||
argnames: Union[str, List[str], Tuple[str, ...]],
|
argnames: Union[str, Sequence[str]],
|
||||||
argvalues: Iterable[Union["ParameterSet", Sequence[object], object]],
|
argvalues: Iterable[Union["ParameterSet", Sequence[object], object]],
|
||||||
func,
|
func,
|
||||||
config: Config,
|
config: Config,
|
||||||
nodeid: str,
|
nodeid: str,
|
||||||
) -> Tuple[Union[List[str], Tuple[str, ...]], List["ParameterSet"]]:
|
) -> Tuple[Sequence[str], List["ParameterSet"]]:
|
||||||
argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues)
|
argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues)
|
||||||
parameters = cls._parse_parametrize_parameters(argvalues, force_tuple)
|
parameters = cls._parse_parametrize_parameters(argvalues, force_tuple)
|
||||||
del argvalues
|
del argvalues
|
||||||
|
@ -434,7 +434,7 @@ if TYPE_CHECKING:
|
||||||
class _ParametrizeMarkDecorator(MarkDecorator):
|
class _ParametrizeMarkDecorator(MarkDecorator):
|
||||||
def __call__( # type: ignore[override]
|
def __call__( # type: ignore[override]
|
||||||
self,
|
self,
|
||||||
argnames: Union[str, List[str], Tuple[str, ...]],
|
argnames: Union[str, Sequence[str]],
|
||||||
argvalues: Iterable[Union[ParameterSet, Sequence[object], object]],
|
argvalues: Iterable[Union[ParameterSet, Sequence[object], object]],
|
||||||
*,
|
*,
|
||||||
indirect: Union[bool, Sequence[str]] = ...,
|
indirect: Union[bool, Sequence[str]] = ...,
|
||||||
|
|
|
@ -29,21 +29,26 @@ V = TypeVar("V")
|
||||||
def monkeypatch() -> Generator["MonkeyPatch", None, None]:
|
def monkeypatch() -> Generator["MonkeyPatch", None, None]:
|
||||||
"""A convenient fixture for monkey-patching.
|
"""A convenient fixture for monkey-patching.
|
||||||
|
|
||||||
The fixture provides these methods to modify objects, dictionaries or
|
The fixture provides these methods to modify objects, dictionaries, or
|
||||||
os.environ::
|
:data:`os.environ`:
|
||||||
|
|
||||||
monkeypatch.setattr(obj, name, value, raising=True)
|
* :meth:`monkeypatch.setattr(obj, name, value, raising=True) <pytest.MonkeyPatch.setattr>`
|
||||||
monkeypatch.delattr(obj, name, raising=True)
|
* :meth:`monkeypatch.delattr(obj, name, raising=True) <pytest.MonkeyPatch.delattr>`
|
||||||
monkeypatch.setitem(mapping, name, value)
|
* :meth:`monkeypatch.setitem(mapping, name, value) <pytest.MonkeyPatch.setitem>`
|
||||||
monkeypatch.delitem(obj, name, raising=True)
|
* :meth:`monkeypatch.delitem(obj, name, raising=True) <pytest.MonkeyPatch.delitem>`
|
||||||
monkeypatch.setenv(name, value, prepend=None)
|
* :meth:`monkeypatch.setenv(name, value, prepend=None) <pytest.MonkeyPatch.setenv>`
|
||||||
monkeypatch.delenv(name, raising=True)
|
* :meth:`monkeypatch.delenv(name, raising=True) <pytest.MonkeyPatch.delenv>`
|
||||||
monkeypatch.syspath_prepend(path)
|
* :meth:`monkeypatch.syspath_prepend(path) <pytest.MonkeyPatch.syspath_prepend>`
|
||||||
monkeypatch.chdir(path)
|
* :meth:`monkeypatch.chdir(path) <pytest.MonkeyPatch.chdir>`
|
||||||
|
* :meth:`monkeypatch.context() <pytest.MonkeyPatch.context>`
|
||||||
|
|
||||||
All modifications will be undone after the requesting test function or
|
All modifications will be undone after the requesting test function or
|
||||||
fixture has finished. The ``raising`` parameter determines if a KeyError
|
fixture has finished. The ``raising`` parameter determines if a :class:`KeyError`
|
||||||
or AttributeError will be raised if the set/deletion operation has no target.
|
or :class:`AttributeError` will be raised if the set/deletion operation does not have the
|
||||||
|
specified target.
|
||||||
|
|
||||||
|
To undo modifications done by the fixture in a contained scope,
|
||||||
|
use :meth:`context() <pytest.MonkeyPatch.context>`.
|
||||||
"""
|
"""
|
||||||
mpatch = MonkeyPatch()
|
mpatch = MonkeyPatch()
|
||||||
yield mpatch
|
yield mpatch
|
||||||
|
@ -115,7 +120,7 @@ class MonkeyPatch:
|
||||||
|
|
||||||
Returned by the :fixture:`monkeypatch` fixture.
|
Returned by the :fixture:`monkeypatch` fixture.
|
||||||
|
|
||||||
:versionchanged:: 6.2
|
.. versionchanged:: 6.2
|
||||||
Can now also be used directly as `pytest.MonkeyPatch()`, for when
|
Can now also be used directly as `pytest.MonkeyPatch()`, for when
|
||||||
the fixture is not available. In this case, use
|
the fixture is not available. In this case, use
|
||||||
:meth:`with MonkeyPatch.context() as mp: <context>` or remember to call
|
:meth:`with MonkeyPatch.context() as mp: <context>` or remember to call
|
||||||
|
@ -182,16 +187,40 @@ class MonkeyPatch:
|
||||||
value: object = notset,
|
value: object = notset,
|
||||||
raising: bool = True,
|
raising: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set attribute value on target, memorizing the old value.
|
"""
|
||||||
|
Set attribute value on target, memorizing the old value.
|
||||||
|
|
||||||
For convenience you can specify a string as ``target`` which
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
monkeypatch.setattr(os, "getcwd", lambda: "/")
|
||||||
|
|
||||||
|
The code above replaces the :func:`os.getcwd` function by a ``lambda`` which
|
||||||
|
always returns ``"/"``.
|
||||||
|
|
||||||
|
For convenience, you can specify a string as ``target`` which
|
||||||
will be interpreted as a dotted import path, with the last part
|
will be interpreted as a dotted import path, with the last part
|
||||||
being the attribute name. For example,
|
being the attribute name:
|
||||||
``monkeypatch.setattr("os.getcwd", lambda: "/")``
|
|
||||||
would set the ``getcwd`` function of the ``os`` module.
|
|
||||||
|
|
||||||
Raises AttributeError if the attribute does not exist, unless
|
.. code-block:: python
|
||||||
|
|
||||||
|
monkeypatch.setattr("os.getcwd", lambda: "/")
|
||||||
|
|
||||||
|
Raises :class:`AttributeError` if the attribute does not exist, unless
|
||||||
``raising`` is set to False.
|
``raising`` is set to False.
|
||||||
|
|
||||||
|
**Where to patch**
|
||||||
|
|
||||||
|
``monkeypatch.setattr`` works by (temporarily) changing the object that a name points to with another one.
|
||||||
|
There can be many names pointing to any individual object, so for patching to work you must ensure
|
||||||
|
that you patch the name used by the system under test.
|
||||||
|
|
||||||
|
See the section :ref:`Where to patch <python:where-to-patch>` in the :mod:`unittest.mock`
|
||||||
|
docs for a complete explanation, which is meant for :func:`unittest.mock.patch` but
|
||||||
|
applies to ``monkeypatch.setattr`` as well.
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -338,7 +367,8 @@ class MonkeyPatch:
|
||||||
def chdir(self, path: Union[str, "os.PathLike[str]"]) -> None:
|
def chdir(self, path: Union[str, "os.PathLike[str]"]) -> None:
|
||||||
"""Change the current working directory to the specified path.
|
"""Change the current working directory to the specified path.
|
||||||
|
|
||||||
Path can be a string or a path object.
|
:param path:
|
||||||
|
The path to change into.
|
||||||
"""
|
"""
|
||||||
if self._cwd is None:
|
if self._cwd is None:
|
||||||
self._cwd = os.getcwd()
|
self._cwd = os.getcwd()
|
||||||
|
@ -353,11 +383,14 @@ class MonkeyPatch:
|
||||||
There is generally no need to call `undo()`, since it is
|
There is generally no need to call `undo()`, since it is
|
||||||
called automatically during tear-down.
|
called automatically during tear-down.
|
||||||
|
|
||||||
Note that the same `monkeypatch` fixture is used across a
|
.. note::
|
||||||
|
The same `monkeypatch` fixture is used across a
|
||||||
single test function invocation. If `monkeypatch` is used both by
|
single test function invocation. If `monkeypatch` is used both by
|
||||||
the test function itself and one of the test fixtures,
|
the test function itself and one of the test fixtures,
|
||||||
calling `undo()` will undo all of the changes made in
|
calling `undo()` will undo all of the changes made in
|
||||||
both functions.
|
both functions.
|
||||||
|
|
||||||
|
Prefer to use :meth:`context() <pytest.MonkeyPatch.context>` instead.
|
||||||
"""
|
"""
|
||||||
for obj, name, value in reversed(self._setattr):
|
for obj, name, value in reversed(self._setattr):
|
||||||
if value is not notset:
|
if value is not notset:
|
||||||
|
|
|
@ -193,7 +193,7 @@ class Node(metaclass=NodeMeta):
|
||||||
nodeid: Optional[str] = None,
|
nodeid: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
#: A unique name within the scope of the parent node.
|
#: A unique name within the scope of the parent node.
|
||||||
self.name = name
|
self.name: str = name
|
||||||
|
|
||||||
#: The parent collector node.
|
#: The parent collector node.
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
@ -208,7 +208,7 @@ class Node(metaclass=NodeMeta):
|
||||||
|
|
||||||
if session:
|
if session:
|
||||||
#: The pytest session this node is part of.
|
#: The pytest session this node is part of.
|
||||||
self.session = session
|
self.session: Session = session
|
||||||
else:
|
else:
|
||||||
if not parent:
|
if not parent:
|
||||||
raise TypeError("session or parent must be provided")
|
raise TypeError("session or parent must be provided")
|
||||||
|
@ -239,9 +239,7 @@ class Node(metaclass=NodeMeta):
|
||||||
|
|
||||||
#: A place where plugins can store information on the node for their
|
#: A place where plugins can store information on the node for their
|
||||||
#: own use.
|
#: own use.
|
||||||
#:
|
self.stash: Stash = Stash()
|
||||||
#: :type: Stash
|
|
||||||
self.stash = Stash()
|
|
||||||
# Deprecated alias. Was never public. Can be removed in a few releases.
|
# Deprecated alias. Was never public. Can be removed in a few releases.
|
||||||
self._store = self.stash
|
self._store = self.stash
|
||||||
|
|
||||||
|
@ -326,7 +324,10 @@ class Node(metaclass=NodeMeta):
|
||||||
|
|
||||||
def listchain(self) -> List["Node"]:
|
def listchain(self) -> List["Node"]:
|
||||||
"""Return list of all parent collectors up to self, starting from
|
"""Return list of all parent collectors up to self, starting from
|
||||||
the root of collection tree."""
|
the root of collection tree.
|
||||||
|
|
||||||
|
:returns: The nodes.
|
||||||
|
"""
|
||||||
chain = []
|
chain = []
|
||||||
item: Optional[Node] = self
|
item: Optional[Node] = self
|
||||||
while item is not None:
|
while item is not None:
|
||||||
|
@ -340,6 +341,8 @@ class Node(metaclass=NodeMeta):
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Dynamically add a marker object to the node.
|
"""Dynamically add a marker object to the node.
|
||||||
|
|
||||||
|
:param marker:
|
||||||
|
The marker.
|
||||||
:param append:
|
:param append:
|
||||||
Whether to append the marker, or prepend it.
|
Whether to append the marker, or prepend it.
|
||||||
"""
|
"""
|
||||||
|
@ -361,6 +364,7 @@ class Node(metaclass=NodeMeta):
|
||||||
"""Iterate over all markers of the node.
|
"""Iterate over all markers of the node.
|
||||||
|
|
||||||
:param name: If given, filter the results by the name attribute.
|
:param name: If given, filter the results by the name attribute.
|
||||||
|
:returns: An iterator of the markers of the node.
|
||||||
"""
|
"""
|
||||||
return (x[1] for x in self.iter_markers_with_node(name=name))
|
return (x[1] for x in self.iter_markers_with_node(name=name))
|
||||||
|
|
||||||
|
@ -407,7 +411,8 @@ class Node(metaclass=NodeMeta):
|
||||||
return [x.name for x in self.listchain()]
|
return [x.name for x in self.listchain()]
|
||||||
|
|
||||||
def addfinalizer(self, fin: Callable[[], object]) -> None:
|
def addfinalizer(self, fin: Callable[[], object]) -> None:
|
||||||
"""Register a function to be called when this node is finalized.
|
"""Register a function to be called without arguments when this node is
|
||||||
|
finalized.
|
||||||
|
|
||||||
This method can only be called when this node is active
|
This method can only be called when this node is active
|
||||||
in a setup chain, for example during self.setup().
|
in a setup chain, for example during self.setup().
|
||||||
|
@ -416,7 +421,11 @@ class Node(metaclass=NodeMeta):
|
||||||
|
|
||||||
def getparent(self, cls: Type[_NodeType]) -> Optional[_NodeType]:
|
def getparent(self, cls: Type[_NodeType]) -> Optional[_NodeType]:
|
||||||
"""Get the next parent node (including self) which is an instance of
|
"""Get the next parent node (including self) which is an instance of
|
||||||
the given class."""
|
the given class.
|
||||||
|
|
||||||
|
:param cls: The node class to search for.
|
||||||
|
:returns: The node, if found.
|
||||||
|
"""
|
||||||
current: Optional[Node] = self
|
current: Optional[Node] = self
|
||||||
while current and not isinstance(current, cls):
|
while current and not isinstance(current, cls):
|
||||||
current = current.parent
|
current = current.parent
|
||||||
|
|
|
@ -241,6 +241,9 @@ def xfail(reason: str = "") -> NoReturn:
|
||||||
|
|
||||||
This function should be called only during testing (setup, call or teardown).
|
This function should be called only during testing (setup, call or teardown).
|
||||||
|
|
||||||
|
:param reason:
|
||||||
|
The message to show the user as reason for the xfail.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
It is better to use the :ref:`pytest.mark.xfail ref` marker when
|
It is better to use the :ref:`pytest.mark.xfail ref` marker when
|
||||||
possible to declare a test to be xfailed under certain conditions
|
possible to declare a test to be xfailed under certain conditions
|
||||||
|
@ -256,12 +259,12 @@ def importorskip(
|
||||||
"""Import and return the requested module ``modname``, or skip the
|
"""Import and return the requested module ``modname``, or skip the
|
||||||
current test if the module cannot be imported.
|
current test if the module cannot be imported.
|
||||||
|
|
||||||
:param str modname:
|
:param modname:
|
||||||
The name of the module to import.
|
The name of the module to import.
|
||||||
:param str minversion:
|
:param minversion:
|
||||||
If given, the imported module's ``__version__`` attribute must be at
|
If given, the imported module's ``__version__`` attribute must be at
|
||||||
least this minimal version, otherwise the test is still skipped.
|
least this minimal version, otherwise the test is still skipped.
|
||||||
:param str reason:
|
:param reason:
|
||||||
If given, this reason is shown as the message when the module cannot
|
If given, this reason is shown as the message when the module cannot
|
||||||
be imported.
|
be imported.
|
||||||
|
|
||||||
|
|
|
@ -661,17 +661,7 @@ class Pytester:
|
||||||
against expected output, perfect for black-box testing of pytest plugins.
|
against expected output, perfect for black-box testing of pytest plugins.
|
||||||
|
|
||||||
It attempts to isolate the test run from external factors as much as possible, modifying
|
It attempts to isolate the test run from external factors as much as possible, modifying
|
||||||
the current working directory to ``path`` and environment variables during initialization.
|
the current working directory to :attr:`path` and environment variables during initialization.
|
||||||
|
|
||||||
Attributes:
|
|
||||||
|
|
||||||
:ivar Path path: temporary directory path used to create files/run tests from, etc.
|
|
||||||
|
|
||||||
:ivar plugins:
|
|
||||||
A list of plugins to use with :py:meth:`parseconfig` and
|
|
||||||
:py:meth:`runpytest`. Initially this is an empty list but plugins can
|
|
||||||
be added to the list. The type of items to add to the list depends on
|
|
||||||
the method using them so refer to them for details.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__test__ = False
|
__test__ = False
|
||||||
|
@ -700,6 +690,10 @@ class Pytester:
|
||||||
name = request.node.name
|
name = request.node.name
|
||||||
self._name = name
|
self._name = name
|
||||||
self._path: Path = tmp_path_factory.mktemp(name, numbered=True)
|
self._path: Path = tmp_path_factory.mktemp(name, numbered=True)
|
||||||
|
#: A list of plugins to use with :py:meth:`parseconfig` and
|
||||||
|
#: :py:meth:`runpytest`. Initially this is an empty list but plugins can
|
||||||
|
#: be added to the list. The type of items to add to the list depends on
|
||||||
|
#: the method using them so refer to them for details.
|
||||||
self.plugins: List[Union[str, _PluggyPlugin]] = []
|
self.plugins: List[Union[str, _PluggyPlugin]] = []
|
||||||
self._cwd_snapshot = CwdSnapshot()
|
self._cwd_snapshot = CwdSnapshot()
|
||||||
self._sys_path_snapshot = SysPathsSnapshot()
|
self._sys_path_snapshot = SysPathsSnapshot()
|
||||||
|
@ -724,7 +718,7 @@ class Pytester:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self) -> Path:
|
def path(self) -> Path:
|
||||||
"""Temporary directory where files are created and pytest is executed."""
|
"""Temporary directory path used to create files/run tests from, etc."""
|
||||||
return self._path
|
return self._path
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
|
@ -755,7 +749,7 @@ class Pytester:
|
||||||
return SysModulesSnapshot(preserve=preserve_module)
|
return SysModulesSnapshot(preserve=preserve_module)
|
||||||
|
|
||||||
def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder:
|
def make_hook_recorder(self, pluginmanager: PytestPluginManager) -> HookRecorder:
|
||||||
"""Create a new :py:class:`HookRecorder` for a PluginManager."""
|
"""Create a new :class:`HookRecorder` for a :class:`PytestPluginManager`."""
|
||||||
pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True)
|
pluginmanager.reprec = reprec = HookRecorder(pluginmanager, _ispytest=True)
|
||||||
self._request.addfinalizer(reprec.finish_recording)
|
self._request.addfinalizer(reprec.finish_recording)
|
||||||
return reprec
|
return reprec
|
||||||
|
@ -804,7 +798,7 @@ class Pytester:
|
||||||
def makefile(self, ext: str, *args: str, **kwargs: str) -> Path:
|
def makefile(self, ext: str, *args: str, **kwargs: str) -> Path:
|
||||||
r"""Create new text file(s) in the test directory.
|
r"""Create new text file(s) in the test directory.
|
||||||
|
|
||||||
:param str ext:
|
:param ext:
|
||||||
The extension the file(s) should use, including the dot, e.g. `.py`.
|
The extension the file(s) should use, including the dot, e.g. `.py`.
|
||||||
:param args:
|
:param args:
|
||||||
All args are treated as strings and joined using newlines.
|
All args are treated as strings and joined using newlines.
|
||||||
|
@ -813,6 +807,8 @@ class Pytester:
|
||||||
:param kwargs:
|
:param kwargs:
|
||||||
Each keyword is the name of a file, while the value of it will
|
Each keyword is the name of a file, while the value of it will
|
||||||
be written as contents of the file.
|
be written as contents of the file.
|
||||||
|
:returns:
|
||||||
|
The first created file.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -832,11 +828,19 @@ class Pytester:
|
||||||
return self._makefile(ext, args, kwargs)
|
return self._makefile(ext, args, kwargs)
|
||||||
|
|
||||||
def makeconftest(self, source: str) -> Path:
|
def makeconftest(self, source: str) -> Path:
|
||||||
"""Write a conftest.py file with 'source' as contents."""
|
"""Write a contest.py file.
|
||||||
|
|
||||||
|
:param source: The contents.
|
||||||
|
:returns: The conftest.py file.
|
||||||
|
"""
|
||||||
return self.makepyfile(conftest=source)
|
return self.makepyfile(conftest=source)
|
||||||
|
|
||||||
def makeini(self, source: str) -> Path:
|
def makeini(self, source: str) -> Path:
|
||||||
"""Write a tox.ini file with 'source' as contents."""
|
"""Write a tox.ini file.
|
||||||
|
|
||||||
|
:param source: The contents.
|
||||||
|
:returns: The tox.ini file.
|
||||||
|
"""
|
||||||
return self.makefile(".ini", tox=source)
|
return self.makefile(".ini", tox=source)
|
||||||
|
|
||||||
def getinicfg(self, source: str) -> SectionWrapper:
|
def getinicfg(self, source: str) -> SectionWrapper:
|
||||||
|
@ -845,7 +849,10 @@ class Pytester:
|
||||||
return IniConfig(str(p))["pytest"]
|
return IniConfig(str(p))["pytest"]
|
||||||
|
|
||||||
def makepyprojecttoml(self, source: str) -> Path:
|
def makepyprojecttoml(self, source: str) -> Path:
|
||||||
"""Write a pyproject.toml file with 'source' as contents.
|
"""Write a pyproject.toml file.
|
||||||
|
|
||||||
|
:param source: The contents.
|
||||||
|
:returns: The pyproject.ini file.
|
||||||
|
|
||||||
.. versionadded:: 6.0
|
.. versionadded:: 6.0
|
||||||
"""
|
"""
|
||||||
|
@ -898,6 +905,9 @@ class Pytester:
|
||||||
|
|
||||||
This is undone automatically when this object dies at the end of each
|
This is undone automatically when this object dies at the end of each
|
||||||
test.
|
test.
|
||||||
|
|
||||||
|
:param path:
|
||||||
|
The path.
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
path = self.path
|
path = self.path
|
||||||
|
@ -905,7 +915,13 @@ class Pytester:
|
||||||
self._monkeypatch.syspath_prepend(str(path))
|
self._monkeypatch.syspath_prepend(str(path))
|
||||||
|
|
||||||
def mkdir(self, name: Union[str, "os.PathLike[str]"]) -> Path:
|
def mkdir(self, name: Union[str, "os.PathLike[str]"]) -> Path:
|
||||||
"""Create a new (sub)directory."""
|
"""Create a new (sub)directory.
|
||||||
|
|
||||||
|
:param name:
|
||||||
|
The name of the directory, relative to the pytester path.
|
||||||
|
:returns:
|
||||||
|
The created directory.
|
||||||
|
"""
|
||||||
p = self.path / name
|
p = self.path / name
|
||||||
p.mkdir()
|
p.mkdir()
|
||||||
return p
|
return p
|
||||||
|
@ -924,14 +940,15 @@ class Pytester:
|
||||||
def copy_example(self, name: Optional[str] = None) -> Path:
|
def copy_example(self, name: Optional[str] = None) -> Path:
|
||||||
"""Copy file from project's directory into the testdir.
|
"""Copy file from project's directory into the testdir.
|
||||||
|
|
||||||
:param str name: The name of the file to copy.
|
:param name:
|
||||||
:return: path to the copied directory (inside ``self.path``).
|
The name of the file to copy.
|
||||||
|
:return:
|
||||||
|
Path to the copied directory (inside ``self.path``).
|
||||||
"""
|
"""
|
||||||
example_dir = self._request.config.getini("pytester_example_dir")
|
example_dir_ = self._request.config.getini("pytester_example_dir")
|
||||||
if example_dir is None:
|
if example_dir_ is None:
|
||||||
raise ValueError("pytester_example_dir is unset, can't copy examples")
|
raise ValueError("pytester_example_dir is unset, can't copy examples")
|
||||||
example_dir = self._request.config.rootpath / example_dir
|
example_dir: Path = self._request.config.rootpath / example_dir_
|
||||||
|
|
||||||
for extra_element in self._request.node.iter_markers("pytester_example_path"):
|
for extra_element in self._request.node.iter_markers("pytester_example_path"):
|
||||||
assert extra_element.args
|
assert extra_element.args
|
||||||
|
@ -967,14 +984,16 @@ class Pytester:
|
||||||
|
|
||||||
def getnode(
|
def getnode(
|
||||||
self, config: Config, arg: Union[str, "os.PathLike[str]"]
|
self, config: Config, arg: Union[str, "os.PathLike[str]"]
|
||||||
) -> Optional[Union[Collector, Item]]:
|
) -> Union[Collector, Item]:
|
||||||
"""Return the collection node of a file.
|
"""Get the collection node of a file.
|
||||||
|
|
||||||
:param pytest.Config config:
|
:param config:
|
||||||
A pytest config.
|
A pytest config.
|
||||||
See :py:meth:`parseconfig` and :py:meth:`parseconfigure` for creating it.
|
See :py:meth:`parseconfig` and :py:meth:`parseconfigure` for creating it.
|
||||||
:param os.PathLike[str] arg:
|
:param arg:
|
||||||
Path to the file.
|
Path to the file.
|
||||||
|
:returns:
|
||||||
|
The node.
|
||||||
"""
|
"""
|
||||||
session = Session.from_config(config)
|
session = Session.from_config(config)
|
||||||
assert "::" not in str(arg)
|
assert "::" not in str(arg)
|
||||||
|
@ -984,13 +1003,18 @@ class Pytester:
|
||||||
config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK)
|
config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def getpathnode(self, path: Union[str, "os.PathLike[str]"]):
|
def getpathnode(
|
||||||
|
self, path: Union[str, "os.PathLike[str]"]
|
||||||
|
) -> Union[Collector, Item]:
|
||||||
"""Return the collection node of a file.
|
"""Return the collection node of a file.
|
||||||
|
|
||||||
This is like :py:meth:`getnode` but uses :py:meth:`parseconfigure` to
|
This is like :py:meth:`getnode` but uses :py:meth:`parseconfigure` to
|
||||||
create the (configured) pytest Config instance.
|
create the (configured) pytest Config instance.
|
||||||
|
|
||||||
:param os.PathLike[str] path: Path to the file.
|
:param path:
|
||||||
|
Path to the file.
|
||||||
|
:returns:
|
||||||
|
The node.
|
||||||
"""
|
"""
|
||||||
path = Path(path)
|
path = Path(path)
|
||||||
config = self.parseconfigure(path)
|
config = self.parseconfigure(path)
|
||||||
|
@ -1006,6 +1030,11 @@ class Pytester:
|
||||||
|
|
||||||
This recurses into the collection node and returns a list of all the
|
This recurses into the collection node and returns a list of all the
|
||||||
test items contained within.
|
test items contained within.
|
||||||
|
|
||||||
|
:param colitems:
|
||||||
|
The collection nodes.
|
||||||
|
:returns:
|
||||||
|
The collected items.
|
||||||
"""
|
"""
|
||||||
session = colitems[0].session
|
session = colitems[0].session
|
||||||
result: List[Item] = []
|
result: List[Item] = []
|
||||||
|
@ -1192,15 +1221,16 @@ class Pytester:
|
||||||
return new_args
|
return new_args
|
||||||
|
|
||||||
def parseconfig(self, *args: Union[str, "os.PathLike[str]"]) -> Config:
|
def parseconfig(self, *args: Union[str, "os.PathLike[str]"]) -> Config:
|
||||||
"""Return a new pytest Config instance from given commandline args.
|
"""Return a new pytest :class:`pytest.Config` instance from given
|
||||||
|
commandline args.
|
||||||
|
|
||||||
This invokes the pytest bootstrapping code in _pytest.config to create
|
This invokes the pytest bootstrapping code in _pytest.config to create a
|
||||||
a new :py:class:`_pytest.core.PluginManager` and call the
|
new :py:class:`pytest.PytestPluginManager` and call the
|
||||||
pytest_cmdline_parse hook to create a new
|
:hook:`pytest_cmdline_parse` hook to create a new :class:`pytest.Config`
|
||||||
:py:class:`pytest.Config` instance.
|
instance.
|
||||||
|
|
||||||
If :py:attr:`plugins` has been populated they should be plugin modules
|
If :attr:`plugins` has been populated they should be plugin modules
|
||||||
to be registered with the PluginManager.
|
to be registered with the plugin manager.
|
||||||
"""
|
"""
|
||||||
import _pytest.config
|
import _pytest.config
|
||||||
|
|
||||||
|
@ -1218,7 +1248,8 @@ class Pytester:
|
||||||
"""Return a new pytest configured Config instance.
|
"""Return a new pytest configured Config instance.
|
||||||
|
|
||||||
Returns a new :py:class:`pytest.Config` instance like
|
Returns a new :py:class:`pytest.Config` instance like
|
||||||
:py:meth:`parseconfig`, but also calls the pytest_configure hook.
|
:py:meth:`parseconfig`, but also calls the :hook:`pytest_configure`
|
||||||
|
hook.
|
||||||
"""
|
"""
|
||||||
config = self.parseconfig(*args)
|
config = self.parseconfig(*args)
|
||||||
config._do_configure()
|
config._do_configure()
|
||||||
|
@ -1237,6 +1268,8 @@ class Pytester:
|
||||||
The module source.
|
The module source.
|
||||||
:param funcname:
|
:param funcname:
|
||||||
The name of the test function for which to return a test item.
|
The name of the test function for which to return a test item.
|
||||||
|
:returns:
|
||||||
|
The test item.
|
||||||
"""
|
"""
|
||||||
items = self.getitems(source)
|
items = self.getitems(source)
|
||||||
for item in items:
|
for item in items:
|
||||||
|
@ -1377,6 +1410,8 @@ class Pytester:
|
||||||
- Otherwise, it is passed through to :py:class:`subprocess.Popen`.
|
- Otherwise, it is passed through to :py:class:`subprocess.Popen`.
|
||||||
For further information in this case, consult the document of the
|
For further information in this case, consult the document of the
|
||||||
``stdin`` parameter in :py:class:`subprocess.Popen`.
|
``stdin`` parameter in :py:class:`subprocess.Popen`.
|
||||||
|
:returns:
|
||||||
|
The result.
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
|
|
||||||
|
@ -1463,6 +1498,8 @@ class Pytester:
|
||||||
:param timeout:
|
:param timeout:
|
||||||
The period in seconds after which to timeout and raise
|
The period in seconds after which to timeout and raise
|
||||||
:py:class:`Pytester.TimeoutExpired`.
|
:py:class:`Pytester.TimeoutExpired`.
|
||||||
|
:returns:
|
||||||
|
The result.
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700)
|
p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700)
|
||||||
|
|
|
@ -1207,7 +1207,7 @@ class Metafunc:
|
||||||
|
|
||||||
def parametrize(
|
def parametrize(
|
||||||
self,
|
self,
|
||||||
argnames: Union[str, List[str], Tuple[str, ...]],
|
argnames: Union[str, Sequence[str]],
|
||||||
argvalues: Iterable[Union[ParameterSet, Sequence[object], object]],
|
argvalues: Iterable[Union[ParameterSet, Sequence[object], object]],
|
||||||
indirect: Union[bool, Sequence[str]] = False,
|
indirect: Union[bool, Sequence[str]] = False,
|
||||||
ids: Optional[
|
ids: Optional[
|
||||||
|
|
|
@ -12,7 +12,6 @@ from typing import Generic
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Mapping
|
from typing import Mapping
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import overload
|
|
||||||
from typing import Pattern
|
from typing import Pattern
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
@ -28,6 +27,7 @@ if TYPE_CHECKING:
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
from _pytest.compat import STRING_TYPES
|
from _pytest.compat import STRING_TYPES
|
||||||
|
from _pytest.compat import overload
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
|
||||||
"""Assert that two numbers (or two ordered sequences of numbers) are equal to each other
|
"""Assert that two numbers (or two ordered sequences of numbers) are equal to each other
|
||||||
within some tolerance.
|
within some tolerance.
|
||||||
|
|
||||||
Due to the :std:doc:`tutorial/floatingpoint`, numbers that we
|
Due to the :doc:`python:tutorial/floatingpoint`, numbers that we
|
||||||
would intuitively expect to be equal are not always so::
|
would intuitively expect to be equal are not always so::
|
||||||
|
|
||||||
>>> 0.1 + 0.2 == 0.3
|
>>> 0.1 + 0.2 == 0.3
|
||||||
|
@ -786,7 +786,7 @@ def raises(
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def raises(
|
def raises( # noqa: F811
|
||||||
expected_exception: Union[Type[E], Tuple[Type[E], ...]],
|
expected_exception: Union[Type[E], Tuple[Type[E], ...]],
|
||||||
func: Callable[..., Any],
|
func: Callable[..., Any],
|
||||||
*args: Any,
|
*args: Any,
|
||||||
|
@ -795,18 +795,21 @@ def raises(
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def raises(
|
def raises( # noqa: F811
|
||||||
expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any
|
expected_exception: Union[Type[E], Tuple[Type[E], ...]], *args: Any, **kwargs: Any
|
||||||
) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]:
|
) -> Union["RaisesContext[E]", _pytest._code.ExceptionInfo[E]]:
|
||||||
r"""Assert that a code block/function call raises ``expected_exception``
|
r"""Assert that a code block/function call raises an exception.
|
||||||
or raise a failure exception otherwise.
|
|
||||||
|
|
||||||
:kwparam match:
|
:param typing.Type[E] | typing.Tuple[typing.Type[E], ...] expected_exception:
|
||||||
|
The excpected exception type, or a tuple if one of multiple possible
|
||||||
|
exception types are excepted.
|
||||||
|
:kwparam str | typing.Pattern[str] | None match:
|
||||||
If specified, a string containing a regular expression,
|
If specified, a string containing a regular expression,
|
||||||
or a regular expression object, that is tested against the string
|
or a regular expression object, that is tested against the string
|
||||||
representation of the exception using :py:func:`re.search`. To match a literal
|
representation of the exception using :func:`re.search`.
|
||||||
string that may contain :std:ref:`special characters <re-syntax>`, the pattern can
|
|
||||||
first be escaped with :py:func:`re.escape`.
|
To match a literal string that may contain :ref:`special characters
|
||||||
|
<re-syntax>`, the pattern can first be escaped with :func:`re.escape`.
|
||||||
|
|
||||||
(This is only used when :py:func:`pytest.raises` is used as a context manager,
|
(This is only used when :py:func:`pytest.raises` is used as a context manager,
|
||||||
and passed through to the function otherwise.
|
and passed through to the function otherwise.
|
||||||
|
|
|
@ -9,7 +9,6 @@ from typing import Generator
|
||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import overload
|
|
||||||
from typing import Pattern
|
from typing import Pattern
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
@ -17,6 +16,7 @@ from typing import TypeVar
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from _pytest.compat import final
|
from _pytest.compat import final
|
||||||
|
from _pytest.compat import overload
|
||||||
from _pytest.deprecated import check_ispytest
|
from _pytest.deprecated import check_ispytest
|
||||||
from _pytest.deprecated import WARNS_NONE_ARG
|
from _pytest.deprecated import WARNS_NONE_ARG
|
||||||
from _pytest.fixtures import fixture
|
from _pytest.fixtures import fixture
|
||||||
|
@ -47,11 +47,13 @@ def deprecated_call(
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
|
def deprecated_call( # noqa: F811
|
||||||
|
func: Callable[..., T], *args: Any, **kwargs: Any
|
||||||
|
) -> T:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def deprecated_call(
|
def deprecated_call( # noqa: F811
|
||||||
func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
|
func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
|
||||||
) -> Union["WarningsRecorder", Any]:
|
) -> Union["WarningsRecorder", Any]:
|
||||||
"""Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.
|
"""Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.
|
||||||
|
@ -93,7 +95,7 @@ def warns(
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def warns(
|
def warns( # noqa: F811
|
||||||
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]],
|
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]],
|
||||||
func: Callable[..., T],
|
func: Callable[..., T],
|
||||||
*args: Any,
|
*args: Any,
|
||||||
|
@ -102,7 +104,7 @@ def warns(
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def warns(
|
def warns( # noqa: F811
|
||||||
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
|
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
|
||||||
*args: Any,
|
*args: Any,
|
||||||
match: Optional[Union[str, Pattern[str]]] = None,
|
match: Optional[Union[str, Pattern[str]]] = None,
|
||||||
|
@ -110,15 +112,15 @@ def warns(
|
||||||
) -> Union["WarningsChecker", Any]:
|
) -> Union["WarningsChecker", Any]:
|
||||||
r"""Assert that code raises a particular class of warning.
|
r"""Assert that code raises a particular class of warning.
|
||||||
|
|
||||||
Specifically, the parameter ``expected_warning`` can be a warning class or
|
Specifically, the parameter ``expected_warning`` can be a warning class or sequence
|
||||||
sequence of warning classes, and the code inside the ``with`` block must issue a warning of that class or
|
of warning classes, and the code inside the ``with`` block must issue at least one
|
||||||
classes.
|
warning of that class or classes.
|
||||||
|
|
||||||
This helper produces a list of :class:`warnings.WarningMessage` objects,
|
This helper produces a list of :class:`warnings.WarningMessage` objects, one for
|
||||||
one for each warning raised.
|
each warning raised (regardless of whether it is an ``expected_warning`` or not).
|
||||||
|
|
||||||
This function can be used as a context manager, or any of the other ways
|
This function can be used as a context manager, which will capture all the raised
|
||||||
:func:`pytest.raises` can be used::
|
warnings inside it::
|
||||||
|
|
||||||
>>> import pytest
|
>>> import pytest
|
||||||
>>> with pytest.warns(RuntimeWarning):
|
>>> with pytest.warns(RuntimeWarning):
|
||||||
|
@ -139,6 +141,14 @@ def warns(
|
||||||
...
|
...
|
||||||
Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...
|
Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...
|
||||||
|
|
||||||
|
**Using with** ``pytest.mark.parametrize``
|
||||||
|
|
||||||
|
When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests
|
||||||
|
such that some runs raise a warning and others do not.
|
||||||
|
|
||||||
|
This could be achieved in the same way as with exceptions, see
|
||||||
|
:ref:`parametrizing_conditional_raising` for an example.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
if not args:
|
if not args:
|
||||||
|
|
|
@ -276,7 +276,7 @@ class TestReport(BaseReport):
|
||||||
|
|
||||||
#: A name -> value dictionary containing all keywords and
|
#: A name -> value dictionary containing all keywords and
|
||||||
#: markers associated with a test invocation.
|
#: markers associated with a test invocation.
|
||||||
self.keywords = keywords
|
self.keywords: Mapping[str, Any] = keywords
|
||||||
|
|
||||||
#: Test outcome, always one of "passed", "failed", "skipped".
|
#: Test outcome, always one of "passed", "failed", "skipped".
|
||||||
self.outcome = outcome
|
self.outcome = outcome
|
||||||
|
@ -298,7 +298,7 @@ class TestReport(BaseReport):
|
||||||
self.sections = list(sections)
|
self.sections = list(sections)
|
||||||
|
|
||||||
#: Time it took to run just the test.
|
#: Time it took to run just the test.
|
||||||
self.duration = duration
|
self.duration: float = duration
|
||||||
|
|
||||||
self.__dict__.update(extra)
|
self.__dict__.update(extra)
|
||||||
|
|
||||||
|
@ -309,7 +309,11 @@ class TestReport(BaseReport):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_item_and_call(cls, item: Item, call: "CallInfo[None]") -> "TestReport":
|
def from_item_and_call(cls, item: Item, call: "CallInfo[None]") -> "TestReport":
|
||||||
"""Create and fill a TestReport with standard item and call info."""
|
"""Create and fill a TestReport with standard item and call info.
|
||||||
|
|
||||||
|
:param item: The item.
|
||||||
|
:param call: The call info.
|
||||||
|
"""
|
||||||
when = call.when
|
when = call.when
|
||||||
# Remove "collect" from the Literal type -- only for collection calls.
|
# Remove "collect" from the Literal type -- only for collection calls.
|
||||||
assert when != "collect"
|
assert when != "collect"
|
||||||
|
|
|
@ -100,7 +100,11 @@ class TempPathFactory:
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def getbasetemp(self) -> Path:
|
def getbasetemp(self) -> Path:
|
||||||
"""Return the base temporary directory, creating it if needed."""
|
"""Return the base temporary directory, creating it if needed.
|
||||||
|
|
||||||
|
:returns:
|
||||||
|
The base temporary directory.
|
||||||
|
"""
|
||||||
if self._basetemp is not None:
|
if self._basetemp is not None:
|
||||||
return self._basetemp
|
return self._basetemp
|
||||||
|
|
||||||
|
|
|
@ -1470,3 +1470,90 @@ def test_no_recursion_index_on_recursion_error():
|
||||||
with pytest.raises(RuntimeError) as excinfo:
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
RecursionDepthError().trigger
|
RecursionDepthError().trigger
|
||||||
assert "maximum recursion" in str(excinfo.getrepr())
|
assert "maximum recursion" in str(excinfo.getrepr())
|
||||||
|
|
||||||
|
|
||||||
|
def _exceptiongroup_common(
|
||||||
|
pytester: Pytester,
|
||||||
|
outer_chain: str,
|
||||||
|
inner_chain: str,
|
||||||
|
native: bool,
|
||||||
|
) -> None:
|
||||||
|
pre_raise = "exceptiongroup." if not native else ""
|
||||||
|
pre_catch = pre_raise if sys.version_info < (3, 11) else ""
|
||||||
|
filestr = f"""
|
||||||
|
{"import exceptiongroup" if not native else ""}
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def f(): raise ValueError("From f()")
|
||||||
|
def g(): raise BaseException("From g()")
|
||||||
|
|
||||||
|
def inner(inner_chain):
|
||||||
|
excs = []
|
||||||
|
for callback in [f, g]:
|
||||||
|
try:
|
||||||
|
callback()
|
||||||
|
except BaseException as err:
|
||||||
|
excs.append(err)
|
||||||
|
if excs:
|
||||||
|
if inner_chain == "none":
|
||||||
|
raise {pre_raise}BaseExceptionGroup("Oops", excs)
|
||||||
|
try:
|
||||||
|
raise SyntaxError()
|
||||||
|
except SyntaxError as e:
|
||||||
|
if inner_chain == "from":
|
||||||
|
raise {pre_raise}BaseExceptionGroup("Oops", excs) from e
|
||||||
|
else:
|
||||||
|
raise {pre_raise}BaseExceptionGroup("Oops", excs)
|
||||||
|
|
||||||
|
def outer(outer_chain, inner_chain):
|
||||||
|
try:
|
||||||
|
inner(inner_chain)
|
||||||
|
except {pre_catch}BaseExceptionGroup as e:
|
||||||
|
if outer_chain == "none":
|
||||||
|
raise
|
||||||
|
if outer_chain == "from":
|
||||||
|
raise IndexError() from e
|
||||||
|
else:
|
||||||
|
raise IndexError()
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
outer("{outer_chain}", "{inner_chain}")
|
||||||
|
"""
|
||||||
|
pytester.makepyfile(test_excgroup=filestr)
|
||||||
|
result = pytester.runpytest()
|
||||||
|
match_lines = []
|
||||||
|
if inner_chain in ("another", "from"):
|
||||||
|
match_lines.append(r"SyntaxError: <no detail available>")
|
||||||
|
|
||||||
|
match_lines += [
|
||||||
|
r" + Exception Group Traceback (most recent call last):",
|
||||||
|
rf" \| {pre_catch}BaseExceptionGroup: Oops \(2 sub-exceptions\)",
|
||||||
|
r" \| ValueError: From f\(\)",
|
||||||
|
r" \| BaseException: From g\(\)",
|
||||||
|
r"=* short test summary info =*",
|
||||||
|
]
|
||||||
|
if outer_chain in ("another", "from"):
|
||||||
|
match_lines.append(r"FAILED test_excgroup.py::test - IndexError")
|
||||||
|
else:
|
||||||
|
match_lines.append(
|
||||||
|
rf"FAILED test_excgroup.py::test - {pre_catch}BaseExceptionGroup: Oops \(2.*"
|
||||||
|
)
|
||||||
|
result.stdout.re_match_lines(match_lines)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
sys.version_info < (3, 11), reason="Native ExceptionGroup not implemented"
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
|
||||||
|
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
|
||||||
|
def test_native_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
|
||||||
|
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=True)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
|
||||||
|
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
|
||||||
|
def test_exceptiongroup(pytester: Pytester, outer_chain, inner_chain) -> None:
|
||||||
|
# with py>=3.11 does not depend on exceptiongroup, though there is a toxenv for it
|
||||||
|
pytest.importorskip("exceptiongroup")
|
||||||
|
_exceptiongroup_common(pytester, outer_chain, inner_chain, native=False)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
anyio[curio,trio]==3.6.1
|
anyio[curio,trio]==3.6.1
|
||||||
django==4.0.6
|
django==4.1
|
||||||
pytest-asyncio==0.18.3
|
pytest-asyncio==0.19.0
|
||||||
pytest-bdd==6.0.1
|
pytest-bdd==6.0.1
|
||||||
pytest-cov==3.0.0
|
pytest-cov==3.0.0
|
||||||
pytest-django==4.5.2
|
pytest-django==4.5.2
|
||||||
|
|
|
@ -1625,6 +1625,28 @@ def test_escaped_skipreason_issue3533(
|
||||||
snode.assert_attr(message="1 <> 2")
|
snode.assert_attr(message="1 <> 2")
|
||||||
|
|
||||||
|
|
||||||
|
def test_escaped_setup_teardown_error(
|
||||||
|
pytester: Pytester, run_and_parse: RunAndParse
|
||||||
|
) -> None:
|
||||||
|
pytester.makepyfile(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def my_setup():
|
||||||
|
raise Exception("error: \033[31mred\033[m")
|
||||||
|
|
||||||
|
def test_esc(my_setup):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
_, dom = run_and_parse()
|
||||||
|
node = dom.find_first_by_tag("testcase")
|
||||||
|
snode = node.find_first_by_tag("error")
|
||||||
|
assert "#x1B[31mred#x1B[m" in snode["message"]
|
||||||
|
assert "#x1B[31mred#x1B[m" in snode.text
|
||||||
|
|
||||||
|
|
||||||
@parametrize_families
|
@parametrize_families
|
||||||
def test_logging_passing_tests_disabled_does_not_log_test_output(
|
def test_logging_passing_tests_disabled_does_not_log_test_output(
|
||||||
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
pytester: Pytester, run_and_parse: RunAndParse, xunit_family: str
|
||||||
|
|
5
tox.ini
5
tox.ini
|
@ -17,6 +17,10 @@ envlist =
|
||||||
docs
|
docs
|
||||||
docs-checklinks
|
docs-checklinks
|
||||||
|
|
||||||
|
# checks that 3.11 native ExceptionGroup works with exceptiongroup
|
||||||
|
# not included in CI.
|
||||||
|
py311-exceptiongroup
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -46,6 +50,7 @@ setenv =
|
||||||
extras = testing
|
extras = testing
|
||||||
deps =
|
deps =
|
||||||
doctesting: PyYAML
|
doctesting: PyYAML
|
||||||
|
exceptiongroup: exceptiongroup>=1.0.0rc8
|
||||||
numpy: numpy>=1.19.4
|
numpy: numpy>=1.19.4
|
||||||
pexpect: pexpect>=4.8.0
|
pexpect: pexpect>=4.8.0
|
||||||
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
|
pluggymain: pluggy @ git+https://github.com/pytest-dev/pluggy.git
|
||||||
|
|
Loading…
Reference in New Issue