Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9c98762f5 | ||
|
|
8003fd23b9 | ||
|
|
8d605b9b26 | ||
|
|
14e0c3e105 | ||
|
|
45facc16c8 | ||
|
|
99fe887d7c | ||
|
|
8dbf9dc1aa | ||
|
|
baaee2148d | ||
|
|
f7d1ab870f | ||
|
|
b8201c280e | ||
|
|
1f0c50b475 | ||
|
|
da82e1853c | ||
|
|
a566eb9c70 | ||
|
|
d3971c30f4 | ||
|
|
780044b64a | ||
|
|
8354995abc | ||
|
|
8b8b1214f4 | ||
|
|
f854cf66f4 | ||
|
|
c475106f12 | ||
|
|
e7073afe6e |
2
AUTHORS
@@ -21,6 +21,7 @@ Anders Hovmöller
|
||||
Andras Mitzki
|
||||
Andras Tim
|
||||
Andrea Cimatoribus
|
||||
Andreas Motl
|
||||
Andreas Zeidler
|
||||
Andrey Paramonov
|
||||
Andrzej Klajnert
|
||||
@@ -56,6 +57,7 @@ Charles Cloud
|
||||
Charles Machalow
|
||||
Charnjit SiNGH (CCSJ)
|
||||
Chris Lamb
|
||||
Chris NeJame
|
||||
Christian Boelsen
|
||||
Christian Fetzer
|
||||
Christian Neumüller
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Added an ``__str__`` implementation to the :class:`~pytest.pytester.LineMatcher` class which is returned from ``pytester.run_pytest().stdout`` and similar. It returns the entire output, like the existing ``str()`` method.
|
||||
@@ -1 +0,0 @@
|
||||
Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS".
|
||||
@@ -1 +0,0 @@
|
||||
Fixed quadratic behavior and improved performance of collection of items using autouse fixtures and xunit fixtures.
|
||||
@@ -1,2 +0,0 @@
|
||||
pytest now warns about unraisable exceptions and unhandled thread exceptions that occur in tests on Python>=3.8.
|
||||
See :ref:`unraisable` for more information.
|
||||
@@ -1,5 +0,0 @@
|
||||
New :fixture:`pytester` fixture, which is identical to :fixture:`testdir` but its methods return :class:`pathlib.Path` when appropriate instead of ``py.path.local``.
|
||||
|
||||
This is part of the movement to use :class:`pathlib.Path` objects internally, in order to remove the dependency to ``py`` in the future.
|
||||
|
||||
Internally, the old :class:`Testdir <_pytest.pytester.Testdir>` is now a thin wrapper around :class:`Pytester <_pytest.pytester.Pytester>`, preserving the old interface.
|
||||
@@ -1 +0,0 @@
|
||||
Add more information and use cases about skipping doctests.
|
||||
@@ -1,18 +0,0 @@
|
||||
Directly constructing/calling the following classes/functions is now deprecated:
|
||||
|
||||
- ``_pytest.cacheprovider.Cache``
|
||||
- ``_pytest.cacheprovider.Cache.for_config()``
|
||||
- ``_pytest.cacheprovider.Cache.clear_cache()``
|
||||
- ``_pytest.cacheprovider.Cache.cache_dir_from_config()``
|
||||
- ``_pytest.capture.CaptureFixture``
|
||||
- ``_pytest.fixtures.FixtureRequest``
|
||||
- ``_pytest.fixtures.SubRequest``
|
||||
- ``_pytest.logging.LogCaptureFixture``
|
||||
- ``_pytest.pytester.Pytester``
|
||||
- ``_pytest.pytester.Testdir``
|
||||
- ``_pytest.recwarn.WarningsRecorder``
|
||||
- ``_pytest.recwarn.WarningsChecker``
|
||||
- ``_pytest.tmpdir.TempPathFactory``
|
||||
- ``_pytest.tmpdir.TempdirFactory``
|
||||
|
||||
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
||||
@@ -1,23 +0,0 @@
|
||||
It is now possible to construct a :class:`MonkeyPatch` object directly as ``pytest.MonkeyPatch()``,
|
||||
in cases when the :fixture:`monkeypatch` fixture cannot be used. Previously some users imported it
|
||||
from the private `_pytest.monkeypatch.MonkeyPatch` namespace.
|
||||
|
||||
The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions.
|
||||
The newly-exported types are:
|
||||
|
||||
- ``pytest.FixtureRequest`` for the :fixture:`request` fixture.
|
||||
- ``pytest.Cache`` for the :fixture:`cache` fixture.
|
||||
- ``pytest.CaptureFixture[str]`` for the :fixture:`capfd` and :fixture:`capsys` fixtures.
|
||||
- ``pytest.CaptureFixture[bytes]`` for the :fixture:`capfdbinary` and :fixture:`capsysbinary` fixtures.
|
||||
- ``pytest.LogCaptureFixture`` for the :fixture:`caplog` fixture.
|
||||
- ``pytest.Pytester`` for the :fixture:`pytester` fixture.
|
||||
- ``pytest.Testdir`` for the :fixture:`testdir` fixture.
|
||||
- ``pytest.TempdirFactory`` for the :fixture:`tmpdir_factory` fixture.
|
||||
- ``pytest.TempPathFactory`` for the :fixture:`tmp_path_factory` fixture.
|
||||
- ``pytest.MonkeyPatch`` for the :fixture:`monkeypatch` fixture.
|
||||
- ``pytest.WarningsRecorder`` for the :fixture:`recwarn` fixture.
|
||||
|
||||
Constructing them is not supported (except for `MonkeyPatch`); they are only meant for use in type annotations.
|
||||
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
|
||||
|
||||
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
|
||||
@@ -1 +0,0 @@
|
||||
When a comparison between :func:`namedtuple <collections.namedtuple>` instances of the same type fails, pytest now shows the differing field names (possibly nested) instead of their indexes.
|
||||
@@ -1,4 +0,0 @@
|
||||
The ``--strict`` command-line option has been deprecated, use ``--strict-markers`` instead.
|
||||
|
||||
We have plans to maybe in the future to reintroduce ``--strict`` and make it an encompassing flag for all strictness
|
||||
related options (``--strict-markers`` and ``--strict-config`` at the moment, more might be introduced in the future).
|
||||
@@ -1 +0,0 @@
|
||||
:meth:`Node.warn <_pytest.nodes.Node.warn>` now permits any subclass of :class:`Warning`, not just :class:`PytestWarning <pytest.PytestWarning>`.
|
||||
@@ -1,19 +0,0 @@
|
||||
A new hook was added, `pytest_markeval_namespace` which should return a dictionary.
|
||||
This dictionary will be used to augment the "global" variables available to evaluate skipif/xfail/xpass markers.
|
||||
|
||||
Pseudo example
|
||||
|
||||
``conftest.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def pytest_markeval_namespace():
|
||||
return {"color": "red"}
|
||||
|
||||
``test_func.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.skipif("color == 'blue'", reason="Color is not red")
|
||||
def test_func():
|
||||
assert False
|
||||
@@ -1 +0,0 @@
|
||||
Improved reporting when using ``--collected-only``. It will now show the number of collected tests in the summary stats.
|
||||
@@ -1,4 +0,0 @@
|
||||
Use strict equality comparison for non-numeric types in :func:`pytest.approx` instead of
|
||||
raising :class:`TypeError`.
|
||||
|
||||
This was the undocumented behavior before 3.7, but is now officially a supported feature.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed an issue where some files in packages are getting lost from ``--lf`` even though they contain tests that failed. Regressed in pytest 5.4.0.
|
||||
@@ -1 +0,0 @@
|
||||
Classes which should not be inherited from are now marked ``final class`` in the API reference.
|
||||
@@ -1 +0,0 @@
|
||||
The ``attrs`` dependency requirement is now >=19.2.0 instead of >=17.4.0.
|
||||
@@ -1 +0,0 @@
|
||||
pytest now supports python3.6+ only.
|
||||
@@ -1 +0,0 @@
|
||||
``_pytest.config.argparsing.Parser.addini()`` accepts explicit ``None`` and ``"string"``.
|
||||
@@ -1 +0,0 @@
|
||||
In pull request section, ask to commit after editing changelog and authors file.
|
||||
@@ -1 +0,0 @@
|
||||
Directories created by by :fixture:`tmp_path` and :fixture:`tmpdir` are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed a crash or hang in :meth:`pytester.spawn <_pytest.pytester.Pytester.spawn>` when the :mod:`readline` module is involved.
|
||||
@@ -1 +0,0 @@
|
||||
New ``--sw-skip`` argument which is a shorthand for ``--stepwise-skip``.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed handling of recursive symlinks when collecting tests.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed symlinked directories not being followed during collection. Regressed in pytest 6.1.0.
|
||||
@@ -1,3 +0,0 @@
|
||||
The ``@pytest.yield_fixture`` decorator/function is now deprecated. Use :func:`pytest.fixture` instead.
|
||||
|
||||
``yield_fixture`` has been an alias for ``fixture`` for a very long time, so can be search/replaced safely.
|
||||
@@ -1,8 +0,0 @@
|
||||
It is now possible to construct a :class:`~pytest.MonkeyPatch` object directly as ``pytest.MonkeyPatch()``,
|
||||
in cases when the :fixture:`monkeypatch` fixture cannot be used. Previously some users imported it
|
||||
from the private `_pytest.monkeypatch.MonkeyPatch` namespace.
|
||||
|
||||
Additionally, :meth:`MonkeyPatch.context <pytest.MonkeyPatch.context>` is now a classmethod,
|
||||
and can be used as ``with MonkeyPatch.context() as mp: ...``. This is the recommended way to use
|
||||
``MonkeyPatch`` directly, since unlike the ``monkeypatch`` fixture, an instance created directly
|
||||
is not ``undo()``-ed automatically.
|
||||
@@ -1,2 +0,0 @@
|
||||
`.pyc` files created by pytest's assertion rewriting now conform to the newer PEP-552 format on Python>=3.7.
|
||||
(These files are internal and only interpreted by pytest itself.)
|
||||
@@ -1 +0,0 @@
|
||||
Fixed only one doctest being collected when using ``pytest --doctest-modules path/to/an/__init__.py``.
|
||||
@@ -1 +0,0 @@
|
||||
Added ``'node_modules'`` to default value for :confval:`norecursedirs`.
|
||||
@@ -1 +0,0 @@
|
||||
:meth:`doClassCleanups <unittest.TestCase.doClassCleanups>` (introduced in :mod:`unittest` in Python and 3.8) is now called appropriately.
|
||||
@@ -6,6 +6,9 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-6.2.2
|
||||
release-6.2.1
|
||||
release-6.2.0
|
||||
release-6.1.2
|
||||
release-6.1.1
|
||||
release-6.1.0
|
||||
|
||||
76
doc/en/announce/release-6.2.0.rst
Normal file
@@ -0,0 +1,76 @@
|
||||
pytest-6.2.0
|
||||
=======================================
|
||||
|
||||
The pytest team is proud to announce the 6.2.0 release!
|
||||
|
||||
This release contains new features, improvements, bug fixes, and breaking changes, so users
|
||||
are encouraged to take a look at the CHANGELOG carefully:
|
||||
|
||||
https://docs.pytest.org/en/stable/changelog.html
|
||||
|
||||
For complete documentation, please visit:
|
||||
|
||||
https://docs.pytest.org/en/stable/
|
||||
|
||||
As usual, you can upgrade from PyPI via:
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
Thanks to all of the contributors to this release:
|
||||
|
||||
* Adam Johnson
|
||||
* Albert Villanova del Moral
|
||||
* Anthony Sottile
|
||||
* Anton
|
||||
* Ariel Pillemer
|
||||
* Bruno Oliveira
|
||||
* Charles Aracil
|
||||
* Christine M
|
||||
* Christine Mecklenborg
|
||||
* Cserna Zsolt
|
||||
* Dominic Mortlock
|
||||
* Emiel van de Laar
|
||||
* Florian Bruhin
|
||||
* Garvit Shubham
|
||||
* Gustavo Camargo
|
||||
* Hugo Martins
|
||||
* Hugo van Kemenade
|
||||
* Jakob van Santen
|
||||
* Josias Aurel
|
||||
* Jürgen Gmach
|
||||
* Karthikeyan Singaravelan
|
||||
* Katarzyna
|
||||
* Kyle Altendorf
|
||||
* Manuel Mariñez
|
||||
* Matthew Hughes
|
||||
* Matthias Gabriel
|
||||
* Max Voitko
|
||||
* Maximilian Cosmo Sitter
|
||||
* Mikhail Fesenko
|
||||
* Nimesh Vashistha
|
||||
* Pedro Algarvio
|
||||
* Petter Strandmark
|
||||
* Prakhar Gurunani
|
||||
* Prashant Sharma
|
||||
* Ran Benita
|
||||
* Ronny Pfannschmidt
|
||||
* Sanket Duthade
|
||||
* Shubham Adep
|
||||
* Simon K
|
||||
* Tanvi Mehta
|
||||
* Thomas Grainger
|
||||
* Tim Hoffmann
|
||||
* Vasilis Gerakaris
|
||||
* William Jamir Silva
|
||||
* Zac Hatfield-Dodds
|
||||
* crricks
|
||||
* dependabot[bot]
|
||||
* duthades
|
||||
* frankgerhardt
|
||||
* kwgchi
|
||||
* mickeypash
|
||||
* symonk
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
20
doc/en/announce/release-6.2.1.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
pytest-6.2.1
|
||||
=======================================
|
||||
|
||||
pytest 6.2.1 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
|
||||
|
||||
Thanks to all of the contributors to this release:
|
||||
|
||||
* Bruno Oliveira
|
||||
* Jakob van Santen
|
||||
* Ran Benita
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
21
doc/en/announce/release-6.2.2.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
pytest-6.2.2
|
||||
=======================================
|
||||
|
||||
pytest 6.2.2 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
|
||||
|
||||
Thanks to all of the contributors to this release:
|
||||
|
||||
* Adam Johnson
|
||||
* Bruno Oliveira
|
||||
* Chris NeJame
|
||||
* Ran Benita
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -158,6 +158,11 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
function invocation, created as a sub directory of the base temporary
|
||||
directory.
|
||||
|
||||
By default, a new base temporary directory is created each test session,
|
||||
and old bases are removed after 3 sessions, to aid in debugging. If
|
||||
``--basetemp`` is used then it is cleared each session. See :ref:`base
|
||||
temporary directory`.
|
||||
|
||||
The returned object is a `py.path.local`_ path object.
|
||||
|
||||
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
|
||||
@@ -167,6 +172,11 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
function invocation, created as a sub directory of the base temporary
|
||||
directory.
|
||||
|
||||
By default, a new base temporary directory is created each test session,
|
||||
and old bases are removed after 3 sessions, to aid in debugging. If
|
||||
``--basetemp`` is used then it is cleared each session. See :ref:`base
|
||||
temporary directory`.
|
||||
|
||||
The returned object is a :class:`pathlib.Path` object.
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,237 @@ with advance notice in the **Deprecations** section of releases.
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
pytest 6.2.2 (2021-01-25)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#8152 <https://github.com/pytest-dev/pytest/issues/8152>`_: Fixed "(<Skipped instance>)" being shown as a skip reason in the verbose test summary line when the reason is empty.
|
||||
|
||||
|
||||
- `#8249 <https://github.com/pytest-dev/pytest/issues/8249>`_: Fix the ``faulthandler`` plugin for occasions when running with ``twisted.logger`` and using ``pytest --capture=no``.
|
||||
|
||||
|
||||
pytest 6.2.1 (2020-12-15)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#7678 <https://github.com/pytest-dev/pytest/issues/7678>`_: Fixed bug where ``ImportPathMismatchError`` would be raised for files compiled in
|
||||
the host and loaded later from an UNC mounted path (Windows).
|
||||
|
||||
|
||||
- `#8132 <https://github.com/pytest-dev/pytest/issues/8132>`_: Fixed regression in ``approx``: in 6.2.0 ``approx`` no longer raises
|
||||
``TypeError`` when dealing with non-numeric types, falling back to normal comparison.
|
||||
Before 6.2.0, array types like tf.DeviceArray fell through to the scalar case,
|
||||
and happened to compare correctly to a scalar if they had only one element.
|
||||
After 6.2.0, these types began failing, because they inherited neither from
|
||||
standard Python number hierarchy nor from ``numpy.ndarray``.
|
||||
|
||||
``approx`` now converts arguments to ``numpy.ndarray`` if they expose the array
|
||||
protocol and are not scalars. This treats array-like objects like numpy arrays,
|
||||
regardless of size.
|
||||
|
||||
|
||||
pytest 6.2.0 (2020-12-12)
|
||||
=========================
|
||||
|
||||
Breaking Changes
|
||||
----------------
|
||||
|
||||
- `#7808 <https://github.com/pytest-dev/pytest/issues/7808>`_: pytest now supports python3.6+ only.
|
||||
|
||||
|
||||
|
||||
Deprecations
|
||||
------------
|
||||
|
||||
- `#7469 <https://github.com/pytest-dev/pytest/issues/7469>`_: Directly constructing/calling the following classes/functions is now deprecated:
|
||||
|
||||
- ``_pytest.cacheprovider.Cache``
|
||||
- ``_pytest.cacheprovider.Cache.for_config()``
|
||||
- ``_pytest.cacheprovider.Cache.clear_cache()``
|
||||
- ``_pytest.cacheprovider.Cache.cache_dir_from_config()``
|
||||
- ``_pytest.capture.CaptureFixture``
|
||||
- ``_pytest.fixtures.FixtureRequest``
|
||||
- ``_pytest.fixtures.SubRequest``
|
||||
- ``_pytest.logging.LogCaptureFixture``
|
||||
- ``_pytest.pytester.Pytester``
|
||||
- ``_pytest.pytester.Testdir``
|
||||
- ``_pytest.recwarn.WarningsRecorder``
|
||||
- ``_pytest.recwarn.WarningsChecker``
|
||||
- ``_pytest.tmpdir.TempPathFactory``
|
||||
- ``_pytest.tmpdir.TempdirFactory``
|
||||
|
||||
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
||||
|
||||
|
||||
- `#7530 <https://github.com/pytest-dev/pytest/issues/7530>`_: The ``--strict`` command-line option has been deprecated, use ``--strict-markers`` instead.
|
||||
|
||||
We have plans to maybe in the future to reintroduce ``--strict`` and make it an encompassing flag for all strictness
|
||||
related options (``--strict-markers`` and ``--strict-config`` at the moment, more might be introduced in the future).
|
||||
|
||||
|
||||
- `#7988 <https://github.com/pytest-dev/pytest/issues/7988>`_: The ``@pytest.yield_fixture`` decorator/function is now deprecated. Use :func:`pytest.fixture` instead.
|
||||
|
||||
``yield_fixture`` has been an alias for ``fixture`` for a very long time, so can be search/replaced safely.
|
||||
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#5299 <https://github.com/pytest-dev/pytest/issues/5299>`_: pytest now warns about unraisable exceptions and unhandled thread exceptions that occur in tests on Python>=3.8.
|
||||
See :ref:`unraisable` for more information.
|
||||
|
||||
|
||||
- `#7425 <https://github.com/pytest-dev/pytest/issues/7425>`_: New :fixture:`pytester` fixture, which is identical to :fixture:`testdir` but its methods return :class:`pathlib.Path` when appropriate instead of ``py.path.local``.
|
||||
|
||||
This is part of the movement to use :class:`pathlib.Path` objects internally, in order to remove the dependency to ``py`` in the future.
|
||||
|
||||
Internally, the old :class:`Testdir <_pytest.pytester.Testdir>` is now a thin wrapper around :class:`Pytester <_pytest.pytester.Pytester>`, preserving the old interface.
|
||||
|
||||
|
||||
- `#7695 <https://github.com/pytest-dev/pytest/issues/7695>`_: A new hook was added, `pytest_markeval_namespace` which should return a dictionary.
|
||||
This dictionary will be used to augment the "global" variables available to evaluate skipif/xfail/xpass markers.
|
||||
|
||||
Pseudo example
|
||||
|
||||
``conftest.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def pytest_markeval_namespace():
|
||||
return {"color": "red"}
|
||||
|
||||
``test_func.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.skipif("color == 'blue'", reason="Color is not red")
|
||||
def test_func():
|
||||
assert False
|
||||
|
||||
|
||||
- `#8006 <https://github.com/pytest-dev/pytest/issues/8006>`_: It is now possible to construct a :class:`~pytest.MonkeyPatch` object directly as ``pytest.MonkeyPatch()``,
|
||||
in cases when the :fixture:`monkeypatch` fixture cannot be used. Previously some users imported it
|
||||
from the private `_pytest.monkeypatch.MonkeyPatch` namespace.
|
||||
|
||||
Additionally, :meth:`MonkeyPatch.context <pytest.MonkeyPatch.context>` is now a classmethod,
|
||||
and can be used as ``with MonkeyPatch.context() as mp: ...``. This is the recommended way to use
|
||||
``MonkeyPatch`` directly, since unlike the ``monkeypatch`` fixture, an instance created directly
|
||||
is not ``undo()``-ed automatically.
|
||||
|
||||
|
||||
|
||||
Improvements
|
||||
------------
|
||||
|
||||
- `#1265 <https://github.com/pytest-dev/pytest/issues/1265>`_: Added an ``__str__`` implementation to the :class:`~pytest.pytester.LineMatcher` class which is returned from ``pytester.run_pytest().stdout`` and similar. It returns the entire output, like the existing ``str()`` method.
|
||||
|
||||
|
||||
- `#2044 <https://github.com/pytest-dev/pytest/issues/2044>`_: Verbose mode now shows the reason that a test was skipped in the test's terminal line after the "SKIPPED", "XFAIL" or "XPASS".
|
||||
|
||||
|
||||
- `#7469 <https://github.com/pytest-dev/pytest/issues/7469>`_ The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions.
|
||||
The newly-exported types are:
|
||||
|
||||
- ``pytest.FixtureRequest`` for the :fixture:`request` fixture.
|
||||
- ``pytest.Cache`` for the :fixture:`cache` fixture.
|
||||
- ``pytest.CaptureFixture[str]`` for the :fixture:`capfd` and :fixture:`capsys` fixtures.
|
||||
- ``pytest.CaptureFixture[bytes]`` for the :fixture:`capfdbinary` and :fixture:`capsysbinary` fixtures.
|
||||
- ``pytest.LogCaptureFixture`` for the :fixture:`caplog` fixture.
|
||||
- ``pytest.Pytester`` for the :fixture:`pytester` fixture.
|
||||
- ``pytest.Testdir`` for the :fixture:`testdir` fixture.
|
||||
- ``pytest.TempdirFactory`` for the :fixture:`tmpdir_factory` fixture.
|
||||
- ``pytest.TempPathFactory`` for the :fixture:`tmp_path_factory` fixture.
|
||||
- ``pytest.MonkeyPatch`` for the :fixture:`monkeypatch` fixture.
|
||||
- ``pytest.WarningsRecorder`` for the :fixture:`recwarn` fixture.
|
||||
|
||||
Constructing them is not supported (except for `MonkeyPatch`); they are only meant for use in type annotations.
|
||||
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
|
||||
|
||||
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
|
||||
|
||||
|
||||
- `#7527 <https://github.com/pytest-dev/pytest/issues/7527>`_: When a comparison between :func:`namedtuple <collections.namedtuple>` instances of the same type fails, pytest now shows the differing field names (possibly nested) instead of their indexes.
|
||||
|
||||
|
||||
- `#7615 <https://github.com/pytest-dev/pytest/issues/7615>`_: :meth:`Node.warn <_pytest.nodes.Node.warn>` now permits any subclass of :class:`Warning`, not just :class:`PytestWarning <pytest.PytestWarning>`.
|
||||
|
||||
|
||||
- `#7701 <https://github.com/pytest-dev/pytest/issues/7701>`_: Improved reporting when using ``--collected-only``. It will now show the number of collected tests in the summary stats.
|
||||
|
||||
|
||||
- `#7710 <https://github.com/pytest-dev/pytest/issues/7710>`_: Use strict equality comparison for non-numeric types in :func:`pytest.approx` instead of
|
||||
raising :class:`TypeError`.
|
||||
|
||||
This was the undocumented behavior before 3.7, but is now officially a supported feature.
|
||||
|
||||
|
||||
- `#7938 <https://github.com/pytest-dev/pytest/issues/7938>`_: New ``--sw-skip`` argument which is a shorthand for ``--stepwise-skip``.
|
||||
|
||||
|
||||
- `#8023 <https://github.com/pytest-dev/pytest/issues/8023>`_: Added ``'node_modules'`` to default value for :confval:`norecursedirs`.
|
||||
|
||||
|
||||
- `#8032 <https://github.com/pytest-dev/pytest/issues/8032>`_: :meth:`doClassCleanups <unittest.TestCase.doClassCleanups>` (introduced in :mod:`unittest` in Python and 3.8) is now called appropriately.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#4824 <https://github.com/pytest-dev/pytest/issues/4824>`_: Fixed quadratic behavior and improved performance of collection of items using autouse fixtures and xunit fixtures.
|
||||
|
||||
|
||||
- `#7758 <https://github.com/pytest-dev/pytest/issues/7758>`_: Fixed an issue where some files in packages are getting lost from ``--lf`` even though they contain tests that failed. Regressed in pytest 5.4.0.
|
||||
|
||||
|
||||
- `#7911 <https://github.com/pytest-dev/pytest/issues/7911>`_: Directories created by by :fixture:`tmp_path` and :fixture:`tmpdir` are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites.
|
||||
|
||||
|
||||
- `#7913 <https://github.com/pytest-dev/pytest/issues/7913>`_: Fixed a crash or hang in :meth:`pytester.spawn <_pytest.pytester.Pytester.spawn>` when the :mod:`readline` module is involved.
|
||||
|
||||
|
||||
- `#7951 <https://github.com/pytest-dev/pytest/issues/7951>`_: Fixed handling of recursive symlinks when collecting tests.
|
||||
|
||||
|
||||
- `#7981 <https://github.com/pytest-dev/pytest/issues/7981>`_: Fixed symlinked directories not being followed during collection. Regressed in pytest 6.1.0.
|
||||
|
||||
|
||||
- `#8016 <https://github.com/pytest-dev/pytest/issues/8016>`_: Fixed only one doctest being collected when using ``pytest --doctest-modules path/to/an/__init__.py``.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#7429 <https://github.com/pytest-dev/pytest/issues/7429>`_: Add more information and use cases about skipping doctests.
|
||||
|
||||
|
||||
- `#7780 <https://github.com/pytest-dev/pytest/issues/7780>`_: Classes which should not be inherited from are now marked ``final class`` in the API reference.
|
||||
|
||||
|
||||
- `#7872 <https://github.com/pytest-dev/pytest/issues/7872>`_: ``_pytest.config.argparsing.Parser.addini()`` accepts explicit ``None`` and ``"string"``.
|
||||
|
||||
|
||||
- `#7878 <https://github.com/pytest-dev/pytest/issues/7878>`_: In pull request section, ask to commit after editing changelog and authors file.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#7802 <https://github.com/pytest-dev/pytest/issues/7802>`_: The ``attrs`` dependency requirement is now >=19.2.0 instead of >=17.4.0.
|
||||
|
||||
|
||||
- `#8014 <https://github.com/pytest-dev/pytest/issues/8014>`_: `.pyc` files created by pytest's assertion rewriting now conform to the newer PEP-552 format on Python>=3.7.
|
||||
(These files are internal and only interpreted by pytest itself.)
|
||||
|
||||
|
||||
pytest 6.1.2 (2020-10-28)
|
||||
=========================
|
||||
|
||||
|
||||
132
doc/en/example/fixtures/fixture_availability.svg
Normal file
@@ -0,0 +1,132 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="572" height="542">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class, circle.module, circle.package {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class, text.module, text.package {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line, path {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- main scope -->
|
||||
<circle class="package" r="270" cx="286" cy="271" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 26,271 A 260 260 0 0 1 546 271" id="testp"/>
|
||||
</defs>
|
||||
<text class="package">
|
||||
<textPath href="#testp" startOffset="50%">tests</textPath>
|
||||
</text>
|
||||
|
||||
<!-- subpackage -->
|
||||
<circle class="package" r="140" cx="186" cy="271" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 56,271 A 130 130 0 0 1 316 271" id="subpackage"/>
|
||||
</defs>
|
||||
<text class="package">
|
||||
<textPath href="#subpackage" startOffset="50%">subpackage</textPath>
|
||||
</text>
|
||||
|
||||
<!-- test_subpackage.py -->
|
||||
<circle class="module" r="90" cx="186" cy="311" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 106,311 A 80 80 0 0 1 266 311" id="testSubpackage"/>
|
||||
</defs>
|
||||
<text class="module">
|
||||
<textPath href="#testSubpackage" startOffset="50%">test_subpackage.py</textPath>
|
||||
</text>
|
||||
<!-- innermost -->
|
||||
<line x1="186" x2="186" y1="271" y2="351"/>
|
||||
<!-- mid -->
|
||||
<path d="M 186 351 L 136 351 L 106 331 L 106 196" />
|
||||
<!-- order -->
|
||||
<path d="M 186 351 L 256 351 L 316 291 L 316 136" />
|
||||
<!-- top -->
|
||||
<path d="M 186 351 L 186 391 L 231 436 L 331 436" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="186" cy="271" />
|
||||
<text x="186" y="271">innermost</text>
|
||||
<rect class="test" width="110" height="50" x="131" y="326" />
|
||||
<text x="186" y="351">test_order</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="126" cy="196" />
|
||||
<text x="126" y="196">mid</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testSubpackageOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="90" cx="186" cy="311" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="96" cy="311" mask="url(#testSubpackageOrderMask)"/>
|
||||
<text class="module" x="96" y="311">1</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="subpackageOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="140" cx="186" cy="271" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="46" cy="271" mask="url(#subpackageOrderMask)"/>
|
||||
<text class="module" x="46" y="271">2</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testsOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="270" cx="286" cy="271" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="16" cy="271" mask="url(#testsOrderMask)"/>
|
||||
<text class="module" x="16" y="271">3</text>
|
||||
|
||||
<!-- test_top.py -->
|
||||
<circle class="module" r="85" cx="441" cy="271" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 366,271 A 75 75 0 0 1 516 271" id="testTop"/>
|
||||
</defs>
|
||||
<text class="module">
|
||||
<textPath href="#testTop" startOffset="50%">test_top.py</textPath>
|
||||
</text>
|
||||
<!-- innermost -->
|
||||
<line x1="441" x2="441" y1="306" y2="236"/>
|
||||
<!-- order -->
|
||||
<path d="M 441 306 L 376 306 L 346 276 L 346 136" />
|
||||
<!-- top -->
|
||||
<path d="M 441 306 L 441 411 L 411 436 L 331 436" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="441" cy="236" />
|
||||
<text x="441" y="236">innermost</text>
|
||||
<rect class="test" width="110" height="50" x="386" y="281" />
|
||||
<text x="441" y="306">test_order</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testTopOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="85" cx="441" cy="271" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="526" cy="271" mask="url(#testTopOrderMask)"/>
|
||||
<text class="module" x="526" y="271">1</text>
|
||||
<!-- scope order number -->
|
||||
<circle class="module" r="15" cx="556" cy="271" mask="url(#testsOrderMask)"/>
|
||||
<text class="module" x="556" y="271">2</text>
|
||||
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="331" cy="436" />
|
||||
<text x="331" y="436">top</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="331" cy="136" />
|
||||
<text x="331" y="136">order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
142
doc/en/example/fixtures/fixture_availability_plugins.svg
Normal file
@@ -0,0 +1,142 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="587" height="382">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
alignment-baseline: center;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class, circle.module, circle.package, circle.plugin {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class, text.module, text.package, text.plugin {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line, path {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- plugin_a.py scope -->
|
||||
<circle class="plugin" r="85" cx="486" cy="86" />
|
||||
<!-- plugin name -->
|
||||
<defs>
|
||||
<path d="M 411,86 A 75 75 0 0 1 561 86" id="pluginA"/>
|
||||
</defs>
|
||||
<text class="plugin">
|
||||
<textPath href="#pluginA" startOffset="50%">plugin_a</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="pluginAOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="85" cx="486" cy="86" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="571" cy="86" mask="url(#pluginAOrderMask)"/>
|
||||
<text class="module" x="571" y="86">4</text>
|
||||
|
||||
<!-- plugin_b.py scope -->
|
||||
<circle class="plugin" r="85" cx="486" cy="296" />
|
||||
<!-- plugin name -->
|
||||
<defs>
|
||||
<path d="M 411,296 A 75 75 0 0 1 561 296" id="pluginB"/>
|
||||
</defs>
|
||||
<text class="plugin">
|
||||
<textPath href="#pluginB" startOffset="50%">plugin_b</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="pluginBOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="85" cx="486" cy="296" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="571" cy="296" mask="url(#pluginBOrderMask)"/>
|
||||
<text class="module" x="571" y="296">4</text>
|
||||
|
||||
<!-- main scope -->
|
||||
<circle class="package" r="190" cx="191" cy="191" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 11,191 A 180 180 0 0 1 371 191" id="testp"/>
|
||||
</defs>
|
||||
<text class="package">
|
||||
<textPath href="#testp" startOffset="50%">tests</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="mainOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="190" cx="191" cy="191" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="381" cy="191" mask="url(#mainOrderMask)"/>
|
||||
<text class="module" x="381" y="191">3</text>
|
||||
|
||||
<!-- subpackage -->
|
||||
<circle class="package" r="140" cx="191" cy="231" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 61,231 A 130 130 0 0 1 321 231" id="subpackage"/>
|
||||
</defs>
|
||||
<text class="package">
|
||||
<textPath href="#subpackage" startOffset="50%">subpackage</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="subpackageOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="140" cx="191" cy="231" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="331" cy="231" mask="url(#subpackageOrderMask)"/>
|
||||
<text class="module" x="331" y="231">2</text>
|
||||
|
||||
<!-- test_subpackage.py -->
|
||||
<circle class="module" r="90" cx="191" cy="271" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 111,271 A 80 80 0 0 1 271 271" id="testSubpackage"/>
|
||||
</defs>
|
||||
<text class="module">
|
||||
<textPath href="#testSubpackage" startOffset="50%">test_subpackage.py</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testSubpackageOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="90" cx="191" cy="271" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="281" cy="271" mask="url(#testSubpackageOrderMask)"/>
|
||||
<text class="module" x="281" y="271">1</text>
|
||||
|
||||
<!-- innermost -->
|
||||
<line x1="191" x2="191" y1="231" y2="311"/>
|
||||
<!-- mid -->
|
||||
<path d="M 191 306 L 101 306 L 91 296 L 91 156 L 101 146 L 191 146" />
|
||||
<!-- order -->
|
||||
<path d="M 191 316 L 91 316 L 81 306 L 81 61 L 91 51 L 191 51" />
|
||||
<!-- a_fix -->
|
||||
<path d="M 191 306 L 291 306 L 301 296 L 301 96 L 311 86 L 486 86" />
|
||||
<!-- b_fix -->
|
||||
<path d="M 191 316 L 316 316 L 336 296 L 486 296" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="191" cy="231" />
|
||||
<text x="191" y="231">inner</text>
|
||||
<rect class="test" width="110" height="50" x="136" y="286" />
|
||||
<text x="191" y="311">test_order</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="191" cy="146" />
|
||||
<text x="191" y="146">mid</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="191" cy="51" />
|
||||
<text x="191" y="51">order</text>
|
||||
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="486" cy="86" />
|
||||
<text x="486" y="86">a_fix</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="486" cy="296" />
|
||||
<text x="486" y="296">b_fix</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -1,38 +0,0 @@
|
||||
import pytest
|
||||
|
||||
# fixtures documentation order example
|
||||
order = []
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def s1():
|
||||
order.append("s1")
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def m1():
|
||||
order.append("m1")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def f1(f3):
|
||||
order.append("f1")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def f3():
|
||||
order.append("f3")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def a1():
|
||||
order.append("a1")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def f2():
|
||||
order.append("f2")
|
||||
|
||||
|
||||
def test_order(f1, m1, f2, s1):
|
||||
assert order == ["s1", "m1", "a1", "f3", "f1", "f2"]
|
||||
45
doc/en/example/fixtures/test_fixtures_order_autouse.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def a(order):
|
||||
order.append("a")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def b(a, order):
|
||||
order.append("b")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def c(b, order):
|
||||
order.append("c")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def d(b, order):
|
||||
order.append("d")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def e(d, order):
|
||||
order.append("e")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def f(e, order):
|
||||
order.append("f")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def g(f, c, order):
|
||||
order.append("g")
|
||||
|
||||
|
||||
def test_order_and_g(g, order):
|
||||
assert order == ["a", "b", "c", "d", "e", "f", "g"]
|
||||
64
doc/en/example/fixtures/test_fixtures_order_autouse.svg
Normal file
@@ -0,0 +1,64 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="252" height="682">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
path, line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
rect.autouse {
|
||||
fill: #ca7f3d;
|
||||
}
|
||||
</style>
|
||||
<path d="M126,586 L26,506 L26,236" />
|
||||
<path d="M226,446 L226,236 L126,166" />
|
||||
<line x1="126" x2="126" y1="656" y2="516" />
|
||||
<line x1="126" x2="226" y1="516" y2="446" />
|
||||
<line x1="226" x2="126" y1="446" y2="376" />
|
||||
<line x1="126" x2="126" y1="376" y2="166" />
|
||||
<line x1="26" x2="126" y1="236" y2="166" />
|
||||
<line x1="126" x2="126" y1="166" y2="26" />
|
||||
<line x1="126" x2="126" y1="96" y2="26" />
|
||||
<rect class="autouse" width="251" height="40" x="0" y="286" />
|
||||
<text x="126" y="306">autouse</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="126" cy="26" />
|
||||
<text x="126" y="26">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="96" />
|
||||
<text x="126" y="96">a</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="166" />
|
||||
<text x="126" y="166">b</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="26" cy="236" />
|
||||
<text x="26" y="236">c</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="376" />
|
||||
<text x="126" y="376">d</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="226" cy="446" />
|
||||
<text x="226" y="446">e</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="516" />
|
||||
<text x="126" y="516">f</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="586" />
|
||||
<text x="126" y="586">g</text>
|
||||
<rect class="test" width="110" height="50" x="71" y="631" />
|
||||
<text x="126" y="656">test_order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,31 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture(scope="class", autouse=True)
|
||||
def c1(order):
|
||||
order.append("c1")
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def c2(order):
|
||||
order.append("c2")
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def c3(order, c1):
|
||||
order.append("c3")
|
||||
|
||||
|
||||
class TestClassWithC1Request:
|
||||
def test_order(self, order, c1, c3):
|
||||
assert order == ["c1", "c3"]
|
||||
|
||||
|
||||
class TestClassWithoutC1Request:
|
||||
def test_order(self, order, c2):
|
||||
assert order == ["c1", "c2"]
|
||||
@@ -0,0 +1,76 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="862" height="402">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
}
|
||||
rect.autouse {
|
||||
fill: #ca7f3d;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- TestWithC1Request -->
|
||||
<circle class="class" r="200" cx="221" cy="201" />
|
||||
<line x1="221" x2="221" y1="61" y2="316"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="221" cy="61" />
|
||||
<text x="221" y="61">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="221" cy="131" />
|
||||
<text x="221" y="131">c1</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="221" cy="271" />
|
||||
<text x="221" y="271">c3</text>
|
||||
<rect class="test" width="110" height="50" x="166" y="316" />
|
||||
<text x="221" y="341">test_order</text>
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M31,201 A 190 190 0 0 1 411 201" id="testClassWith"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testClassWith" startOffset="50%">TestWithC1Request</textPath>
|
||||
</text>
|
||||
|
||||
<!-- TestWithoutC1Request -->
|
||||
<circle class="class" r="200" cx="641" cy="201" />
|
||||
<line x1="641" x2="641" y1="61" y2="316"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="641" cy="61" />
|
||||
<text x="641" y="61">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="641" cy="131" />
|
||||
<text x="641" y="131">c1</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="641" cy="271" />
|
||||
<text x="641" y="271">c2</text>
|
||||
<rect class="test" width="110" height="50" x="586" y="316" />
|
||||
<text x="641" y="341">test_order</text>
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M451,201 A 190 190 0 0 1 831 201" id="testClassWithout"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testClassWithout" startOffset="50%">TestWithoutC1Request</textPath>
|
||||
</text>
|
||||
|
||||
<rect class="autouse" width="862" height="40" x="1" y="181" />
|
||||
<rect width="10" height="100" class="autouse" x="426" y="151" />
|
||||
<text x="431" y="201">autouse</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def c1(order):
|
||||
order.append("c1")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def c2(order):
|
||||
order.append("c2")
|
||||
|
||||
|
||||
class TestClassWithAutouse:
|
||||
@pytest.fixture(autouse=True)
|
||||
def c3(self, order, c2):
|
||||
order.append("c3")
|
||||
|
||||
def test_req(self, order, c1):
|
||||
assert order == ["c2", "c3", "c1"]
|
||||
|
||||
def test_no_req(self, order):
|
||||
assert order == ["c2", "c3"]
|
||||
|
||||
|
||||
class TestClassWithoutAutouse:
|
||||
def test_req(self, order, c1):
|
||||
assert order == ["c1"]
|
||||
|
||||
def test_no_req(self, order):
|
||||
assert order == []
|
||||
@@ -0,0 +1,100 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="862" height="502">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
}
|
||||
rect.autouse {
|
||||
fill: #ca7f3d;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- TestWithAutouse -->
|
||||
<circle class="class" r="250" cx="251" cy="251" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M11,251 A 240 240 0 0 1 491 251" id="testClassWith"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testClassWith" startOffset="50%">TestWithAutouse</textPath>
|
||||
</text>
|
||||
<mask id="autouseScope">
|
||||
<circle fill="white" r="249" cx="251" cy="251" />
|
||||
</mask>
|
||||
|
||||
<!-- TestWithAutouse.test_req -->
|
||||
<line x1="176" x2="176" y1="76" y2="426"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="176" cy="76" />
|
||||
<text x="176" y="76">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="176" cy="146" />
|
||||
<text x="176" y="146">c2</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="176" cy="216" />
|
||||
<text x="176" y="216">c3</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="176" cy="356" />
|
||||
<text x="176" y="356">c1</text>
|
||||
<rect class="test" width="100" height="50" x="126" y="401" />
|
||||
<text x="176" y="426">test_req</text>
|
||||
|
||||
<!-- TestWithAutouse.test_no_req -->
|
||||
<line x1="326" x2="326" y1="76" y2="346"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="326" cy="76" />
|
||||
<text x="326" y="76">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="326" cy="146" />
|
||||
<text x="326" y="146">c2</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="326" cy="216" />
|
||||
<text x="326" y="216">c3</text>
|
||||
<rect class="test" width="120" height="50" x="266" y="331" />
|
||||
<text x="326" y="356">test_no_req</text>
|
||||
|
||||
<rect class="autouse" width="500" height="40" x="1" y="266" mask="url(#autouseScope)"/>
|
||||
<text x="261" y="286">autouse</text>
|
||||
|
||||
<!-- TestWithoutAutouse -->
|
||||
<circle class="class" r="170" cx="691" cy="251" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 531,251 A 160 160 0 0 1 851 251" id="testClassWithout"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testClassWithout" startOffset="50%">TestWithoutAutouse</textPath>
|
||||
</text>
|
||||
|
||||
<!-- TestWithoutAutouse.test_req -->
|
||||
<line x1="616" x2="616" y1="181" y2="321"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="616" cy="181" />
|
||||
<text x="616" y="181">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="616" cy="251" />
|
||||
<text x="616" y="251">c1</text>
|
||||
<rect class="test" width="100" height="50" x="566" y="296" />
|
||||
<text x="616" y="321">test_req</text>
|
||||
|
||||
<!-- TestWithoutAutouse.test_no_req -->
|
||||
<line x1="766" x2="766" y1="181" y2="251"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="766" cy="181" />
|
||||
<text x="766" y="181">order</text>
|
||||
<rect class="test" width="120" height="50" x="706" y="226" />
|
||||
<text x="766" y="251">test_no_req</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
45
doc/en/example/fixtures/test_fixtures_order_dependencies.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def a(order):
|
||||
order.append("a")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def b(a, order):
|
||||
order.append("b")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def c(a, b, order):
|
||||
order.append("c")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def d(c, b, order):
|
||||
order.append("d")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def e(d, b, order):
|
||||
order.append("e")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def f(e, order):
|
||||
order.append("f")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def g(f, c, order):
|
||||
order.append("g")
|
||||
|
||||
|
||||
def test_order(g, order):
|
||||
assert order == ["a", "b", "c", "d", "e", "f", "g"]
|
||||
60
doc/en/example/fixtures/test_fixtures_order_dependencies.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="252" height="612">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
path, line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
<path d="M126,516 L26,436 L26,236" />
|
||||
<path d="M226,376 L226,236 L126,166" />
|
||||
<line x1="126" x2="126" y1="586" y2="446" />
|
||||
<line x1="126" x2="226" y1="446" y2="376" />
|
||||
<line x1="226" x2="126" y1="376" y2="306" />
|
||||
<line x1="126" x2="26" y1="306" y2="236" />
|
||||
<line x1="126" x2="126" y1="306" y2="166" />
|
||||
<line x1="26" x2="126" y1="236" y2="166" />
|
||||
<line x1="126" x2="126" y1="166" y2="26" />
|
||||
<line x1="126" x2="126" y1="96" y2="26" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="126" cy="26" />
|
||||
<text x="126" y="26">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="96" />
|
||||
<text x="126" y="96">a</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="166" />
|
||||
<text x="126" y="166">b</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="26" cy="236" />
|
||||
<text x="26" y="236">c</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="306" />
|
||||
<text x="126" y="306">d</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="226" cy="376" />
|
||||
<text x="226" y="376">e</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="446" />
|
||||
<text x="126" y="446">f</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="516" />
|
||||
<text x="126" y="516">g</text>
|
||||
<rect class="test" width="110" height="50" x="71" y="561" />
|
||||
<text x="126" y="586">test_order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,51 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="112" height="612">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
path, line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
<line x1="56" x2="56" y1="611" y2="26" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="56" cy="26" />
|
||||
<text x="56" y="26">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="96" />
|
||||
<text x="56" y="96">a</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="166" />
|
||||
<text x="56" y="166">b</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="236" />
|
||||
<text x="56" y="236">c</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="306" />
|
||||
<text x="56" y="306">d</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="376" />
|
||||
<text x="56" y="376">e</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="446" />
|
||||
<text x="56" y="446">f</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="56" cy="516" />
|
||||
<text x="56" y="516">g</text>
|
||||
<rect class="test" width="110" height="50" x="1" y="561" />
|
||||
<text x="56" y="586">test_order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,60 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="252" height="542">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
path, line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
<path d="M126,446 L26,376 L26,236" />
|
||||
<path d="M226,306 L126,236 L126,166" />
|
||||
<line x1="126" x2="126" y1="516" y2="446" />
|
||||
<line x1="226" x2="226" y1="376" y2="306" />
|
||||
<line x1="226" x2="226" y1="306" y2="236" />
|
||||
<line x1="226" x2="126" y1="236" y2="166" />
|
||||
<line x1="126" x2="226" y1="446" y2="376" />
|
||||
<line x1="26" x2="126" y1="236" y2="166" />
|
||||
<line x1="126" x2="126" y1="166" y2="96" />
|
||||
<line x1="126" x2="126" y1="96" y2="26" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="126" cy="26" />
|
||||
<text x="126" y="26">order</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="96" />
|
||||
<text x="126" y="96">a</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="166" />
|
||||
<text x="126" y="166">b</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="26" cy="236" />
|
||||
<text x="26" y="236">c</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="226" cy="236" />
|
||||
<text x="226" y="236">d</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="226" cy="306" />
|
||||
<text x="226" y="306">e</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="226" cy="376" />
|
||||
<text x="226" y="376">f</text>
|
||||
<ellipse class="fixture" rx="25" ry="25" cx="126" cy="446" />
|
||||
<text x="126" y="446">g</text>
|
||||
<rect class="test" width="110" height="50" x="71" y="491" />
|
||||
<text x="126" y="516">test_order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
36
doc/en/example/fixtures/test_fixtures_order_scope.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def func(order):
|
||||
order.append("function")
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def cls(order):
|
||||
order.append("class")
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mod(order):
|
||||
order.append("module")
|
||||
|
||||
|
||||
@pytest.fixture(scope="package")
|
||||
def pack(order):
|
||||
order.append("package")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def sess(order):
|
||||
order.append("session")
|
||||
|
||||
|
||||
class TestClass:
|
||||
def test_order(self, func, cls, mod, pack, sess, order):
|
||||
assert order == ["session", "package", "module", "class", "function"]
|
||||
55
doc/en/example/fixtures/test_fixtures_order_scope.svg
Normal file
@@ -0,0 +1,55 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="262" height="537">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
}
|
||||
</style>
|
||||
<!-- TestClass -->
|
||||
<circle class="class" r="130" cx="131" cy="406" />
|
||||
<line x1="131" x2="131" y1="21" y2="446"/>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="26" />
|
||||
<text x="131" y="26">order</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="96" />
|
||||
<text x="131" y="96">sess</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="166" />
|
||||
<text x="131" y="166">pack</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="236" />
|
||||
<text x="131" y="236">mod</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="306" />
|
||||
<text x="131" y="306">cls</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="131" cy="376" />
|
||||
<text x="131" y="376">func</text>
|
||||
<rect class="test" width="110" height="50" x="76" y="421" />
|
||||
<text x="131" y="446">test_order</text>
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M131,526 A 120 120 0 0 1 136 286" id="testClass"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testClass" startOffset="50%">TestClass</textPath>
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,29 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order():
|
||||
return []
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def outer(order, inner):
|
||||
order.append("outer")
|
||||
|
||||
|
||||
class TestOne:
|
||||
@pytest.fixture
|
||||
def inner(self, order):
|
||||
order.append("one")
|
||||
|
||||
def test_order(self, order, outer):
|
||||
assert order == ["one", "outer"]
|
||||
|
||||
|
||||
class TestTwo:
|
||||
@pytest.fixture
|
||||
def inner(self, order):
|
||||
order.append("two")
|
||||
|
||||
def test_order(self, order, outer):
|
||||
assert order == ["two", "outer"]
|
||||
@@ -0,0 +1,115 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="562" height="532">
|
||||
<style>
|
||||
text {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
fill: #062886;
|
||||
font-size: medium;
|
||||
}
|
||||
ellipse.fixture, rect.test {
|
||||
fill: #eeffcc;
|
||||
stroke: #007020;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.fixture {
|
||||
color: #06287e;
|
||||
}
|
||||
circle.class {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
circle.module {
|
||||
fill: #c3e0ec;
|
||||
stroke: #0e84b5;
|
||||
stroke-width: 2;
|
||||
}
|
||||
text.class, text.module {
|
||||
fill: #0e84b5;
|
||||
}
|
||||
line, path {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
</style>
|
||||
<!-- main scope -->
|
||||
<circle class="module" r="265" cx="281" cy="266" />
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 26,266 A 255 255 0 0 1 536 266" id="testModule"/>
|
||||
</defs>
|
||||
<text class="module">
|
||||
<textPath href="#testModule" startOffset="50%">test_fixtures_request_different_scope.py</textPath>
|
||||
</text>
|
||||
|
||||
<!-- TestOne -->
|
||||
<circle class="class" r="100" cx="141" cy="266" />
|
||||
<!-- inner -->
|
||||
<line x1="141" x2="141" y1="231" y2="301"/>
|
||||
<!-- order -->
|
||||
<path d="M 141 296 L 201 296 L 211 286 L 211 146 L 221 136 L 281 136" />
|
||||
<!-- outer -->
|
||||
<path d="M 141 306 L 201 306 L 211 316 L 211 386 L 221 396 L 281 396" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="141" cy="231" />
|
||||
<text x="141" y="231">inner</text>
|
||||
<rect class="test" width="110" height="50" x="86" y="276" />
|
||||
<text x="141" y="301">test_order</text>
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 51,266 A 90 90 0 0 1 231 266" id="testOne"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testOne" startOffset="50%">TestOne</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testOneOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="100" cx="141" cy="266" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="41" cy="266" mask="url(#testOneOrderMask)"/>
|
||||
<text class="module" x="41" y="266">1</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testMainOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="265" cx="281" cy="266" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="16" cy="266" mask="url(#testMainOrderMask)"/>
|
||||
<text class="module" x="16" y="266">2</text>
|
||||
|
||||
<!-- TestTwo -->
|
||||
<circle class="class" r="100" cx="421" cy="266" />
|
||||
<!-- inner -->
|
||||
<line x1="421" x2="421" y1="231" y2="301"/>
|
||||
<!-- order -->
|
||||
<path d="M 421 296 L 361 296 L 351 286 L 351 146 L 341 136 L 281 136" />
|
||||
<!-- outer -->
|
||||
<path d="M 421 306 L 361 306 L 351 316 L 351 386 L 341 396 L 281 396" />
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="421" cy="231" />
|
||||
<text x="421" y="231">inner</text>
|
||||
<rect class="test" width="110" height="50" x="366" y="276" />
|
||||
<text x="421" y="301">test_order</text>
|
||||
<!-- scope name -->
|
||||
<defs>
|
||||
<path d="M 331,266 A 90 90 0 0 1 511 266" id="testTwo"/>
|
||||
</defs>
|
||||
<text class="class">
|
||||
<textPath href="#testTwo" startOffset="50%">TestTwo</textPath>
|
||||
</text>
|
||||
<!-- scope order number -->
|
||||
<mask id="testTwoOrderMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="white"/>
|
||||
<circle fill="black" stroke="white" stroke-width="2" r="100" cx="421" cy="266" />
|
||||
</mask>
|
||||
<circle class="module" r="15" cx="521" cy="266" mask="url(#testTwoOrderMask)"/>
|
||||
<text class="module" x="521" y="266">1</text>
|
||||
<!-- scope order number -->
|
||||
<circle class="module" r="15" cx="546" cy="266" mask="url(#testMainOrderMask)"/>
|
||||
<text class="module" x="546" y="266">2</text>
|
||||
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="281" cy="396" />
|
||||
<text x="281" y="396">outer</text>
|
||||
<ellipse class="fixture" rx="50" ry="25" cx="281" cy="136" />
|
||||
<text x="281" y="136">order</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -102,4 +102,4 @@ interesting to just look at the collection tree:
|
||||
<YamlItem hello>
|
||||
<YamlItem ok>
|
||||
|
||||
========================== 2 tests found in 0.12s ===========================
|
||||
======================== 2 tests collected in 0.12s ========================
|
||||
|
||||
@@ -175,7 +175,7 @@ objects, they are still using the default pytest representation:
|
||||
<Function test_timedistance_v3[forward]>
|
||||
<Function test_timedistance_v3[backward]>
|
||||
|
||||
========================== 8 tests found in 0.12s ===========================
|
||||
======================== 8 tests collected in 0.12s ========================
|
||||
|
||||
In ``test_timedistance_v3``, we used ``pytest.param`` to specify the test IDs
|
||||
together with the actual data, instead of listing them separately.
|
||||
@@ -252,7 +252,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
|
||||
<Function test_demo1[advanced]>
|
||||
<Function test_demo2[advanced]>
|
||||
|
||||
========================== 4 tests found in 0.12s ===========================
|
||||
======================== 4 tests collected in 0.12s ========================
|
||||
|
||||
Note that we told ``metafunc.parametrize()`` that your scenario values
|
||||
should be considered class-scoped. With pytest-2.3 this leads to a
|
||||
@@ -328,7 +328,7 @@ Let's first see how it looks like at collection time:
|
||||
<Function test_db_initialized[d1]>
|
||||
<Function test_db_initialized[d2]>
|
||||
|
||||
========================== 2/2 tests found in 0.12s ===========================
|
||||
======================== 2 tests collected in 0.12s ========================
|
||||
|
||||
And then when we run the test:
|
||||
|
||||
@@ -637,13 +637,13 @@ Then run ``pytest`` with verbose mode and with only the ``basic`` marker:
|
||||
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python
|
||||
cachedir: $PYTHON_PREFIX/.pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR
|
||||
collecting ... collected 14 items / 11 deselected / 3 selected
|
||||
collecting ... collected 24 items / 21 deselected / 3 selected
|
||||
|
||||
test_pytest_param_example.py::test_eval[1+7-8] PASSED [ 33%]
|
||||
test_pytest_param_example.py::test_eval[basic_2+4] PASSED [ 66%]
|
||||
test_pytest_param_example.py::test_eval[basic_6*9] XFAIL [100%]
|
||||
|
||||
=============== 2 passed, 11 deselected, 1 xfailed in 0.12s ================
|
||||
=============== 2 passed, 21 deselected, 1 xfailed in 0.12s ================
|
||||
|
||||
As the result:
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ The test collection would look like this:
|
||||
<Function simple_check>
|
||||
<Function complex_check>
|
||||
|
||||
========================== 2 tests found in 0.12s ===========================
|
||||
======================== 2 tests collected in 0.12s ========================
|
||||
|
||||
You can check for multiple glob patterns by adding a space between the patterns:
|
||||
|
||||
@@ -220,7 +220,7 @@ You can always peek at the collection tree without running tests like this:
|
||||
<Function test_method>
|
||||
<Function test_anothermethod>
|
||||
|
||||
========================== 3 tests found in 0.12s ===========================
|
||||
======================== 3 tests collected in 0.12s ========================
|
||||
|
||||
.. _customizing-test-collection:
|
||||
|
||||
@@ -296,7 +296,7 @@ file will be left out:
|
||||
rootdir: $REGENDOC_TMPDIR, configfile: pytest.ini
|
||||
collected 0 items
|
||||
|
||||
========================== no tests found in 0.12s ===========================
|
||||
======================= no tests collected in 0.12s ========================
|
||||
|
||||
It's also possible to ignore files based on Unix shell-style wildcards by adding
|
||||
patterns to :globalvar:`collect_ignore_glob`.
|
||||
|
||||
@@ -446,7 +446,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
|
||||
|
||||
def test_reinterpret_fails_with_print_for_the_fun_of_it(self):
|
||||
items = [1, 2, 3]
|
||||
print("items is {!r}".format(items))
|
||||
print(f"items is {items!r}")
|
||||
> a, b = items.pop()
|
||||
E TypeError: cannot unpack non-iterable int object
|
||||
|
||||
|
||||
1691
doc/en/fixture.rst
@@ -28,7 +28,7 @@ Install ``pytest``
|
||||
.. code-block:: bash
|
||||
|
||||
$ pytest --version
|
||||
pytest 6.1.2
|
||||
pytest 6.2.2
|
||||
|
||||
.. _`simpletest`:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
.. sidebar:: Next Open Trainings
|
||||
|
||||
- `Professional testing with Python <https://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, via Python Academy, February 1-3 2021, Leipzig (Germany) and remote.
|
||||
- `Professional testing with Python <https://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, via Python Academy, February 1-3 2021, remote and Leipzig (Germany). **Early-bird discount available until January 15th**.
|
||||
|
||||
Also see `previous talks and blogposts <talks.html>`_.
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. module:: pytest
|
||||
|
||||
This page contains the full reference to pytest's API.
|
||||
|
||||
.. contents::
|
||||
@@ -1749,7 +1751,8 @@ All the command-line flags can be obtained by running ``pytest --help``::
|
||||
failures.
|
||||
--sw, --stepwise exit on test failure and continue from last failing
|
||||
test next time
|
||||
--stepwise-skip ignore the first failing test but stop on the next
|
||||
--sw-skip, --stepwise-skip
|
||||
ignore the first failing test but stop on the next
|
||||
failing test
|
||||
|
||||
reporting:
|
||||
@@ -1791,9 +1794,9 @@ All the command-line flags can be obtained by running ``pytest --help``::
|
||||
--maxfail=num exit after first num failures or errors.
|
||||
--strict-config any warnings encountered while parsing the `pytest`
|
||||
section of the configuration file raise errors.
|
||||
--strict-markers, --strict
|
||||
markers not registered in the `markers` section of
|
||||
--strict-markers markers not registered in the `markers` section of
|
||||
the configuration file raise errors.
|
||||
--strict (deprecated) alias to --strict-markers.
|
||||
-c file load configuration from `file` instead of trying to
|
||||
locate one of the implicit configuration files.
|
||||
--continue-on-collection-errors
|
||||
|
||||
@@ -61,7 +61,7 @@ Running this would result in a passed test except for the last
|
||||
> assert 0
|
||||
E assert 0
|
||||
|
||||
test_tmp_path.py:13: AssertionError
|
||||
test_tmp_path.py:11: AssertionError
|
||||
========================= short test summary info ==========================
|
||||
FAILED test_tmp_path.py::test_create_file - assert 0
|
||||
============================ 1 failed in 0.12s =============================
|
||||
@@ -129,7 +129,7 @@ Running this would result in a passed test except for the last
|
||||
> assert 0
|
||||
E assert 0
|
||||
|
||||
test_tmpdir.py:9: AssertionError
|
||||
test_tmpdir.py:6: AssertionError
|
||||
========================= short test summary info ==========================
|
||||
FAILED test_tmpdir.py::test_create_file - assert 0
|
||||
============================ 1 failed in 0.12s =============================
|
||||
|
||||
@@ -449,13 +449,7 @@ Additionally it is possible to copy examples for an example folder before runnin
|
||||
|
||||
test_example.py .. [100%]
|
||||
|
||||
============================= warnings summary =============================
|
||||
test_example.py::test_plugin
|
||||
$REGENDOC_TMPDIR/test_example.py:4: PytestExperimentalApiWarning: testdir.copy_example is an experimental api that may change over time
|
||||
testdir.copy_example("test_example.py")
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/warnings.html
|
||||
======================= 2 passed, 1 warning in 0.12s =======================
|
||||
============================ 2 passed in 0.12s =============================
|
||||
|
||||
For more information about the result object that ``runpytest()`` returns, and
|
||||
the methods that it provides please check out the :py:class:`RunResult
|
||||
|
||||
@@ -26,6 +26,8 @@ classifiers =
|
||||
Topic :: Utilities
|
||||
keywords = test, unittest
|
||||
project_urls =
|
||||
Changelog=https://docs.pytest.org/en/stable/changelog.html
|
||||
Twitter=https://twitter.com/pytestdotorg
|
||||
Source=https://github.com/pytest-dev/pytest
|
||||
Tracker=https://github.com/pytest-dev/pytest/issues
|
||||
|
||||
|
||||
@@ -69,7 +69,12 @@ class FaultHandlerHooks:
|
||||
@staticmethod
|
||||
def _get_stderr_fileno():
|
||||
try:
|
||||
return sys.stderr.fileno()
|
||||
fileno = sys.stderr.fileno()
|
||||
# The Twisted Logger will return an invalid file descriptor since it is not backed
|
||||
# by an FD. So, let's also forward this to the same code path as with pytest-xdist.
|
||||
if fileno == -1:
|
||||
raise AttributeError()
|
||||
return fileno
|
||||
except (AttributeError, io.UnsupportedOperation):
|
||||
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.
|
||||
# https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors
|
||||
|
||||
@@ -38,7 +38,7 @@ class OutcomeException(BaseException):
|
||||
self.pytrace = pytrace
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.msg:
|
||||
if self.msg is not None:
|
||||
return self.msg
|
||||
return f"<{self.__class__.__name__} instance>"
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ def import_path(
|
||||
module_file = module_file[: -(len(os.path.sep + "__init__.py"))]
|
||||
|
||||
try:
|
||||
is_same = os.path.samefile(str(path), module_file)
|
||||
is_same = _is_same(str(path), module_file)
|
||||
except FileNotFoundError:
|
||||
is_same = False
|
||||
|
||||
@@ -553,6 +553,20 @@ def import_path(
|
||||
return mod
|
||||
|
||||
|
||||
# Implement a special _is_same function on Windows which returns True if the two filenames
|
||||
# compare equal, to circumvent os.path.samefile returning False for mounts in UNC (#7678).
|
||||
if sys.platform.startswith("win"):
|
||||
|
||||
def _is_same(f1: str, f2: str) -> bool:
|
||||
return Path(f1) == Path(f2) or os.path.samefile(f1, f2)
|
||||
|
||||
|
||||
else:
|
||||
|
||||
def _is_same(f1: str, f2: str) -> bool:
|
||||
return os.path.samefile(f1, f2)
|
||||
|
||||
|
||||
def resolve_package_path(path: Path) -> Optional[Path]:
|
||||
"""Return the Python package path by looking for the last
|
||||
directory upwards which still contains an __init__.py.
|
||||
|
||||
@@ -15,9 +15,14 @@ from typing import overload
|
||||
from typing import Pattern
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TypeVar
|
||||
from typing import Union
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from numpy import ndarray
|
||||
|
||||
|
||||
import _pytest._code
|
||||
from _pytest.compat import final
|
||||
from _pytest.compat import STRING_TYPES
|
||||
@@ -232,10 +237,11 @@ class ApproxScalar(ApproxBase):
|
||||
def __eq__(self, actual) -> bool:
|
||||
"""Return whether the given value is equal to the expected value
|
||||
within the pre-specified tolerance."""
|
||||
if _is_numpy_array(actual):
|
||||
asarray = _as_numpy_array(actual)
|
||||
if asarray is not None:
|
||||
# Call ``__eq__()`` manually to prevent infinite-recursion with
|
||||
# numpy<1.13. See #3748.
|
||||
return all(self.__eq__(a) for a in actual.flat)
|
||||
return all(self.__eq__(a) for a in asarray.flat)
|
||||
|
||||
# Short-circuit exact equality.
|
||||
if actual == self.expected:
|
||||
@@ -521,6 +527,7 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
|
||||
elif isinstance(expected, Mapping):
|
||||
cls = ApproxMapping
|
||||
elif _is_numpy_array(expected):
|
||||
expected = _as_numpy_array(expected)
|
||||
cls = ApproxNumpy
|
||||
elif (
|
||||
isinstance(expected, Iterable)
|
||||
@@ -536,16 +543,30 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
|
||||
|
||||
|
||||
def _is_numpy_array(obj: object) -> bool:
|
||||
"""Return true if the given object is a numpy array.
|
||||
"""
|
||||
Return true if the given object is implicitly convertible to ndarray,
|
||||
and numpy is already imported.
|
||||
"""
|
||||
return _as_numpy_array(obj) is not None
|
||||
|
||||
A special effort is made to avoid importing numpy unless it's really necessary.
|
||||
|
||||
def _as_numpy_array(obj: object) -> Optional["ndarray"]:
|
||||
"""
|
||||
Return an ndarray if the given object is implicitly convertible to ndarray,
|
||||
and numpy is already imported, otherwise None.
|
||||
"""
|
||||
import sys
|
||||
|
||||
np: Any = sys.modules.get("numpy")
|
||||
if np is not None:
|
||||
return isinstance(obj, np.ndarray)
|
||||
return False
|
||||
# avoid infinite recursion on numpy scalars, which have __array__
|
||||
if np.isscalar(obj):
|
||||
return None
|
||||
elif isinstance(obj, np.ndarray):
|
||||
return obj
|
||||
elif hasattr(obj, "__array__") or hasattr("obj", "__array_interface__"):
|
||||
return np.asarray(obj)
|
||||
return None
|
||||
|
||||
|
||||
# builtin pytest.raises helper
|
||||
|
||||
@@ -1400,4 +1400,6 @@ def _get_raw_skip_reason(report: TestReport) -> str:
|
||||
_, _, reason = report.longrepr
|
||||
if reason.startswith("Skipped: "):
|
||||
reason = reason[len("Skipped: ") :]
|
||||
elif reason == "Skipped":
|
||||
reason = ""
|
||||
return reason
|
||||
|
||||
@@ -447,6 +447,36 @@ class TestApprox:
|
||||
assert a12 != approx(a21)
|
||||
assert a21 != approx(a12)
|
||||
|
||||
def test_numpy_array_protocol(self):
|
||||
"""
|
||||
array-like objects such as tensorflow's DeviceArray are handled like ndarray.
|
||||
See issue #8132
|
||||
"""
|
||||
np = pytest.importorskip("numpy")
|
||||
|
||||
class DeviceArray:
|
||||
def __init__(self, value, size):
|
||||
self.value = value
|
||||
self.size = size
|
||||
|
||||
def __array__(self):
|
||||
return self.value * np.ones(self.size)
|
||||
|
||||
class DeviceScalar:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __array__(self):
|
||||
return np.array(self.value)
|
||||
|
||||
expected = 1
|
||||
actual = 1 + 1e-6
|
||||
assert approx(expected) == DeviceArray(actual, size=1)
|
||||
assert approx(expected) == DeviceArray(actual, size=2)
|
||||
assert approx(expected) == DeviceScalar(actual)
|
||||
assert approx(DeviceScalar(expected)) == actual
|
||||
assert approx(DeviceScalar(expected)) == DeviceScalar(actual)
|
||||
|
||||
def test_doctests(self, mocked_doctest_runner) -> None:
|
||||
import doctest
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import io
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
@@ -135,3 +136,27 @@ def test_already_initialized(faulthandler_timeout: int, pytester: Pytester) -> N
|
||||
result.stdout.no_fnmatch_line(warning_line)
|
||||
result.stdout.fnmatch_lines("*1 passed*")
|
||||
assert result.ret == 0
|
||||
|
||||
|
||||
def test_get_stderr_fileno_invalid_fd() -> None:
|
||||
"""Test for faulthandler being able to handle invalid file descriptors for stderr (#8249)."""
|
||||
from _pytest.faulthandler import FaultHandlerHooks
|
||||
|
||||
class StdErrWrapper(io.StringIO):
|
||||
"""
|
||||
Mimic ``twisted.logger.LoggingFile`` to simulate returning an invalid file descriptor.
|
||||
|
||||
https://github.com/twisted/twisted/blob/twisted-20.3.0/src/twisted/logger/_io.py#L132-L139
|
||||
"""
|
||||
|
||||
def fileno(self):
|
||||
return -1
|
||||
|
||||
wrapper = StdErrWrapper()
|
||||
|
||||
with pytest.MonkeyPatch.context() as mp:
|
||||
mp.setattr("sys.stderr", wrapper)
|
||||
|
||||
# Even when the stderr wrapper signals an invalid file descriptor,
|
||||
# ``_get_stderr_fileno()`` should return the real one.
|
||||
assert FaultHandlerHooks._get_stderr_fileno() == 2
|
||||
|
||||
@@ -7,6 +7,7 @@ from textwrap import dedent
|
||||
import py
|
||||
|
||||
import pytest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from _pytest.pathlib import bestrelpath
|
||||
from _pytest.pathlib import commonpath
|
||||
from _pytest.pathlib import ensure_deletable
|
||||
@@ -414,3 +415,23 @@ def test_visit_ignores_errors(tmpdir) -> None:
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows only")
|
||||
def test_samefile_false_negatives(tmp_path: Path, monkeypatch: MonkeyPatch) -> None:
|
||||
"""
|
||||
import_file() should not raise ImportPathMismatchError if the paths are exactly
|
||||
equal on Windows. It seems directories mounted as UNC paths make os.path.samefile
|
||||
return False, even when they are clearly equal.
|
||||
"""
|
||||
module_path = tmp_path.joinpath("my_module.py")
|
||||
module_path.write_text("def foo(): return 42")
|
||||
monkeypatch.syspath_prepend(tmp_path)
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
# Forcibly make os.path.samefile() return False here to ensure we are comparing
|
||||
# the paths too. Using a context to narrow the patch as much as possible given
|
||||
# this is an important system function.
|
||||
mp.setattr(os.path, "samefile", lambda x, y: False)
|
||||
module = import_path(module_path)
|
||||
assert getattr(module, "foo")() == 42
|
||||
|
||||
@@ -366,6 +366,26 @@ class TestTerminal:
|
||||
@pytest.mark.xfail(reason="")
|
||||
def test_4():
|
||||
assert False
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_5():
|
||||
pass
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_6():
|
||||
pass
|
||||
|
||||
def test_7():
|
||||
pytest.skip()
|
||||
|
||||
def test_8():
|
||||
pytest.skip("888 is great")
|
||||
|
||||
def test_9():
|
||||
pytest.xfail()
|
||||
|
||||
def test_10():
|
||||
pytest.xfail("It's 🕙 o'clock")
|
||||
"""
|
||||
)
|
||||
result = pytester.runpytest("-v")
|
||||
@@ -375,6 +395,12 @@ class TestTerminal:
|
||||
"test_verbose_skip_reason.py::test_2 XPASS (456) *",
|
||||
"test_verbose_skip_reason.py::test_3 XFAIL (789) *",
|
||||
"test_verbose_skip_reason.py::test_4 XFAIL *",
|
||||
"test_verbose_skip_reason.py::test_5 SKIPPED (unconditional skip) *",
|
||||
"test_verbose_skip_reason.py::test_6 XPASS *",
|
||||
"test_verbose_skip_reason.py::test_7 SKIPPED *",
|
||||
"test_verbose_skip_reason.py::test_8 SKIPPED (888 is great) *",
|
||||
"test_verbose_skip_reason.py::test_9 XFAIL *",
|
||||
"test_verbose_skip_reason.py::test_10 XFAIL (It's 🕙 o'clock) *",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||