diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 22f3ac862..e7784b931 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,232 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 4.1.0 (2019-01-05) +========================= + +Removals +-------- + +- `#2169 `_: ``pytest.mark.parametrize``: in previous versions, errors raised by id functions were suppressed and changed into warnings. Now the exceptions are propagated, along with a pytest message informing the node, parameter value and index where the exception occurred. + + +- `#3078 `_: Remove legacy internal warnings system: ``config.warn``, ``Node.warn``. The ``pytest_logwarning`` now issues a warning when implemented. + + See our `docs `__ on information on how to update your code. + + +- `#3079 `_: Removed support for yield tests - they are fundamentally broken because they don't support fixtures properly since collection and test execution were separated. + + See our `docs `__ on information on how to update your code. + + +- `#3082 `_: Removed support for applying marks directly to values in ``@pytest.mark.parametrize``. Use ``pytest.param`` instead. + + See our `docs `__ on information on how to update your code. + + +- `#3083 `_: Removed ``Metafunc.addcall``. This was the predecessor mechanism to ``@pytest.mark.parametrize``. + + See our `docs `__ on information on how to update your code. + + +- `#3085 `_: Removed support for passing strings to ``pytest.main``. Now, always pass a list of strings instead. + + See our `docs `__ on information on how to update your code. + + +- `#3086 `_: ``[pytest]`` section in **setup.cfg** files is not longer supported, use ``[tool:pytest]`` instead. ``setup.cfg`` files + are meant for use with ``distutils``, and a section named ``pytest`` has notoriously been a source of conflicts and bugs. + + Note that for **pytest.ini** and **tox.ini** files the section remains ``[pytest]``. + + +- `#3616 `_: Removed the deprecated compat properties for ``node.Class/Function/Module`` - use ``pytest.Class/Function/Module`` now. + + See our `docs `__ on information on how to update your code. + + +- `#4421 `_: Removed the implementation of the ``pytest_namespace`` hook. + + See our `docs `__ on information on how to update your code. + + +- `#4489 `_: Removed ``request.cached_setup``. This was the predecessor mechanism to modern fixtures. + + See our `docs `__ on information on how to update your code. + + +- `#4535 `_: Removed the deprecated ``PyCollector.makeitem`` method. This method was made public by mistake a long time ago. + + +- `#4543 `_: Removed support to define fixtures using the ``pytest_funcarg__`` prefix. Use the ``@pytest.fixture`` decorator instead. + + See our `docs `__ on information on how to update your code. + + +- `#4545 `_: Calling fixtures directly is now always an error instead of a warning. + + See our `docs `__ on information on how to update your code. + + +- `#4546 `_: Remove ``Node.get_marker(name)`` the return value was not usable for more than a existence check. + + Use ``Node.get_closest_marker(name)`` as a replacement. + + +- `#4547 `_: The deprecated ``record_xml_property`` fixture has been removed, use the more generic ``record_property`` instead. + + See our `docs `__ for more information. + + +- `#4548 `_: An error is now raised if the ``pytest_plugins`` variable is defined in a non-top-level ``conftest.py`` file (i.e., not residing in the ``rootdir``). + + See our `docs `__ for more information. + + +- `#891 `_: Remove ``testfunction.markername`` attributes - use ``Node.iter_markers(name=None)`` to iterate them. + + + +Deprecations +------------ + +- `#3050 `_: Deprecated the ``pytest.config`` global. + + See https://docs.pytest.org/en/latest/deprecations.html#pytest-config-global for rationale. + + +- `#3974 `_: Passing the ``message`` parameter of ``pytest.raises`` now issues a ``DeprecationWarning``. + + It is a common mistake to think this parameter will match the exception message, while in fact + it only serves to provide a custom message in case the ``pytest.raises`` check fails. To avoid this + mistake and because it is believed to be little used, pytest is deprecating it without providing + an alternative for the moment. + + If you have concerns about this, please comment on `issue #3974 `__. + + +- `#4435 `_: Deprecated ``raises(..., 'code(as_a_string)')`` and ``warns(..., 'code(as_a_string)')``. + + See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec for rationale and examples. + + + +Features +-------- + +- `#3191 `_: A warning is now issued when assertions are made for ``None``. + + This is a common source of confusion among new users, which write: + + .. code-block:: python + + assert mocked_object.assert_called_with(3, 4, 5, key="value") + + When they should write: + + .. code-block:: python + + mocked_object.assert_called_with(3, 4, 5, key="value") + + Because the ``assert_called_with`` method of mock objects already executes an assertion. + + This warning will not be issued when ``None`` is explicitly checked. An assertion like: + + .. code-block:: python + + assert variable is None + + will not issue the warning. + + +- `#3632 `_: Richer equality comparison introspection on ``AssertionError`` for objects created using `attrs `__ or `dataclasses `_ (Python 3.7+, `backported to 3.6 `__). + + +- `#4278 `_: ``CACHEDIR.TAG`` files are now created inside cache directories. + + Those files are part of the `Cache Directory Tagging Standard `__, and can + be used by backup or synchronization programs to identify pytest's cache directory as such. + + +- `#4292 `_: ``pytest.outcomes.Exit`` is derived from ``SystemExit`` instead of ``KeyboardInterrupt``. This allows us to better handle ``pdb`` exiting. + + +- `#4371 `_: Updated the ``--collect-only`` option to display test descriptions when ran using ``--verbose``. + + +- `#4386 `_: Restructured ``ExceptionInfo`` object construction and ensure incomplete instances have a ``repr``/``str``. + + +- `#4416 `_: pdb: added support for keyword arguments with ``pdb.set_trace``. + + It handles ``header`` similar to Python 3.7 does it, and forwards any + other keyword arguments to the ``Pdb`` constructor. + + This allows for ``__import__("pdb").set_trace(skip=["foo.*"])``. + + +- `#4483 `_: Added ini parameter ``junit_duration_report`` to optionally report test call durations, excluding setup and teardown times. + + The JUnit XML specification and the default pytest behavior is to include setup and teardown times in the test duration + report. You can include just the call durations instead (excluding setup and teardown) by adding this to your ``pytest.ini`` file: + + .. code-block:: ini + + [pytest] + junit_duration_report = call + + +- `#4532 `_: ``-ra`` now will show errors and failures last, instead of as the first items in the summary. + + This makes it easier to obtain a list of errors and failures to run tests selectively. + + +- `#4599 `_: ``pytest.importorskip`` now supports a ``reason`` parameter, which will be shown when the + requested module cannot be imported. + + + +Bug Fixes +--------- + +- `#3532 `_: ``-p`` now accepts its argument without a space between the value, for example ``-pmyplugin``. + + +- `#4327 `_: ``approx`` again works with more generic containers, more precisely instances of ``Iterable`` and ``Sized`` instead of more restrictive ``Sequence``. + + +- `#4397 `_: Ensure that node ids are printable. + + +- `#4435 `_: Fixed ``raises(..., 'code(string)')`` frame filename. + + +- `#4458 `_: Display actual test ids in ``--collect-only``. + + + +Improved Documentation +---------------------- + +- `#4557 `_: Markers example documentation page updated to support latest pytest version. + + +- `#4558 `_: Update cache documentation example to correctly show cache hit and miss. + + +- `#4580 `_: Improved detailed summary report documentation. + + + +Trivial/Internal Changes +------------------------ + +- `#4447 `_: Changed the deprecation type of ``--result-log`` to ``PytestDeprecationWarning``. + + It was decided to remove this feature at the next major revision. + + pytest 4.0.2 (2018-12-13) ========================= @@ -1022,7 +1248,7 @@ Features - Revamp the internals of the ``pytest.mark`` implementation with correct per node handling which fixes a number of long standing bugs caused by the old design. This introduces new ``Node.iter_markers(name)`` and - ``Node.get_closest_mark(name)`` APIs. Users are **strongly encouraged** to + ``Node.get_closest_marker(name)`` APIs. Users are **strongly encouraged** to read the `reasons for the revamp in the docs `_, or jump over to details about `updating existing code to use the new APIs @@ -1757,7 +1983,7 @@ Bug Fixes Trivial/Internal Changes ------------------------ -- pytest now depends on `attrs `_ for internal +- pytest now depends on `attrs `__ for internal structures to ease code maintainability. (`#2641 `_) diff --git a/LICENSE b/LICENSE index 629df45ac..477af2d2e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2004-2017 Holger Krekel and others +Copyright (c) 2004-2019 Holger Krekel and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.rst b/README.rst index 7454893a2..bd7f1daa6 100644 --- a/README.rst +++ b/README.rst @@ -111,7 +111,7 @@ Consult the `Changelog `__ pag License ------- -Copyright Holger Krekel and others, 2004-2018. +Copyright Holger Krekel and others, 2004-2019. Distributed under the terms of the `MIT`_ license, pytest is free and open source software. diff --git a/changelog/2169.removal.rst b/changelog/2169.removal.rst deleted file mode 100644 index 272ddbdfb..000000000 --- a/changelog/2169.removal.rst +++ /dev/null @@ -1 +0,0 @@ -``pytest.mark.parametrize``: in previous versions, errors raised by id functions were suppressed and changed into warnings. Now the exceptions are propagated, along with a pytest message informing the node, parameter value and index where the exception occurred. diff --git a/changelog/3050.deprecation.rst b/changelog/3050.deprecation.rst deleted file mode 100644 index fce5979d6..000000000 --- a/changelog/3050.deprecation.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecated the ``pytest.config`` global. - -See https://docs.pytest.org/en/latest/deprecations.html#pytest-config-global for rationale. diff --git a/changelog/3078.removal.rst b/changelog/3078.removal.rst deleted file mode 100644 index 8f90811c3..000000000 --- a/changelog/3078.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove legacy internal warnings system: ``config.warn``, ``Node.warn``. The ``pytest_logwarning`` now issues a warning when implemented. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3079.removal.rst b/changelog/3079.removal.rst deleted file mode 100644 index cb2265ff3..000000000 --- a/changelog/3079.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed support for yield tests - they are fundamentally broken because they don't support fixtures properly since collection and test execution were separated. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3082.removal.rst b/changelog/3082.removal.rst deleted file mode 100644 index 750f097bc..000000000 --- a/changelog/3082.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed support for applying marks directly to values in ``@pytest.mark.parametrize``. Use ``pytest.param`` instead. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3083.removal.rst b/changelog/3083.removal.rst deleted file mode 100644 index 74d268a4e..000000000 --- a/changelog/3083.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed ``Metafunc.addcall``. This was the predecessor mechanism to ``@pytest.mark.parametrize``. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3085.removal.rst b/changelog/3085.removal.rst deleted file mode 100644 index 67ba04c28..000000000 --- a/changelog/3085.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed support for passing strings to ``pytest.main``. Now, always pass a list of strings instead. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3086.removal.rst b/changelog/3086.removal.rst deleted file mode 100644 index 3974aa500..000000000 --- a/changelog/3086.removal.rst +++ /dev/null @@ -1,4 +0,0 @@ -``[pytest]`` section in **setup.cfg** files is not longer supported, use ``[tool:pytest]`` instead. ``setup.cfg`` files -are meant for use with ``distutils``, and a section named ``pytest`` has notoriously been a source of conflicts and bugs. - -Note that for **pytest.ini** and **tox.ini** files the section remains ``[pytest]``. diff --git a/changelog/3191.feature.rst b/changelog/3191.feature.rst deleted file mode 100644 index dbf1c8304..000000000 --- a/changelog/3191.feature.rst +++ /dev/null @@ -1,23 +0,0 @@ -A warning is now issued when assertions are made for ``None``. - -This is a common source of confusion among new users, which write: - -.. code-block:: python - - assert mocked_object.assert_called_with(3, 4, 5, key="value") - -When they should write: - -.. code-block:: python - - mocked_object.assert_called_with(3, 4, 5, key="value") - -Because the ``assert_called_with`` method of mock objects already executes an assertion. - -This warning will not be issued when ``None`` is explicitly checked. An assertion like: - -.. code-block:: python - - assert variable is None - -will not issue the warning. diff --git a/changelog/3532.bugfix.rst b/changelog/3532.bugfix.rst deleted file mode 100644 index 8651458d9..000000000 --- a/changelog/3532.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -``-p`` now accepts its argument without a space between the value, for example ``-pmyplugin``. diff --git a/changelog/3616.removal.rst b/changelog/3616.removal.rst deleted file mode 100644 index 5d8c9134e..000000000 --- a/changelog/3616.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed the deprecated compat properties for ``node.Class/Function/Module`` - use ``pytest.Class/Function/Module`` now. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/3632.feature.rst b/changelog/3632.feature.rst deleted file mode 100644 index cb1d93750..000000000 --- a/changelog/3632.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Richer equality comparison introspection on ``AssertionError`` for objects created using `attrs `_ or `dataclasses `_ (Python 3.7+, `backported to 3.6 `_). diff --git a/changelog/3974.deprecation.rst b/changelog/3974.deprecation.rst deleted file mode 100644 index 070ecb8b2..000000000 --- a/changelog/3974.deprecation.rst +++ /dev/null @@ -1,8 +0,0 @@ -Passing the ``message`` parameter of ``pytest.raises`` now issues a ``DeprecationWarning``. - -It is a common mistake to think this parameter will match the exception message, while in fact -it only serves to provide a custom message in case the ``pytest.raises`` check fails. To avoid this -mistake and because it is believed to be little used, pytest is deprecating it without providing -an alternative for the moment. - -If you have concerns about this, please comment on `issue #3974 `__. diff --git a/changelog/4278.feature.rst b/changelog/4278.feature.rst deleted file mode 100644 index 332e64572..000000000 --- a/changelog/4278.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -``CACHEDIR.TAG`` files are now created inside cache directories. - -Those files are part of the `Cache Directory Tagging Standard `__, and can -be used by backup or synchronization programs to identify pytest's cache directory as such. diff --git a/changelog/4292.feature.rst b/changelog/4292.feature.rst deleted file mode 100644 index 760a27783..000000000 --- a/changelog/4292.feature.rst +++ /dev/null @@ -1 +0,0 @@ -``pytest.outcomes.Exit`` is derived from ``SystemExit`` instead of ``KeyboardInterrupt``. This allows us to better handle ``pdb`` exiting. diff --git a/changelog/4327.bugfix.rst b/changelog/4327.bugfix.rst deleted file mode 100644 index 72223af4e..000000000 --- a/changelog/4327.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -``approx`` again works with more generic containers, more precisely instances of ``Iterable`` and ``Sized`` instead of more restrictive ``Sequence``. diff --git a/changelog/4371.feature.rst b/changelog/4371.feature.rst deleted file mode 100644 index f205fc269..000000000 --- a/changelog/4371.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Updated the ``--collect-only`` option to display test descriptions when ran using ``--verbose``. diff --git a/changelog/4386.feature.rst b/changelog/4386.feature.rst deleted file mode 100644 index 5133a39a7..000000000 --- a/changelog/4386.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Restructured ``ExceptionInfo`` object construction and ensure incomplete instances have a ``repr``/``str``. diff --git a/changelog/4397.bugfix.rst b/changelog/4397.bugfix.rst deleted file mode 100644 index d1a5bd3ba..000000000 --- a/changelog/4397.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure that node ids are printable. diff --git a/changelog/4416.feature.rst b/changelog/4416.feature.rst deleted file mode 100644 index 949e7c25a..000000000 --- a/changelog/4416.feature.rst +++ /dev/null @@ -1,6 +0,0 @@ -pdb: added support for keyword arguments with ``pdb.set_trace``. - -It handles ``header`` similar to Python 3.7 does it, and forwards any -other keyword arguments to the ``Pdb`` constructor. - -This allows for ``__import__("pdb").set_trace(skip=["foo.*"])``. diff --git a/changelog/4421.removal.rst b/changelog/4421.removal.rst deleted file mode 100644 index 4bebd5c19..000000000 --- a/changelog/4421.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed the implementation of the ``pytest_namespace`` hook. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/4435.bugfix.rst b/changelog/4435.bugfix.rst deleted file mode 100644 index 36ace1fab..000000000 --- a/changelog/4435.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed ``raises(..., 'code(string)')`` frame filename. diff --git a/changelog/4435.deprecation.rst b/changelog/4435.deprecation.rst deleted file mode 100644 index 6815c1776..000000000 --- a/changelog/4435.deprecation.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecated ``raises(..., 'code(as_a_string)')`` and ``warns(..., 'code(as_a_string)')``. - -See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec for rationale and examples. diff --git a/changelog/4447.trivial.rst b/changelog/4447.trivial.rst deleted file mode 100644 index 884ccd4c9..000000000 --- a/changelog/4447.trivial.rst +++ /dev/null @@ -1,3 +0,0 @@ -Changed the deprecation type of ``--result-log`` to ``PytestDeprecationWarning``. - -It was decided to remove this feature at the next major revision. diff --git a/changelog/4458.bugfix.rst b/changelog/4458.bugfix.rst deleted file mode 100644 index 891fb9a2f..000000000 --- a/changelog/4458.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Display actual test ids in ``--collect-only``. diff --git a/changelog/4483.feature.rst b/changelog/4483.feature.rst deleted file mode 100644 index 9b3018707..000000000 --- a/changelog/4483.feature.rst +++ /dev/null @@ -1,9 +0,0 @@ -Added ini parameter ``junit_duration_report`` to optionally report test call durations, excluding setup and teardown times. - -The JUnit XML specification and the default pytest behavior is to include setup and teardown times in the test duration -report. You can include just the call durations instead (excluding setup and teardown) by adding this to your ``pytest.ini`` file: - -.. code-block:: ini - - [pytest] - junit_duration_report = call diff --git a/changelog/4489.removal.rst b/changelog/4489.removal.rst deleted file mode 100644 index 423620465..000000000 --- a/changelog/4489.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed ``request.cached_setup``. This was the predecessor mechanism to modern fixtures. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/4532.feature.rst b/changelog/4532.feature.rst deleted file mode 100644 index ce7eb3729..000000000 --- a/changelog/4532.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -``-ra`` now will show errors and failures last, instead of as the first items in the summary. - -This makes it easier to obtain a list of errors and failures to run tests selectively. diff --git a/changelog/4535.removal.rst b/changelog/4535.removal.rst deleted file mode 100644 index 89de6b744..000000000 --- a/changelog/4535.removal.rst +++ /dev/null @@ -1 +0,0 @@ -Removed the deprecated ``PyCollector.makeitem`` method. This method was made public by mistake a long time ago. diff --git a/changelog/4543.removal.rst b/changelog/4543.removal.rst deleted file mode 100644 index 0a2b615f9..000000000 --- a/changelog/4543.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed support to define fixtures using the ``pytest_funcarg__`` prefix. Use the ``@pytest.fixture`` decorator instead. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/4545.removal.rst b/changelog/4545.removal.rst deleted file mode 100644 index 865d2fc12..000000000 --- a/changelog/4545.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Calling fixtures directly is now always an error instead of a warning. - -See our `docs `__ on information on how to update your code. diff --git a/changelog/4546.removal.rst b/changelog/4546.removal.rst deleted file mode 100644 index 977a30e8c..000000000 --- a/changelog/4546.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove ``Node.get_marker(name)`` the return value was not usable for more than a existence check. - -Use ``Node.get_closest_marker(name)`` as a replacement. diff --git a/changelog/4547.removal.rst b/changelog/4547.removal.rst deleted file mode 100644 index a30d5d7bd..000000000 --- a/changelog/4547.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -The deprecated ``record_xml_property`` fixture has been removed, use the more generic ``record_property`` instead. - -See our `docs `__ for more information. diff --git a/changelog/4548.removal.rst b/changelog/4548.removal.rst deleted file mode 100644 index bd47b1d51..000000000 --- a/changelog/4548.removal.rst +++ /dev/null @@ -1,3 +0,0 @@ -An error is now raised if the ``pytest_plugins`` variable is defined in a non-top-level ``conftest.py`` file (i.e., not residing in the ``rootdir``). - -See our `docs `__ for more information. diff --git a/changelog/4557.doc.rst b/changelog/4557.doc.rst deleted file mode 100644 index dba2e39cd..000000000 --- a/changelog/4557.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Markers example documentation page updated to support latest pytest version. diff --git a/changelog/4558.doc.rst b/changelog/4558.doc.rst deleted file mode 100644 index 09dc5b863..000000000 --- a/changelog/4558.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Update cache documentation example to correctly show cache hit and miss. diff --git a/changelog/4580.doc.rst b/changelog/4580.doc.rst deleted file mode 100644 index 2d8d52f33..000000000 --- a/changelog/4580.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Improved detailed summary report documentation. diff --git a/changelog/4599.feature.rst b/changelog/4599.feature.rst deleted file mode 100644 index 12ed20b23..000000000 --- a/changelog/4599.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -``pytest.importorskip`` now supports a ``reason`` parameter, which will be shown when the -requested module cannot be imported. diff --git a/changelog/4602.trivial.rst b/changelog/4602.trivial.rst new file mode 100644 index 000000000..619b40601 --- /dev/null +++ b/changelog/4602.trivial.rst @@ -0,0 +1 @@ +Uninstall ``hypothesis`` in regen tox env. diff --git a/changelog/4617.bugfix.rst b/changelog/4617.bugfix.rst new file mode 100644 index 000000000..166378efd --- /dev/null +++ b/changelog/4617.bugfix.rst @@ -0,0 +1 @@ +Fixed ``pytest.warns`` bug when context manager is reused (e.g. multiple parametrization). diff --git a/changelog/891.removal.rst b/changelog/891.removal.rst deleted file mode 100644 index 82d75c530..000000000 --- a/changelog/891.removal.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``testfunction.markername`` attributes - use ``Node.iter_markers(name=None)`` to iterate them. diff --git a/doc/en/Makefile b/doc/en/Makefile index fa8e8266a..f93d84557 100644 --- a/doc/en/Makefile +++ b/doc/en/Makefile @@ -39,7 +39,7 @@ clean: -rm -rf $(BUILDDIR)/* regen: - PYTHONDONTWRITEBYTECODE=1 PYTEST_ADDOPT=-pno:hypothesis COLUMNS=76 regendoc --update *.rst */*.rst ${REGENDOC_ARGS} + PYTHONDONTWRITEBYTECODE=1 PYTEST_ADDOPTS=-pno:hypothesis COLUMNS=76 regendoc --update *.rst */*.rst ${REGENDOC_ARGS} html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index d6379f1b3..40734e5b3 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-4.1.0 release-4.0.2 release-4.0.1 release-4.0.0 diff --git a/doc/en/announce/release-4.1.0.rst b/doc/en/announce/release-4.1.0.rst new file mode 100644 index 000000000..b7a076f61 --- /dev/null +++ b/doc/en/announce/release-4.1.0.rst @@ -0,0 +1,44 @@ +pytest-4.1.0 +======================================= + +The pytest team is proud to announce the 4.1.0 release! + +pytest is a mature Python testing tool with more than a 2000 tests +against itself, passing on many different interpreters and platforms. + +This release contains a number of bugs fixes and improvements, so users are encouraged +to take a look at the CHANGELOG: + + https://docs.pytest.org/en/latest/changelog.html + +For complete documentation, please visit: + + https://docs.pytest.org/en/latest/ + +As usual, you can upgrade from pypi via: + + pip install -U pytest + +Thanks to all who contributed to this release, among them: + +* Adam Johnson +* Aly Sivji +* Andrey Paramonov +* Anthony Sottile +* Bruno Oliveira +* Daniel Hahler +* David Vo +* Hyunchel Kim +* Jeffrey Rackauckas +* Kanguros +* Nicholas Devenish +* Pedro Algarvio +* Randy Barlow +* Ronny Pfannschmidt +* Tomer Keren +* feuillemorte +* wim glenn + + +Happy testing, +The Pytest Development Team diff --git a/doc/en/builtin.rst b/doc/en/builtin.rst index 1e376f0d3..a40dfc223 100644 --- a/doc/en/builtin.rst +++ b/doc/en/builtin.rst @@ -68,8 +68,6 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a def test_function(record_property): record_property("example_key", 1) - record_xml_property - (Deprecated) use record_property. record_xml_attribute Add extra xml attributes to the tag for the calling test. The fixture is callable with ``(name, value)``, with value being diff --git a/doc/en/cache.rst b/doc/en/cache.rst index a0fa72db1..ba9d87a5f 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -215,7 +215,9 @@ If you run this command for the first time, you can see the print statement: > assert mydata == 23 E assert 42 == 23 - test_caching.py:14: AssertionError + test_caching.py:17: AssertionError + -------------------------- Captured stdout setup --------------------------- + running expensive computation... 1 failed in 0.12 seconds If you run it a second time the value will be retrieved from @@ -234,7 +236,7 @@ the cache and nothing will be printed: > assert mydata == 23 E assert 42 == 23 - test_caching.py:14: AssertionError + test_caching.py:17: AssertionError 1 failed in 0.12 seconds See the :ref:`cache-api` for more details. diff --git a/doc/en/conf.py b/doc/en/conf.py index 445449185..53600e616 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -64,7 +64,7 @@ master_doc = "contents" # General information about the project. project = u"pytest" year = datetime.datetime.utcnow().year -copyright = u"2015–2018 , holger krekel and pytest-dev team" +copyright = u"2015–2019 , holger krekel and pytest-dev team" # The language for content autogenerated by Sphinx. Refer to documentation diff --git a/doc/en/example/nonpython.rst b/doc/en/example/nonpython.rst index 5b96a33bf..eba8279f3 100644 --- a/doc/en/example/nonpython.rst +++ b/doc/en/example/nonpython.rst @@ -90,9 +90,9 @@ interesting to just look at the collection tree: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR/nonpython, inifile: collected 2 items - - - - + + + + ======================= no tests ran in 0.12 seconds ======================= diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index d4540fe5e..92756e492 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -147,15 +147,15 @@ objects, they are still using the default pytest representation: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 8 items - - - - - - - - - + + + + + + + + + ======================= no tests ran in 0.12 seconds ======================= @@ -219,12 +219,12 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items - - - - - - + + + + + + ======================= no tests ran in 0.12 seconds ======================= @@ -285,9 +285,9 @@ Let's first see how it looks like at collection time: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items - - - + + + ======================= no tests ran in 0.12 seconds ======================= @@ -350,8 +350,8 @@ The result of this test will be successful: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 1 item - - + + ======================= no tests ran in 0.12 seconds ======================= diff --git a/doc/en/example/pythoncollection.rst b/doc/en/example/pythoncollection.rst index 3f1dd68ee..394924e2d 100644 --- a/doc/en/example/pythoncollection.rst +++ b/doc/en/example/pythoncollection.rst @@ -134,10 +134,10 @@ The test collection would look like this: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 2 items - - - - + + + + ======================= no tests ran in 0.12 seconds ======================= @@ -189,11 +189,11 @@ You can always peek at the collection tree without running tests like this: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 3 items - - - - - + + + + + ======================= no tests ran in 0.12 seconds ======================= diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index ffccdf77f..15d71caa0 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -15,9 +15,9 @@ get on the terminal - we are working on that): =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR/assertion, inifile: - collected 42 items + collected 44 items - failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF [100%] + failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF [100%] ================================= FAILURES ================================= ___________________________ test_generative[3-6] ___________________________ @@ -289,6 +289,48 @@ get on the terminal - we are working on that): E ? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ failure_demo.py:99: AssertionError + ______________ TestSpecialisedExplanations.test_eq_dataclass _______________ + + self = + + def test_eq_dataclass(self): + from dataclasses import dataclass + + @dataclass + class Foo(object): + a: int + b: str + + left = Foo(1, "b") + right = Foo(1, "c") + > assert left == right + E AssertionError: assert TestSpecialis...oo(a=1, b='b') == TestSpecialise...oo(a=1, b='c') + E Omitting 1 identical items, use -vv to show + E Differing attributes: + E b: 'b' != 'c' + + failure_demo.py:111: AssertionError + ________________ TestSpecialisedExplanations.test_eq_attrs _________________ + + self = + + def test_eq_attrs(self): + import attr + + @attr.s + class Foo(object): + a = attr.ib() + b = attr.ib() + + left = Foo(1, "b") + right = Foo(1, "c") + > assert left == right + E AssertionError: assert Foo(a=1, b='b') == Foo(a=1, b='c') + E Omitting 1 identical items, use -vv to show + E Differing attributes: + E b: 'b' != 'c' + + failure_demo.py:123: AssertionError ______________________________ test_attribute ______________________________ def test_attribute(): @@ -300,7 +342,7 @@ get on the terminal - we are working on that): E assert 1 == 2 E + where 1 = .Foo object at 0xdeadbeef>.b - failure_demo.py:107: AssertionError + failure_demo.py:131: AssertionError _________________________ test_attribute_instance __________________________ def test_attribute_instance(): @@ -312,7 +354,7 @@ get on the terminal - we are working on that): E + where 1 = .Foo object at 0xdeadbeef>.b E + where .Foo object at 0xdeadbeef> = .Foo'>() - failure_demo.py:114: AssertionError + failure_demo.py:138: AssertionError __________________________ test_attribute_failure __________________________ def test_attribute_failure(): @@ -325,7 +367,7 @@ get on the terminal - we are working on that): i = Foo() > assert i.b == 2 - failure_demo.py:125: + failure_demo.py:149: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = .Foo object at 0xdeadbeef> @@ -334,7 +376,7 @@ get on the terminal - we are working on that): > raise Exception("Failed to get attrib") E Exception: Failed to get attrib - failure_demo.py:120: Exception + failure_demo.py:144: Exception _________________________ test_attribute_multiple __________________________ def test_attribute_multiple(): @@ -351,31 +393,26 @@ get on the terminal - we are working on that): E + and 2 = .Bar object at 0xdeadbeef>.b E + where .Bar object at 0xdeadbeef> = .Bar'>() - failure_demo.py:135: AssertionError + failure_demo.py:159: AssertionError __________________________ TestRaises.test_raises __________________________ self = def test_raises(self): - s = "qwe" # NOQA - > raises(TypeError, "int(s)") + s = "qwe" + > raises(TypeError, int, s) + E ValueError: invalid literal for int() with base 10: 'qwe' - failure_demo.py:145: - _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - - > int(s) - E ValueError: invalid literal for int() with base 10: 'qwe' - - <0-codegen $REGENDOC_TMPDIR/assertion/failure_demo.py:145>:1: ValueError + failure_demo.py:169: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ self = def test_raises_doesnt(self): - > raises(IOError, "int('3')") + > raises(IOError, int, "3") E Failed: DID NOT RAISE - failure_demo.py:148: Failed + failure_demo.py:172: Failed __________________________ TestRaises.test_raise ___________________________ self = @@ -384,7 +421,7 @@ get on the terminal - we are working on that): > raise ValueError("demo error") E ValueError: demo error - failure_demo.py:151: ValueError + failure_demo.py:175: ValueError ________________________ TestRaises.test_tupleerror ________________________ self = @@ -393,7 +430,7 @@ get on the terminal - we are working on that): > a, b = [1] # NOQA E ValueError: not enough values to unpack (expected 2, got 1) - failure_demo.py:154: ValueError + failure_demo.py:178: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ self = @@ -404,7 +441,7 @@ get on the terminal - we are working on that): > a, b = items.pop() E TypeError: 'int' object is not iterable - failure_demo.py:159: TypeError + failure_demo.py:183: TypeError --------------------------- Captured stdout call --------------------------- items is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ @@ -415,7 +452,7 @@ get on the terminal - we are working on that): > if namenotexi: # NOQA E NameError: name 'namenotexi' is not defined - failure_demo.py:162: NameError + failure_demo.py:186: NameError ____________________ test_dynamic_compile_shows_nicely _____________________ def test_dynamic_compile_shows_nicely(): @@ -430,14 +467,14 @@ get on the terminal - we are working on that): sys.modules[name] = module > module.foo() - failure_demo.py:180: + failure_demo.py:204: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def foo(): > assert 1 == 0 E AssertionError - <2-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:177>:2: AssertionError + <0-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:201>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ self = @@ -451,7 +488,7 @@ get on the terminal - we are working on that): > somefunc(f(), g()) - failure_demo.py:191: + failure_demo.py:215: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ failure_demo.py:13: in somefunc otherfunc(x, y) @@ -473,7 +510,7 @@ get on the terminal - we are working on that): > a, b = items E ValueError: not enough values to unpack (expected 2, got 0) - failure_demo.py:195: ValueError + failure_demo.py:219: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ self = @@ -483,7 +520,7 @@ get on the terminal - we are working on that): > a, b = items E TypeError: 'int' object is not iterable - failure_demo.py:199: TypeError + failure_demo.py:223: TypeError ______________________ TestMoreErrors.test_startswith ______________________ self = @@ -496,7 +533,7 @@ get on the terminal - we are working on that): E + where False = ('456') E + where = '123'.startswith - failure_demo.py:204: AssertionError + failure_demo.py:228: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ self = @@ -515,7 +552,7 @@ get on the terminal - we are working on that): E + where '123' = .f at 0xdeadbeef>() E + and '456' = .g at 0xdeadbeef>() - failure_demo.py:213: AssertionError + failure_demo.py:237: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ self = @@ -526,7 +563,7 @@ get on the terminal - we are working on that): E + where False = isinstance(43, float) E + where 43 = globf(42) - failure_demo.py:216: AssertionError + failure_demo.py:240: AssertionError _______________________ TestMoreErrors.test_instance _______________________ self = @@ -537,7 +574,7 @@ get on the terminal - we are working on that): E assert 42 != 42 E + where 42 = .x - failure_demo.py:220: AssertionError + failure_demo.py:244: AssertionError _______________________ TestMoreErrors.test_compare ________________________ self = @@ -547,7 +584,7 @@ get on the terminal - we are working on that): E assert 11 < 5 E + where 11 = globf(10) - failure_demo.py:223: AssertionError + failure_demo.py:247: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ self = @@ -558,7 +595,7 @@ get on the terminal - we are working on that): > assert x == 0 E assert 1 == 0 - failure_demo.py:228: AssertionError + failure_demo.py:252: AssertionError ___________________ TestCustomAssertMsg.test_single_line ___________________ self = @@ -573,7 +610,7 @@ get on the terminal - we are working on that): E assert 1 == 2 E + where 1 = .A'>.a - failure_demo.py:239: AssertionError + failure_demo.py:263: AssertionError ____________________ TestCustomAssertMsg.test_multiline ____________________ self = @@ -592,7 +629,7 @@ get on the terminal - we are working on that): E assert 1 == 2 E + where 1 = .A'>.a - failure_demo.py:246: AssertionError + failure_demo.py:270: AssertionError ___________________ TestCustomAssertMsg.test_custom_repr ___________________ self = @@ -614,5 +651,5 @@ get on the terminal - we are working on that): E assert 1 == 2 E + where 1 = This is JSON\n{\n 'foo': 'bar'\n}.a - failure_demo.py:259: AssertionError - ======================== 42 failed in 0.12 seconds ========================= + failure_demo.py:283: AssertionError + ======================== 44 failed in 0.12 seconds ========================= diff --git a/doc/en/example/simple.rst b/doc/en/example/simple.rst index 95c0e6365..76a1ddc80 100644 --- a/doc/en/example/simple.rst +++ b/doc/en/example/simple.rst @@ -598,7 +598,7 @@ We can run this: file $REGENDOC_TMPDIR/b/test_error.py, line 1 def test_root(db): # no db here, will error out E fixture 'db' not found - > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory + > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory > use 'pytest --fixtures [testpath]' for help on them. $REGENDOC_TMPDIR/b/test_error.py:1 diff --git a/doc/en/fixture.rst b/doc/en/fixture.rst index 133901dde..4dd68f8e4 100644 --- a/doc/en/fixture.rst +++ b/doc/en/fixture.rst @@ -628,7 +628,7 @@ So let's just do another run: response, msg = smtp_connection.ehlo() assert response == 250 > assert b"smtp.gmail.com" in msg - E AssertionError: assert b'smtp.gmail.com' in b'mail.python.org\nPIPELINING\nSIZE 51200000\nETRN\nSTARTTLS\nAUTH DIGEST-MD5 NTLM CRAM-MD5\nENHANCEDSTATUSCODES\n8BITMIME\nDSN\nSMTPUTF8' + E AssertionError: assert b'smtp.gmail.com' in b'mail.python.org\nPIPELINING\nSIZE 51200000\nETRN\nSTARTTLS\nAUTH DIGEST-MD5 NTLM CRAM-MD5\nENHANCEDSTATUSCODES\n8BITMIME\nDSN\nSMTPUTF8\nCHUNKING' test_module.py:5: AssertionError -------------------------- Captured stdout setup --------------------------- @@ -703,19 +703,19 @@ Running the above tests results in the following test IDs being used: platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 10 items - - - - - - - - - - - - - + + + + + + + + + + + + + ======================= no tests ran in 0.12 seconds ======================= diff --git a/doc/en/usage.rst b/doc/en/usage.rst index bb1e9218c..3ff6a0dd5 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -152,40 +152,77 @@ making it easy in large test suites to get a clear picture of all failures, skip Example: +.. code-block:: python + + # content of test_example.py + import pytest + + + @pytest.fixture + def error_fixture(): + assert 0 + + + def test_ok(): + print("ok") + + + def test_fail(): + assert 0 + + + def test_error(error_fixture): + pass + + + def test_skip(): + pytest.skip("skipping this test") + + + def test_xfail(): + pytest.xfail("xfailing this test") + + + @pytest.mark.xfail(reason="always xfail") + def test_xpass(): + pass + + .. code-block:: pytest $ pytest -ra =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: - collected 7 items + collected 6 items - test_examples.py ..FEsxX [100%] + test_example.py .FEsxX [100%] - ==================================== ERRORS ==================================== - _________________________ ERROR at setup of test_error _________________________ - file /Users/chainz/tmp/pytestratest/test_examples.py, line 17 - def test_error(unknown_fixture): - E fixture 'unknown_fixture' not found - > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory - > use 'pytest --fixtures [testpath]' for help on them. + ================================== ERRORS ================================== + _______________________ ERROR at setup of test_error _______________________ - /Users/chainz/tmp/pytestratest/test_examples.py:17 - =================================== FAILURES =================================== - __________________________________ test_fail ___________________________________ + @pytest.fixture + def error_fixture(): + > assert 0 + E assert 0 + + test_example.py:6: AssertionError + ================================= FAILURES ================================= + ________________________________ test_fail _________________________________ def test_fail(): > assert 0 E assert 0 - test_examples.py:14: AssertionError - =========================== short test summary info ============================ - FAIL test_examples.py::test_fail - ERROR test_examples.py::test_error - SKIP [1] test_examples.py:21: Example - XFAIL test_examples.py::test_xfail - XPASS test_examples.py::test_xpass - = 1 failed, 2 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.07 seconds = + test_example.py:14: AssertionError + ========================= short test summary info ========================== + SKIP [1] $REGENDOC_TMPDIR/test_example.py:23: skipping this test + XFAIL test_example.py::test_xfail + reason: xfailing this test + XPASS test_example.py::test_xpass always xfail + ERROR test_example.py::test_error + FAIL test_example.py::test_fail + 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12 seconds The ``-r`` options accepts a number of characters after it, with ``a`` used above meaning "all except passes". @@ -208,22 +245,31 @@ More than one character can be used, so for example to only see failed and skipp =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: - collected 2 items + collected 6 items - test_examples.py Fs [100%] + test_example.py .FEsxX [100%] - =================================== FAILURES =================================== - __________________________________ test_fail ___________________________________ + ================================== ERRORS ================================== + _______________________ ERROR at setup of test_error _______________________ + + @pytest.fixture + def error_fixture(): + > assert 0 + E assert 0 + + test_example.py:6: AssertionError + ================================= FAILURES ================================= + ________________________________ test_fail _________________________________ def test_fail(): > assert 0 E assert 0 - test_examples.py:14: AssertionError - =========================== short test summary info ============================ - FAIL test_examples.py::test_fail - SKIP [1] test_examples.py:21: Example - ===================== 1 failed, 1 skipped in 0.09 seconds ====================== + test_example.py:14: AssertionError + ========================= short test summary info ========================== + FAIL test_example.py::test_fail + SKIP [1] $REGENDOC_TMPDIR/test_example.py:23: skipping this test + 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12 seconds Using ``p`` lists the passing tests, whilst ``P`` adds an extra section "PASSES" with those tests that passed but had captured output: @@ -234,18 +280,34 @@ captured output: =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: - collected 2 items + collected 6 items - test_examples.py .. [100%] - =========================== short test summary info ============================ - PASSED test_examples.py::test_pass - PASSED test_examples.py::test_pass_with_output + test_example.py .FEsxX [100%] - ==================================== PASSES ==================================== - ____________________________ test_pass_with_output _____________________________ - ----------------------------- Captured stdout call ----------------------------- - Passing test - =========================== 2 passed in 0.04 seconds =========================== + ================================== ERRORS ================================== + _______________________ ERROR at setup of test_error _______________________ + + @pytest.fixture + def error_fixture(): + > assert 0 + E assert 0 + + test_example.py:6: AssertionError + ================================= FAILURES ================================= + ________________________________ test_fail _________________________________ + + def test_fail(): + > assert 0 + E assert 0 + + test_example.py:14: AssertionError + ========================= short test summary info ========================== + PASSED test_example.py::test_ok + ================================== PASSES ================================== + _________________________________ test_ok __________________________________ + --------------------------- Captured stdout call --------------------------- + ok + 1 failed, 1 passed, 1 skipped, 1 xfailed, 1 xpassed, 1 error in 0.12 seconds .. _pdb-option: @@ -631,8 +693,25 @@ Running it will show that ``MyPlugin`` was added and its hook was invoked:: $ python myinvoke.py - . [100%]*** test run reporting finishing + .FEsxX. [100%]*** test run reporting finishing + ================================== ERRORS ================================== + _______________________ ERROR at setup of test_error _______________________ + + @pytest.fixture + def error_fixture(): + > assert 0 + E assert 0 + + test_example.py:6: AssertionError + ================================= FAILURES ================================= + ________________________________ test_fail _________________________________ + + def test_fail(): + > assert 0 + E assert 0 + + test_example.py:14: AssertionError .. note:: diff --git a/doc/en/warnings.rst b/doc/en/warnings.rst index 3e69d3480..421491086 100644 --- a/doc/en/warnings.rst +++ b/doc/en/warnings.rst @@ -155,7 +155,7 @@ DeprecationWarning and PendingDeprecationWarning .. versionchanged:: 3.9 By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings from -user code and third-party libraries, as recommended by `PEP-0506 `_. +user code and third-party libraries, as recommended by `PEP-0565 `_. This helps users keep their code modern and avoid breakages when deprecated warnings are effectively removed. Sometimes it is useful to hide some specific deprecation warnings that happen in code that you have no control over diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index f39f7aee7..a58c75d3a 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -192,6 +192,10 @@ class WarningsRecorder(warnings.catch_warnings): warnings.warn = self._saved_warn super(WarningsRecorder, self).__exit__(*exc_info) + # Built-in catch_warnings does not reset entered state so we do it + # manually here for this context manager to become reusable. + self._entered = False + class WarningsChecker(WarningsRecorder): def __init__(self, expected_warning=None, match_expr=None): diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 3bac9a545..45e196149 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -683,3 +683,27 @@ class TestAssertionWarnings: self.create_file(testdir, False) result = testdir.runpytest() result.stdout.fnmatch_lines(["*1 failed in*"]) + + +def test_warningschecker_twice(testdir): + """Issue #4617""" + + testdir.makepyfile( + """ + import pytest + import warnings + + @pytest.mark.parametrize("other", [1, 2]) + @pytest.mark.parametrize("expectation", [ + pytest.warns(DeprecationWarning, + match="Message A"), + pytest.warns(DeprecationWarning, + match="Message A"), + ]) + def test_parametrized_warnings(other, expectation): + with expectation: + warnings.warn("Message A", DeprecationWarning) + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["* 4 passed in *"]) diff --git a/tox.ini b/tox.ini index 7a69000c8..7cb430223 100644 --- a/tox.ini +++ b/tox.ini @@ -148,10 +148,13 @@ deps = sphinx PyYAML regendoc>=0.6.1 + dataclasses whitelist_externals = rm make commands = + # don't show hypothesis plugin info in docs, see #4602 + pip uninstall hypothesis -y rm -rf /tmp/doc-exec* make regen