Compare commits

...

54 Commits
8.2.2 ... 7.2.2

Author SHA1 Message Date
pytest bot
4191e02598 Prepare release version 7.2.2 2023-03-03 17:05:52 +00:00
github-actions[bot]
eb50c6ce99 [7.2.x] Normalize how changelog entries are written (#10790)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-03-03 16:26:35 +00:00
github-actions[bot]
9693556f27 [7.2.x] Fix test_cmdline_python_namespace_package (#10789)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2023-03-03 15:52:49 +00:00
github-actions[bot]
e8e7d44a4c [7.2.x] made minor updates to fixtures docs (#10778)
Co-authored-by: Billy <william.j.kern@gmail.com>
2023-02-28 16:08:54 +00:00
github-actions[bot]
2fd4549db5 [7.2.x] docs: be more explicit about module level skip preventing collection (#10777)
Co-authored-by: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
2023-02-28 16:03:47 +00:00
github-actions[bot]
cee8d6f274 [7.2.x] Update import mode documentation to not refer to __import__() anymore. (#10751)
Co-authored-by: Manuel Jacob <me@manueljacob.de>
2023-02-18 18:57:56 -03:00
github-actions[bot]
79108bf9a3 [7.2.x] add CI and BUILD_NUMBER env var in docs (#10750)
Co-authored-by: bitzge <4791819+bitzge@users.noreply.github.com>
2023-02-18 18:57:28 -03:00
github-actions[bot]
779a87aada [7.2.x] Update open training (#10740)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2023-02-15 16:07:30 +01:00
Bruno Oliveira
60216810d9 Merge pull request #10734 from pytest-dev/backport-10725-to-7.2.x
[7.2.x] Fix entry-points declaration in the documentation example using Hatch
2023-02-14 12:10:39 -03:00
Garvit Shubham
37e410fce8 [7.2.x] Fix entry-points declaration in the documentation example using Hatch 2023-02-14 14:01:18 +00:00
Bruno Oliveira
0aeb843e25 Merge pull request #10729 from nicoddemus/backport-10722
[7.2.x] Use build-and-inspect-python-package action (#10722)
2023-02-14 10:57:58 -03:00
Bruno Oliveira
1e83bd8386 Use build-and-inspect-python-package action (#10722)
This uses https://github.com/hynek/build-and-inspect-python-package to ensure our package is correct, both during testing and deploy,
2023-02-12 21:42:24 -03:00
Bruno Oliveira
02e9e8403e Merge pull request #10715 from pytest-dev/backport-10713-to-7.2.x
[7.2.x] DOCS-#10687: Add a note about -W vs filterwarnings.
2023-02-07 19:55:03 -03:00
Mahesh Vashishtha
7e1549dfb6 [7.2.x] DOCS-#10687: Add a note about -W vs filterwarnings. 2023-02-07 22:29:03 +00:00
Bruno Oliveira
d61f83c030 Merge pull request #10698 from pytest-dev/backport-10696-to-7.2.x
[7.2.x] Fix fixtures named teardown being considered by nose
2023-01-27 14:58:14 -03:00
Teejay
432a60bd52 [7.2.x] Fix fixtures named teardown being considered by nose 2023-01-27 17:35:34 +00:00
Bruno Oliveira
4b83a05939 Merge pull request #10697 from pytest-dev/backport-10695-to-7.2.x
[7.2.x] Clarify docs for `match` regarding escaping
2023-01-27 08:47:14 -03:00
vin01
4e14609b99 [7.2.x] Clarify docs for match regarding escaping 2023-01-27 11:13:22 +00:00
github-actions[bot]
76bef68f3e [7.2.x] Add check for zero denominator in approx (#10689)
Co-authored-by: Jay <43951088+jayendra-patil33@users.noreply.github.com>
2023-01-24 10:30:54 +00:00
Bruno Oliveira
af22d34158 Merge pull request #10681 from pytest-dev/backport-10664-to-7.2.x
[7.2.x] Check if config args and args_source exist
2023-01-21 08:46:56 -03:00
q0w
d1b9660402 [7.2.x] Check if config args and args_source exist 2023-01-21 11:21:12 +00:00
Bruno Oliveira
9c103aef2f Merge pull request #10673 from pytest-dev/backport-10660-to-7.2.x
[7.2.x] Derive pytest.raises from AbstractContextManager
2023-01-19 16:44:28 -03:00
Bruno Oliveira
624ae81eb1 Merge pull request #10675 from nicoddemus/backport-10608-to-7.2.x
[7.2.x] Fix crash if `--cache-show` and `--help` are passed at the same time
2023-01-19 11:35:09 -03:00
Ramsey
5bf361f24e Fix crash if --cache-show and --help are passed at the same time
Closes #10592

(cherry picked from commit 4d4ed42c34)
2023-01-19 10:06:05 -03:00
Ronny Pfannschmidt
baa938eea5 [7.2.x] Derive pytest.raises from AbstractContextManager 2023-01-18 05:44:44 +00:00
Bruno Oliveira
94c05bc2a4 Merge pull request #10659 from pytest-dev/release-7.2.1
Prepare release 7.2.1
2023-01-14 09:20:20 -03:00
pytest bot
1ae778f13e Prepare release version 7.2.1 2023-01-13 11:01:33 +00:00
Bruno Oliveira
cb07711846 Merge pull request #10656 from pytest-dev/backport-10641-to-7.2.x
[7.2.x] Dont update cache from xdist worker
2023-01-13 07:50:57 -03:00
Bruno Oliveira
944070259e Merge pull request #10657 from pytest-dev/backport-10640-to-7.2.x
[7.2.x] Fix regen tox environment
2023-01-13 07:22:04 -03:00
Bruno Oliveira
e8055c1609 [7.2.x] Fix regen tox environment 2023-01-13 10:20:49 +00:00
s-padmanaban
f22fbbf9f1 [7.2.x] Dont update cache from xdist worker 2023-01-13 10:16:42 +00:00
Bruno Oliveira
211d08e9bc Merge pull request #10638 from pytest-dev/backport-10607-to-7.2.x
[7.2.x] Mitigate directory creation race condition
2023-01-06 09:33:55 -03:00
Kadino
a6f85a0e3e [7.2.x] Mitigate directory creation race condition 2023-01-06 12:13:46 +00:00
Bruno Oliveira
08d0dd06ac Merge pull request #10637 from pytest-dev/backport-10632-to-7.2.x
[7.2.x] Fix tests pygments 2.14.0
2023-01-05 13:20:53 -03:00
Bruno Oliveira
405fd15128 [7.2.x] Fix tests pygments 2.14.0 2023-01-05 15:59:54 +00:00
Bruno Oliveira
c16315f5c3 Merge pull request #10586 from nicoddemus/backport-10578
[7.2.x] Fix tox 4.0 support and docs
2022-12-14 14:58:44 -03:00
Bruno Oliveira
f1989747b7 Fix tox 4.0 support and docs
Also includes pre-commit autoupdate
2022-12-14 09:09:43 -03:00
Bruno Oliveira
7d35baaa3c Merge pull request #10529 from pytest-dev/backport-10526-to-7.2.x
[7.2.x] Issue #10506
2022-11-23 15:47:02 -03:00
Prerak Patel
c3b0080c87 [7.2.x] Issue #10506 2022-11-23 17:49:15 +00:00
Bruno Oliveira
3c2f90b9b9 Merge pull request #10513 from pytest-dev/backport-10482-to-7.2.x
[7.2.x] issue-10457/show test name when skipping from fixture
2022-11-18 10:06:57 -03:00
Daniel Valenzuela
f5d2edc1fc [7.2.x] issue-10457/show test name when skipping from fixture 2022-11-18 12:22:15 +00:00
Bruno Oliveira
47d6adf890 Merge pull request #10489 from pytest-dev/backport-10488-to-7.2.x
[7.2.x] Fix test_raising_repr test
2022-11-09 20:46:56 -03:00
Bruno Oliveira
dbd4c5fb2f [7.2.x] Fix test_raising_repr test 2022-11-09 23:21:32 +00:00
github-actions[bot]
b2271afa65 [7.2.x] Remove done trainings (#10472)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-11-04 18:50:45 +01:00
github-actions[bot]
6a5076db9f [7.2.x] Fix 'importlib.abc.TraversableResources' deprecation warning in Python 3.12 (#10453)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
2022-10-31 16:16:34 +00:00
Bruno Oliveira
8606feb3a4 Merge pull request #10431 from pytest-dev/backport-10426-to-7.2.x
[7.2.x] Add the PyPI classifier for Python 3.11
2022-10-25 15:53:46 -03:00
Bruno Oliveira
6a4a0f43b5 Merge pull request #10430 from pytest-dev/backport-10425-to-7.2.x
[7.2.x] upgrade pygments-pytest for 7.2.x coloring
2022-10-25 15:32:05 -03:00
Bruno Oliveira
eff2e2decd Merge pull request #10432 from nicoddemus/backport-10417
[2.7.x] Use specific tag in the gh-action-pypi-publish action
2022-10-25 15:21:08 -03:00
Bruno Oliveira
23bbd5a628 Merge pull request #10417 from nicoddemus/publish-action-pin
Use specific tag in the gh-action-pypi-publish action
2022-10-25 18:19:53 -03:00
github-actions[bot]
651c7bf932 [7.2.x] Edit changelog for 7.2.0 (#10429)
Co-authored-by: Florian Bruhin <me@the-compiler.org>
2022-10-25 18:11:35 +00:00
Santiago Castro
1f08cd7225 [7.2.x] Add the PyPI classifier for Python 3.11 2022-10-25 18:10:30 +00:00
Anthony Sottile
5c6a9a6504 [7.2.x] upgrade pygments-pytest for 7.2.x coloring 2022-10-25 17:53:54 +00:00
Ronny Pfannschmidt
ac4e3cced9 Merge pull request #10412 from pytest-dev/release-7.2.0
Prepare release 7.2.0
2022-10-25 10:58:30 +02:00
pytest bot
3af3f569d5 Prepare release version 7.2.0 2022-10-23 20:28:15 +00:00
86 changed files with 781 additions and 217 deletions

View File

@@ -28,25 +28,29 @@ jobs:
fetch-depth: 0
persist-credentials: false
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5
- name: Download Package
uses: actions/download-artifact@v3
with:
name: Packages
path: dist
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.pypi_token }}
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: "3.7"
- name: Install dependencies
- name: Install tox
run: |
python -m pip install --upgrade pip
pip install --upgrade build tox
- name: Build package
run: |
python -m build
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_token }}
pip install --upgrade tox
- name: Publish GitHub release notes
env:

View File

@@ -18,6 +18,11 @@ on:
env:
PYTEST_ADDOPTS: "--color=yes"
# Cancel running jobs for the same workflow and branch.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Set permissions at the job level.
permissions: {}
@@ -189,3 +194,10 @@ jobs:
fail_ci_if_error: true
files: ./coverage.xml
verbose: true
check-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5

View File

@@ -2,7 +2,7 @@ default_language_version:
python: "3.10"
repos:
- repo: https://github.com/psf/black
rev: 22.10.0
rev: 22.12.0
hooks:
- id: black
args: [--safe, --quiet]
@@ -44,7 +44,7 @@ repos:
- id: reorder-python-imports
args: ['--application-directories=.:src', --py37-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v3.1.0
rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py37-plus]
@@ -52,7 +52,7 @@ repos:
rev: v2.1.0
hooks:
- id: setup-cfg-fmt
args: ["--max-py-version=3.10", "--include-version-classifiers"]
args: ["--max-py-version=3.11", "--include-version-classifiers"]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:

View File

@@ -2,9 +2,12 @@ version: 2
python:
install:
- requirements: doc/en/requirements.txt
- method: pip
path: .
# Install pytest first, then doc/en/requirements.txt.
# This order is important to honor any pins in doc/en/requirements.txt
# when the pinned library is also a dependency of pytest.
- method: pip
path: .
- requirements: doc/en/requirements.txt
build:
os: ubuntu-20.04

View File

@@ -88,6 +88,7 @@ Daniel Grana
Daniel Hahler
Daniel Nuri
Daniel Sánchez Castelló
Daniel Valenzuela Zenteno
Daniel Wandschneider
Daniele Procida
Danielle Jenkins
@@ -285,6 +286,7 @@ Prashant Sharma
Pulkit Goyal
Punyashloka Biswal
Quentin Pradet
q0w
Ralf Schmitt
Ram Rachum
Ralph Giles
@@ -310,6 +312,7 @@ Samuel Searles-Bryant
Samuele Pedroni
Sanket Duthade
Sankt Petersbug
Saravanan Padmanaban
Segev Finer
Serhii Mozghovyi
Seth Junot
@@ -341,6 +344,7 @@ Thomas Grainger
Thomas Hisch
Tim Hoffmann
Tim Strazny
TJ Bruno
Tobias Diez
Tom Dalton
Tom Viner
@@ -372,6 +376,8 @@ Xixi Zhao
Xuan Luong
Xuecong Liao
Yoav Caspi
Yuliang Shao
Yusuke Kadowaki
Yuval Shimon
Zac Hatfield-Dodds
Zachary Kneupper

View File

@@ -1 +0,0 @@
Update :class:`pytest.PytestUnhandledCoroutineWarning` to a deprecation; it will raise an error in pytest 8.

View File

@@ -1 +0,0 @@
:data:`sys.stdin` now contains all expected methods of a file-like object when capture is enabled.

View File

@@ -1 +0,0 @@
:class:`~pytest.PytestReturnNotNoneWarning` is now a subclass of :class:`~pytest.PytestRemovedIn8Warning`: the plan is to make returning non-``None`` from tests an error in the future.

View File

@@ -1,5 +0,0 @@
``@pytest.mark.parametrize()`` (and similar functions) now accepts any ``Sequence[str]`` for the argument names,
instead of just ``list[str]`` and ``tuple[str, ...]``.
(Note that ``str``, which is itself a ``Sequence[str]``, is still treated as a
comma-delimited name list, as before).

View File

@@ -1,3 +0,0 @@
Made ``_pytest.doctest.DoctestItem`` export ``pytest.DoctestItem`` for
type check and runtime purposes. Made `_pytest.doctest` use internal APIs
to avoid circular imports.

View File

@@ -1 +0,0 @@
Update information on writing plugins to use ``pyproject.toml`` instead of ``setup.py``.

View File

@@ -1 +0,0 @@
The ``--no-showlocals`` flag has been added. This can be passed directly to tests to override ``--showlocals`` declared through ``addopts``.

View File

@@ -1 +0,0 @@
Do not break into pdb when ``raise unittest.SkipTest()`` appears top-level in a file.

View File

@@ -1 +0,0 @@
pytest no longer depends on the ``py`` library. ``pytest`` provides a vendored copy of ``py.error`` and ``py.path`` modules but will use the ``py`` library if it is installed. If you need other ``py.*`` modules, continue to install the deprecated ``py`` library separately, otherwise it can usually be removed as a dependency.

View File

@@ -1 +0,0 @@
Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expresed instead.

View File

@@ -1,4 +0,0 @@
Deprecate configuring hook specs/impls using attributes/marks.
Instead use :py:func:`pytest.hookimpl` and :py:func:`pytest.hookspec`.
For more details, see the :ref:`docs <legacy-path-hooks-deprecated>`.

View File

@@ -1 +0,0 @@
A warning is now emitted if a test function returns something other than `None`. This prevents a common mistake among beginners that expect that returning a `bool` (for example `return foo(a, b) == result`) would cause a test to pass or fail, instead of using `assert`.

View File

@@ -1,5 +0,0 @@
Marks are now inherited according to the full MRO in test classes. Previously, if a test class inherited from two or more classes, only marks from the first super-class would apply.
When inheriting marks from super-classes, marks from the sub-classes are now ordered before marks from the super-classes, in MRO order. Previously it was the reverse.
When inheriting marks from super-classes, the `pytestmark` attribute of the sub-class now only contains the marks directly applied to it. Previously, it also contained marks from its super-classes. Please note that this attribute should not normally be accessed directly; use :func:`pytest.Node.iter_markers` instead.

View File

@@ -1,2 +0,0 @@
Introduce multiline display for warning matching via :py:func:`pytest.warns` and
enhance match comparison for :py:func:`_pytest._code.ExceptionInfo.match` as returned by :py:func:`pytest.raises`.

View File

@@ -1,2 +0,0 @@
Improve :py:func:`pytest.raises`. Previously passing an empty tuple would give a confusing
error. We now raise immediately with a more helpful message.

View File

@@ -1 +0,0 @@
Showing inner exceptions by forcing native display in ``ExceptionGroups`` even when using display options other than ``--tb=native``. A temporary step before full implementation of pytest-native display for inner exceptions in ``ExceptionGroups``.

View File

@@ -1 +0,0 @@
The documentation is now built using Sphinx 5.x (up from 3.x previously).

View File

@@ -1 +0,0 @@
Update documentation on how :func:`pytest.warns` affects :class:`DeprecationWarning`.

View File

@@ -1,3 +0,0 @@
On Python 3.11, use the standard library's :mod:`tomllib` to parse TOML.
:mod:`tomli`` is no longer a dependency on Python 3.11.

View File

@@ -1 +0,0 @@
Display assertion message without escaped newline characters with ``-vv``.

View File

@@ -1 +0,0 @@
Improved error message that is shown when no collector is found for a given file.

View File

@@ -1 +0,0 @@
Some coloring has been added to the short test summary.

View File

@@ -1 +0,0 @@
Ensure ``caplog.get_records(when)`` returns current/correct data after invoking ``caplog.clear()``.

View File

@@ -1 +0,0 @@
Normalize the help description of all command-line options.

View File

@@ -1,10 +0,0 @@
The functionality for running tests written for ``nose`` has been officially deprecated.
This includes:
* Plain ``setup`` and ``teardown`` functions and methods: this might catch users by surprise, as ``setup()`` and ``teardown()`` are not pytest idioms, but part of the ``nose`` support.
* Setup/teardown using the `@with_setup <with-setup-nose>`_ decorator.
For more details, consult the :ref:`deprecation docs <nose-deprecation>`.
.. _`with-setup-nose`: https://nose.readthedocs.io/en/latest/testing_tools.html?highlight=with_setup#nose.tools.with_setup

View File

@@ -1 +0,0 @@
Added shell-style wildcard support to ``testpaths``.

View File

@@ -1 +0,0 @@
Made ``_pytest.compat`` re-export ``importlib_metadata`` in the eyes of type checkers.

View File

@@ -1 +0,0 @@
Fix default encoding warning (``EncodingWarning``) in ``cacheprovider``

View File

@@ -1 +0,0 @@
Display full crash messages in ``short test summary info``, when runng in a CI environment.

View File

@@ -1,4 +0,0 @@
Improve the error message when we attempt to access a fixture that has been
torn down.
Add an additional sentence to the docstring explaining when it's not a good
idea to call getfixturevalue.

View File

@@ -1 +0,0 @@
Added support for hidden configuration file by allowing ``.pytest.ini`` as an alternative to ``pytest.ini``.

View File

@@ -6,6 +6,9 @@ Release announcements
:maxdepth: 2
release-7.2.2
release-7.2.1
release-7.2.0
release-7.1.3
release-7.1.2
release-7.1.1

View File

@@ -0,0 +1,93 @@
pytest-7.2.0
=======================================
The pytest team is proud to announce the 7.2.0 release!
This release contains new features, improvements, and bug fixes,
the full list of changes is available in the changelog:
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:
* Aaron Berdy
* Adam Turner
* Albert Villanova del Moral
* Alice Purcell
* Anthony Sottile
* Anton Yakutovich
* Babak Keyvani
* Brandon Chinn
* Bruno Oliveira
* Chanvin Xiao
* Cheuk Ting Ho
* Chris Wheeler
* EmptyRabbit
* Ezio Melotti
* Florian Best
* Florian Bruhin
* Fredrik Berndtsson
* Gabriel Landau
* Gergely Kalmár
* Hugo van Kemenade
* James Gerity
* John Litborn
* Jon Parise
* Kevin C
* Kian Eliasi
* MatthewFlamm
* Miro Hrončok
* Nate Meyvis
* Neil Girdhar
* Nhieuvu1802
* Nipunn Koorapati
* Ofek Lev
* Paul Müller
* Paul Reece
* Pax
* Pete Baughman
* Peyman Salehi
* Philipp A
* Ran Benita
* Robert O'Shea
* Ronny Pfannschmidt
* Rowin
* Ruth Comer
* Samuel Colvin
* Samuel Gaist
* Sandro Tosi
* Shantanu
* Simon K
* Stephen Rosen
* Sviatoslav Sydorenko
* Tatiana Ovary
* Thierry Moisan
* Thomas Grainger
* Tim Hoffmann
* Tobias Diez
* Tony Narlock
* Vivaan Verma
* Wolfremium
* Zac Hatfield-Dodds
* Zach OBrien
* aizpurua23a
* gresm
* holesch
* itxasos23
* johnkangw
* skhomuti
* sommersoft
* wodny
* zx.qiu
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,25 @@
pytest-7.2.1
=======================================
pytest 7.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:
* Anthony Sottile
* Bruno Oliveira
* Daniel Valenzuela
* Kadino
* Prerak Patel
* Ronny Pfannschmidt
* Santiago Castro
* s-padmanaban
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,25 @@
pytest-7.2.2
=======================================
pytest 7.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:
* Bruno Oliveira
* Garvit Shubham
* Mahesh Vashishtha
* Ramsey
* Ronny Pfannschmidt
* Teejay
* q0w
* vin01
Happy testing,
The pytest Development Team

View File

@@ -22,7 +22,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
cachedir: .pytest_cache
rootdir: /home/sweet/project
collected 0 items
cache -- .../_pytest/cacheprovider.py:510
cache -- .../_pytest/cacheprovider.py:509
Return a cache object that can persist state between testing sessions.
cache.get(key, default)
@@ -33,7 +33,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Values can be any object handled by the json stdlib module.
capsys -- .../_pytest/capture.py:878
capsys -- .../_pytest/capture.py:905
Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.
The captured output is made available via ``capsys.readouterr()`` method
@@ -51,7 +51,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capsys.readouterr()
assert captured.out == "hello\n"
capsysbinary -- .../_pytest/capture.py:906
capsysbinary -- .../_pytest/capture.py:933
Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.
The captured output is made available via ``capsysbinary.readouterr()``
@@ -69,7 +69,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capsysbinary.readouterr()
assert captured.out == b"hello\n"
capfd -- .../_pytest/capture.py:934
capfd -- .../_pytest/capture.py:961
Enable text capturing of writes to file descriptors ``1`` and ``2``.
The captured output is made available via ``capfd.readouterr()`` method
@@ -87,7 +87,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capfd.readouterr()
assert captured.out == "hello\n"
capfdbinary -- .../_pytest/capture.py:962
capfdbinary -- .../_pytest/capture.py:989
Enable bytes capturing of writes to file descriptors ``1`` and ``2``.
The captured output is made available via ``capfd.readouterr()`` method
@@ -105,7 +105,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
captured = capfdbinary.readouterr()
assert captured.out == b"hello\n"
doctest_namespace [session scope] -- .../_pytest/doctest.py:735
doctest_namespace [session scope] -- .../_pytest/doctest.py:738
Fixture that returns a :py:class:`dict` that will be injected into the
namespace of doctests.
@@ -119,7 +119,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
For more details: :ref:`doctest_namespace`.
pytestconfig [session scope] -- .../_pytest/fixtures.py:1344
pytestconfig [session scope] -- .../_pytest/fixtures.py:1356
Session-scoped fixture that returns the session's :class:`pytest.Config`
object.
@@ -163,7 +163,10 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
record_testsuite_property("ARCH", "PPC")
record_testsuite_property("STORAGE_TYPE", "CEPH")
``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.
:param name:
The property name.
:param value:
The property value. Will be converted to a string.
.. warning::
@@ -193,7 +196,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
.. _legacy_path: https://py.readthedocs.io/en/latest/path.html
caplog -- .../_pytest/logging.py:487
caplog -- .../_pytest/logging.py:491
Access and control log capturing.
Captured logs are available through the following properties/methods::
@@ -228,16 +231,16 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
To undo modifications done by the fixture in a contained scope,
use :meth:`context() <pytest.MonkeyPatch.context>`.
recwarn -- .../_pytest/recwarn.py:29
recwarn -- .../_pytest/recwarn.py:30
Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
See https://docs.python.org/library/how-to/capture-warnings.html for information
See https://docs.pytest.org/en/latest/how-to/capture-warnings.html for information
on warning categories.
tmp_path_factory [session scope] -- .../_pytest/tmpdir.py:184
tmp_path_factory [session scope] -- .../_pytest/tmpdir.py:188
Return a :class:`pytest.TempPathFactory` instance for the test session.
tmp_path -- .../_pytest/tmpdir.py:199
tmp_path -- .../_pytest/tmpdir.py:203
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.

View File

@@ -28,6 +28,206 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 7.2.2 (2023-03-03)
=========================
Bug Fixes
---------
- `#10533 <https://github.com/pytest-dev/pytest/issues/10533>`_: Fixed :func:`pytest.approx` handling of dictionaries containing one or more values of `0.0`.
- `#10592 <https://github.com/pytest-dev/pytest/issues/10592>`_: Fixed crash if `--cache-show` and `--help` are passed at the same time.
- `#10597 <https://github.com/pytest-dev/pytest/issues/10597>`_: Fixed bug where a fixture method named ``teardown`` would be called as part of ``nose`` teardown stage.
- `#10626 <https://github.com/pytest-dev/pytest/issues/10626>`_: Fixed crash if ``--fixtures`` and ``--help`` are passed at the same time.
- `#10660 <https://github.com/pytest-dev/pytest/issues/10660>`_: Fixed :py:func:`pytest.raises` to return a 'ContextManager' so that type-checkers could narrow
:code:`pytest.raises(...) if ... else nullcontext()` down to 'ContextManager' rather than 'object'.
Improved Documentation
----------------------
- `#10690 <https://github.com/pytest-dev/pytest/issues/10690>`_: Added `CI` and `BUILD_NUMBER` environment variables to the documentation.
- `#10721 <https://github.com/pytest-dev/pytest/issues/10721>`_: Fixed entry-points declaration in the documentation example using Hatch.
- `#10753 <https://github.com/pytest-dev/pytest/issues/10753>`_: Changed wording of the module level skip to be very explicit
about not collecting tests and not executing the rest of the module.
pytest 7.2.1 (2023-01-13)
=========================
Bug Fixes
---------
- `#10452 <https://github.com/pytest-dev/pytest/issues/10452>`_: Fix 'importlib.abc.TraversableResources' deprecation warning in Python 3.12.
- `#10457 <https://github.com/pytest-dev/pytest/issues/10457>`_: If a test is skipped from inside a fixture, the test summary now shows the test location instead of the fixture location.
- `#10506 <https://github.com/pytest-dev/pytest/issues/10506>`_: Fix bug where sometimes pytest would use the file system root directory as :ref:`rootdir <rootdir>` on Windows.
- `#10607 <https://github.com/pytest-dev/pytest/issues/10607>`_: Fix a race condition when creating junitxml reports, which could occur when multiple instances of pytest execute in parallel.
- `#10641 <https://github.com/pytest-dev/pytest/issues/10641>`_: Fix a race condition when creating or updating the stepwise plugin's cache, which could occur when multiple xdist worker nodes try to simultaneously update the stepwise plugin's cache.
pytest 7.2.0 (2022-10-23)
=========================
Deprecations
------------
- `#10012 <https://github.com/pytest-dev/pytest/issues/10012>`_: Update :class:`pytest.PytestUnhandledCoroutineWarning` to a deprecation; it will raise an error in pytest 8.
- `#10396 <https://github.com/pytest-dev/pytest/issues/10396>`_: pytest no longer depends on the ``py`` library. ``pytest`` provides a vendored copy of ``py.error`` and ``py.path`` modules but will use the ``py`` library if it is installed. If you need other ``py.*`` modules, continue to install the deprecated ``py`` library separately, otherwise it can usually be removed as a dependency.
- `#4562 <https://github.com/pytest-dev/pytest/issues/4562>`_: Deprecate configuring hook specs/impls using attributes/marks.
Instead use :py:func:`pytest.hookimpl` and :py:func:`pytest.hookspec`.
For more details, see the :ref:`docs <legacy-path-hooks-deprecated>`.
- `#9886 <https://github.com/pytest-dev/pytest/issues/9886>`_: The functionality for running tests written for ``nose`` has been officially deprecated.
This includes:
* Plain ``setup`` and ``teardown`` functions and methods: this might catch users by surprise, as ``setup()`` and ``teardown()`` are not pytest idioms, but part of the ``nose`` support.
* Setup/teardown using the `@with_setup <with-setup-nose>`_ decorator.
For more details, consult the :ref:`deprecation docs <nose-deprecation>`.
.. _`with-setup-nose`: https://nose.readthedocs.io/en/latest/testing_tools.html?highlight=with_setup#nose.tools.with_setup
- `#7337 <https://github.com/pytest-dev/pytest/issues/7337>`_: A deprecation warning is now emitted if a test function returns something other than `None`. This prevents a common mistake among beginners that expect that returning a `bool` (for example `return foo(a, b) == result`) would cause a test to pass or fail, instead of using `assert`. The plan is to make returning non-`None` from tests an error in the future.
Features
--------
- `#9897 <https://github.com/pytest-dev/pytest/issues/9897>`_: Added shell-style wildcard support to ``testpaths``.
Improvements
------------
- `#10218 <https://github.com/pytest-dev/pytest/issues/10218>`_: ``@pytest.mark.parametrize()`` (and similar functions) now accepts any ``Sequence[str]`` for the argument names,
instead of just ``list[str]`` and ``tuple[str, ...]``.
(Note that ``str``, which is itself a ``Sequence[str]``, is still treated as a
comma-delimited name list, as before).
- `#10381 <https://github.com/pytest-dev/pytest/issues/10381>`_: The ``--no-showlocals`` flag has been added. This can be passed directly to tests to override ``--showlocals`` declared through ``addopts``.
- `#3426 <https://github.com/pytest-dev/pytest/issues/3426>`_: Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expressed instead.
- `#8508 <https://github.com/pytest-dev/pytest/issues/8508>`_: Introduce multiline display for warning matching via :py:func:`pytest.warns` and
enhance match comparison for :py:func:`_pytest._code.ExceptionInfo.match` as returned by :py:func:`pytest.raises`.
- `#8646 <https://github.com/pytest-dev/pytest/issues/8646>`_: Improve :py:func:`pytest.raises`. Previously passing an empty tuple would give a confusing
error. We now raise immediately with a more helpful message.
- `#9741 <https://github.com/pytest-dev/pytest/issues/9741>`_: On Python 3.11, use the standard library's :mod:`tomllib` to parse TOML.
:mod:`tomli` is no longer a dependency on Python 3.11.
- `#9742 <https://github.com/pytest-dev/pytest/issues/9742>`_: Display assertion message without escaped newline characters with ``-vv``.
- `#9823 <https://github.com/pytest-dev/pytest/issues/9823>`_: Improved error message that is shown when no collector is found for a given file.
- `#9873 <https://github.com/pytest-dev/pytest/issues/9873>`_: Some coloring has been added to the short test summary.
- `#9883 <https://github.com/pytest-dev/pytest/issues/9883>`_: Normalize the help description of all command-line options.
- `#9920 <https://github.com/pytest-dev/pytest/issues/9920>`_: Display full crash messages in ``short test summary info``, when running in a CI environment.
- `#9987 <https://github.com/pytest-dev/pytest/issues/9987>`_: Added support for hidden configuration file by allowing ``.pytest.ini`` as an alternative to ``pytest.ini``.
Bug Fixes
---------
- `#10150 <https://github.com/pytest-dev/pytest/issues/10150>`_: :data:`sys.stdin` now contains all expected methods of a file-like object when capture is enabled.
- `#10382 <https://github.com/pytest-dev/pytest/issues/10382>`_: Do not break into pdb when ``raise unittest.SkipTest()`` appears top-level in a file.
- `#7792 <https://github.com/pytest-dev/pytest/issues/7792>`_: Marks are now inherited according to the full MRO in test classes. Previously, if a test class inherited from two or more classes, only marks from the first super-class would apply.
When inheriting marks from super-classes, marks from the sub-classes are now ordered before marks from the super-classes, in MRO order. Previously it was the reverse.
When inheriting marks from super-classes, the `pytestmark` attribute of the sub-class now only contains the marks directly applied to it. Previously, it also contained marks from its super-classes. Please note that this attribute should not normally be accessed directly; use :func:`pytest.Node.iter_markers` instead.
- `#9159 <https://github.com/pytest-dev/pytest/issues/9159>`_: Showing inner exceptions by forcing native display in ``ExceptionGroups`` even when using display options other than ``--tb=native``. A temporary step before full implementation of pytest-native display for inner exceptions in ``ExceptionGroups``.
- `#9877 <https://github.com/pytest-dev/pytest/issues/9877>`_: Ensure ``caplog.get_records(when)`` returns current/correct data after invoking ``caplog.clear()``.
Improved Documentation
----------------------
- `#10344 <https://github.com/pytest-dev/pytest/issues/10344>`_: Update information on writing plugins to use ``pyproject.toml`` instead of ``setup.py``.
- `#9248 <https://github.com/pytest-dev/pytest/issues/9248>`_: The documentation is now built using Sphinx 5.x (up from 3.x previously).
- `#9291 <https://github.com/pytest-dev/pytest/issues/9291>`_: Update documentation on how :func:`pytest.warns` affects :class:`DeprecationWarning`.
Trivial/Internal Changes
------------------------
- `#10313 <https://github.com/pytest-dev/pytest/issues/10313>`_: Made ``_pytest.doctest.DoctestItem`` export ``pytest.DoctestItem`` for
type check and runtime purposes. Made `_pytest.doctest` use internal APIs
to avoid circular imports.
- `#9906 <https://github.com/pytest-dev/pytest/issues/9906>`_: Made ``_pytest.compat`` re-export ``importlib_metadata`` in the eyes of type checkers.
- `#9910 <https://github.com/pytest-dev/pytest/issues/9910>`_: Fix default encoding warning (``EncodingWarning``) in ``cacheprovider``
- `#9984 <https://github.com/pytest-dev/pytest/issues/9984>`_: Improve the error message when we attempt to access a fixture that has been
torn down.
Add an additional sentence to the docstring explaining when it's not a good
idea to call ``getfixturevalue``.
pytest 7.1.3 (2022-08-31)
=========================

View File

@@ -17,7 +17,7 @@ def b(a, order):
@pytest.fixture
def c(a, b, order):
def c(b, order):
order.append("c")

View File

@@ -246,9 +246,9 @@ You can ask which markers exist for your test suite - the list includes our just
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see https://docs.pytest.org/en/stable/explanation/fixtures.html#usefixtures
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. DEPRECATED, use @pytest.hookimpl(tryfirst=True) instead.
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. DEPRECATED, use @pytest.hookimpl(trylast=True) instead.
For an example on how to add and work with markers from a plugin, see
@@ -438,9 +438,9 @@ The ``--markers`` option always gives you a list of available markers:
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see https://docs.pytest.org/en/stable/explanation/fixtures.html#usefixtures
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. DEPRECATED, use @pytest.hookimpl(tryfirst=True) instead.
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. DEPRECATED, use @pytest.hookimpl(trylast=True) instead.
.. _`passing callables to custom markers`:
@@ -611,7 +611,7 @@ then you will see two tests skipped and two executed tests as expected:
test_plat.py s.s. [100%]
========================= short test summary info ==========================
SKIPPED [2] conftest.py:12: cannot run on platform linux
SKIPPED [2] conftest.py:13: cannot run on platform linux
======================= 2 passed, 2 skipped in 0.12s =======================
Note that if you specify a platform via the marker-command line option like this:

View File

@@ -504,9 +504,9 @@ Running it results in some skips if we don't have all the python interpreters in
. $ pytest -rs -q multipython.py
sssssssssssssssssssssssssss [100%]
========================= short test summary info ==========================
SKIPPED [9] multipython.py:29: 'python3.5' not found
SKIPPED [9] multipython.py:29: 'python3.6' not found
SKIPPED [9] multipython.py:29: 'python3.7' not found
SKIPPED [9] multipython.py:69: 'python3.5' not found
SKIPPED [9] multipython.py:69: 'python3.6' not found
SKIPPED [9] multipython.py:69: 'python3.7' not found
27 skipped in 0.12s
Indirect parametrization of optional implementations/imports
@@ -574,7 +574,7 @@ If you run this with reporting for skips enabled:
test_module.py .s [100%]
========================= short test summary info ==========================
SKIPPED [1] conftest.py:12: could not import 'opt2': No module named 'opt2'
SKIPPED [1] test_module.py:3: could not import 'opt2': No module named 'opt2'
======================= 1 passed, 1 skipped in 0.12s =======================
You'll see that we don't have an ``opt2`` module and thus the second test run

View File

@@ -661,8 +661,7 @@ If we run this:
test_step.py:11: AssertionError
========================= short test summary info ==========================
XFAIL test_step.py::TestUserHandling::test_deletion
reason: previous test failed (test_modification)
XFAIL test_step.py::TestUserHandling::test_deletion - reason: previous test failed (test_modification)
================== 1 failed, 2 passed, 1 xfailed in 0.12s ==================
We'll see that ``test_deletion`` was not executed because ``test_modification``

View File

@@ -270,8 +270,8 @@ tox
Once you are done with your work and want to make sure that your actual
package passes all tests you may want to look into :doc:`tox <tox:index>`, the
virtualenv test automation tool and its :doc:`pytest support <tox:example/pytest>`.
tox helps you to setup virtualenv environments with pre-defined
virtualenv test automation tool.
``tox`` helps you to setup virtualenv environments with pre-defined
dependencies and then executing a pre-configured test command with
options. It will run tests against the installed package and not
against your source code checkout, helping to detect packaging

View File

@@ -16,7 +16,7 @@ import process can be controlled through the ``--import-mode`` command-line flag
these values:
* ``prepend`` (default): the directory path containing each module will be inserted into the *beginning*
of :py:data:`sys.path` if not already there, and then imported with the :func:`__import__ <__import__>` builtin.
of :py:data:`sys.path` if not already there, and then imported with the :func:`importlib.import_module <importlib.import_module>` function.
This requires test module names to be unique when the test directory tree is not arranged in
packages, because the modules will put in :py:data:`sys.modules` after importing.
@@ -24,7 +24,7 @@ these values:
This is the classic mechanism, dating back from the time Python 2 was still supported.
* ``append``: the directory containing each module is appended to the end of :py:data:`sys.path` if not already
there, and imported with ``__import__``.
there, and imported with :func:`importlib.import_module <importlib.import_module>`.
This better allows to run test modules against installed versions of a package even if the
package under test has the same import root. For example:
@@ -43,7 +43,7 @@ these values:
Same as ``prepend``, requires test module names to be unique when the test directory tree is
not arranged in packages, because the modules will put in :py:data:`sys.modules` after importing.
* ``importlib``: new in pytest-6.0, this mode uses :mod:`importlib` to import test modules. This gives full control over the import process, and doesn't require changing :py:data:`sys.path`.
* ``importlib``: new in pytest-6.0, this mode uses more fine control mechanisms provided by :mod:`importlib` to import test modules. This gives full control over the import process, and doesn't require changing :py:data:`sys.path`.
For this reason this doesn't require test module names to be unique.

View File

@@ -22,7 +22,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 7.1.3
pytest 7.2.2
.. _`simpletest`:

View File

@@ -233,7 +233,7 @@ 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:20: AssertionError
test_caching.py:19: AssertionError
-------------------------- Captured stdout setup ---------------------------
running expensive computation...
========================= short test summary info ==========================
@@ -256,7 +256,7 @@ the cache and nothing will be printed:
> assert mydata == 23
E assert 42 == 23
test_caching.py:20: AssertionError
test_caching.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_caching.py::test_function - assert 42 == 23
1 failed in 0.12s

View File

@@ -109,6 +109,18 @@ When a warning matches more than one option in the list, the action for the last
is performed.
.. note::
The ``-W`` flag and the ``filterwarnings`` ini option use warning filters that are
similar in structure, but each configuration option interprets its filter
differently. For example, *message* in ``filterwarnings`` is a string containing a
regular expression that the start of the warning message must match,
case-insensitively, while *message* in ``-W`` is a literal string that the start of
the warning message must contain (case-insensitively), ignoring any whitespace at
the start or end of message. Consult the `warning filter`_ documentation for more
details.
.. _`filterwarnings`:
``@pytest.mark.filterwarnings``
@@ -270,20 +282,34 @@ which works in a similar manner to :ref:`raises <assertraises>` (except that
warnings.warn("my warning", UserWarning)
The test will fail if the warning in question is not raised. Use the keyword
argument ``match`` to assert that the warning matches a text or regex::
argument ``match`` to assert that the warning matches a text or regex.
To match a literal string that may contain regular expression metacharacters like ``(`` or ``.``, the pattern can
first be escaped with ``re.escape``.
>>> with warns(UserWarning, match='must be 0 or None'):
Some examples:
.. code-block:: pycon
>>> with warns(UserWarning, match="must be 0 or None"):
... warnings.warn("value must be 0 or None", UserWarning)
...
>>> with warns(UserWarning, match=r'must be \d+$'):
>>> with warns(UserWarning, match=r"must be \d+$"):
... warnings.warn("value must be 42", UserWarning)
...
>>> with warns(UserWarning, match=r'must be \d+$'):
>>> with warns(UserWarning, match=r"must be \d+$"):
... warnings.warn("this is not here", UserWarning)
...
Traceback (most recent call last):
...
Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...
>>> with warns(UserWarning, match=re.escape("issue with foo() func")):
... warnings.warn("issue with foo() func")
...
You can also call :func:`pytest.warns` on a function or code string:
.. code-block:: python

View File

@@ -349,8 +349,7 @@ Example:
test_example.py:14: AssertionError
========================= short test summary info ==========================
SKIPPED [1] test_example.py:22: skipping this test
XFAIL test_example.py::test_xfail
reason: xfailing 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 - assert 0
FAILED test_example.py::test_fail - assert 0

View File

@@ -157,7 +157,7 @@ the ``self.db`` values in the traceback:
E AssertionError: <conftest.db_class.<locals>.DummyDB object at 0xdeadbeef0001>
E assert 0
test_unittest_db.py:10: AssertionError
test_unittest_db.py:11: AssertionError
___________________________ MyTest.test_method2 ____________________________
self = <test_unittest_db.MyTest testMethod=test_method2>
@@ -167,7 +167,7 @@ the ``self.db`` values in the traceback:
E AssertionError: <conftest.db_class.<locals>.DummyDB object at 0xdeadbeef0001>
E assert 0
test_unittest_db.py:13: AssertionError
test_unittest_db.py:14: AssertionError
========================= short test summary info ==========================
FAILED test_unittest_db.py::MyTest::test_method1 - AssertionError: <conft...
FAILED test_unittest_db.py::MyTest::test_method2 - AssertionError: <conft...

View File

@@ -167,13 +167,8 @@ it in your ``pyproject.toml`` file.
"Framework :: Pytest",
]
[tool.setuptools]
packages = ["myproject"]
[project.entry_points]
pytest11 = [
"myproject = myproject.pluginmodule",
]
[project.entry-points.pytest11]
myproject = "myproject.pluginmodule"
If a package is installed this way, ``pytest`` will load
``myproject.pluginmodule`` as a plugin which can define

View File

@@ -2,8 +2,7 @@
.. sidebar:: Next Open Trainings
- Professionelles Testen für Python mit pytest, part of `enterPy <https://www.enterpy.de/>`__ (German), `October 28th <https://www.enterpy.de/veranstaltung-15409-se-0-professionelles-testen-fuer-python-mit-pytest.html>`__ (sold out) and `November 4th <https://www.enterpy.de/veranstaltung-15557-se-0-professionelles-testen-fuer-python-mit-pytest-zusatztermin.html>`__, online
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 7th to 9th 2023 (3 day in-depth training), Remote and Leipzig, Germany
- `Professional Testing with Python <https://python-academy.com/courses/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, March 7th to 9th 2023 (3 day in-depth training), Remote
Also see :doc:`previous talks and blogposts <talks>`.

View File

@@ -335,7 +335,7 @@ For example:
.. literalinclude:: /example/fixtures/test_fixtures_order_dependencies.py
If we map out what depends on what, we get something that look like this:
If we map out what depends on what, we get something that looks like this:
.. image:: /example/fixtures/test_fixtures_order_dependencies.*
:align: center

View File

@@ -1047,6 +1047,14 @@ Environment Variables
Environment variables that can be used to change pytest's behavior.
.. envvar:: CI
When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to ``BUILD_NUMBER`` variable.
.. envvar:: BUILD_NUMBER
When set (regardless of value), pytest acknowledges that is running in a CI process. Alterative to CI variable.
.. envvar:: PYTEST_ADDOPTS
This contains a command-line (parsed by the py:mod:`shlex` module) that will be **prepended** to the command line given
@@ -1759,12 +1767,12 @@ All the command-line flags can be obtained by running ``pytest --help``::
$ pytest --help
usage: pytest [options] [file_or_dir] [file_or_dir] [...]
Positional arguments:
positional arguments:
file_or_dir
General:
general:
-k EXPRESSION Only run tests which match the given substring
expression. An expression is a python evaluatable
expression. An expression is a Python evaluatable
expression where all names are substring-matched
against test names and their parent classes.
Example: -k 'test_method or test_other' matches all
@@ -1778,9 +1786,9 @@ All the command-line flags can be obtained by running ``pytest --help``::
'extra_keyword_matches' set, as well as functions
which have names assigned directly to them. The
matching is case-insensitive.
-m MARKEXPR Only run tests matching given mark expression.
For example: -m 'mark1 and not mark2'.
--markers Show markers (builtin, plugin and per-project ones)
-m MARKEXPR Only run tests matching given mark expression. For
example: -m 'mark1 and not mark2'.
--markers show markers (builtin, plugin and per-project ones).
-x, --exitfirst Exit instantly on first error or failed test
--fixtures, --funcargs
Show available fixtures, sorted by plugin appearance
@@ -1790,18 +1798,18 @@ All the command-line flags can be obtained by running ``pytest --help``::
KeyboardInterrupt
--pdbcls=modulename:classname
Specify a custom interactive Python debugger for use
with --pdb. For example:
with --pdb.For example:
--pdbcls=IPython.terminal.debugger:TerminalPdb
--trace Immediately break when running each test
--capture=method Per-test capturing method: one of fd|sys|no|tee-sys.
-s Shortcut for --capture=no.
--capture=method Per-test capturing method: one of fd|sys|no|tee-sys
-s Shortcut for --capture=no
--runxfail Report the results of xfail tests as if they were
not marked
--lf, --last-failed Rerun only the tests that failed at the last run (or
all if none failed)
--ff, --failed-first Run all tests, but run the last failures first
This may re-order tests and thus lead to repeated
fixture setup/teardown
--ff, --failed-first Run all tests, but run the last failures first. This
may re-order tests and thus lead to repeated fixture
setup/teardown.
--nf, --new-first Run tests from new files first, then the rest of the
tests sorted by file mtime
--cache-show=[CACHESHOW]
@@ -1815,11 +1823,10 @@ All the command-line flags can be obtained by running ``pytest --help``::
test next time
--sw-skip, --stepwise-skip
Ignore the first failing test but stop on the next
failing test.
implicitly enables --stepwise.
failing test. Implicitly enables --stepwise.
Reporting:
--durations=N show N slowest setup/test durations (N=0 for all)
--durations=N Show N slowest setup/test durations (N=0 for all)
--durations-min=N Minimal duration in seconds for inclusion in slowest
list. Default: 0.005.
-v, --verbose Increase verbosity
@@ -1836,8 +1843,10 @@ All the command-line flags can be obtained by running ``pytest --help``::
--disable-warnings, --disable-pytest-warnings
Disable warnings summary
-l, --showlocals Show locals in tracebacks (disabled by default)
--no-showlocals Hide locals in tracebacks (negate --showlocals
passed through addopts)
--tb=style Traceback print mode
(auto/long/short/line/native/no).
(auto/long/short/line/native/no)
--show-capture={no,stdout,stderr,log,all}
Controls how captured stdout/stderr/log is shown on
failed tests. Default: all.
@@ -1863,15 +1872,14 @@ All the command-line flags can be obtained by running ``pytest --help``::
-c file Load configuration from `file` instead of trying to
locate one of the implicit configuration files
--continue-on-collection-errors
Force test execution even if collection errors
occur
Force test execution even if collection errors occur
--rootdir=ROOTDIR Define root directory for tests. Can be relative
path: 'root_dir', './root_dir',
'root_dir/another_dir/'; absolute path:
'/home/user/root_dir'; path with variables:
'$HOME/root_dir'.
Collection:
collection:
--collect-only, --co Only collect tests, don't execute them
--pyargs Try to interpret all arguments as Python packages
--ignore=path Ignore path during collection (multi-allowed)
@@ -1899,27 +1907,24 @@ All the command-line flags can be obtained by running ``pytest --help``::
For a given doctest, continue to run after the first
failure
Test session debugging and configuration:
--basetemp=dir Base temporary directory for this test run. (Warning:
this directory is removed if it exists.)
test session debugging and configuration:
--basetemp=dir Base temporary directory for this test run.
(Warning: this directory is removed if it exists.)
-V, --version Display pytest version and information about
plugins. When given twice, also display information
about plugins.
-h, --help Show help message and configuration info
-p name Early-load given plugin module name or entry point
(multi-allowed)
To avoid loading of plugins, use the `no:` prefix,
e.g. `no:doctest`
(multi-allowed). To avoid loading of plugins, use
the `no:` prefix, e.g. `no:doctest`.
--trace-config Trace considerations of conftest.py files
--debug=[DEBUG_FILE_NAME]
Store internal tracing debug information in this log
file.
This file is opened with 'w' and truncated as a
result, care advised.
Default: pytestdebug.log.
file. This file is opened with 'w' and truncated as
a result, care advised. Default: pytestdebug.log.
-o OVERRIDE_INI, --override-ini=OVERRIDE_INI
Override ini option with "option=value" style, e.g.
`-o xfail_strict=True -o cache_dir=cache`
`-o xfail_strict=True -o cache_dir=cache`.
--assert=MODE Control assertion debugging tools.
'plain' performs no assertion debugging.
'rewrite' (the default) rewrites assert statements
@@ -1930,11 +1935,11 @@ All the command-line flags can be obtained by running ``pytest --help``::
--setup-plan Show what fixtures and tests would be executed but
don't execute anything
Logging:
--log-level=LEVEL Level of messages to catch/display.
Not set by default, so it depends on the root/parent
log handler's effective level, where it is "WARNING"
by default.
logging:
--log-level=LEVEL Level of messages to catch/display. Not set by
default, so it depends on the root/parent log
handler's effective level, where it is "WARNING" by
default.
--log-format=LOG_FORMAT
Log format used by the logging module
--log-date-format=LOG_DATE_FORMAT
@@ -1963,7 +1968,7 @@ All the command-line flags can be obtained by running ``pytest --help``::
Default marker for empty parametersets
norecursedirs (args): Directory patterns to avoid for recursion
testpaths (args): Directories to search for tests when no files or
directories are given in the command line
directories are given on the command line
filterwarnings (linelist):
Each line specifies a pattern for
warnings.filterwarnings. Processed after

View File

@@ -1,7 +1,11 @@
pallets-sphinx-themes
pluggy>=1.0
pygments-pytest>=2.2.0
pygments-pytest>=2.3.0
sphinx-removed-in>=0.2.0
sphinx>=5,<6
sphinxcontrib-trio
sphinxcontrib-svg2pdfconverter
# Pin packaging because it no longer handles 'latest' version, which
# is the version that is assigned to the docs.
# See https://github.com/pytest-dev/pytest/pull/10578#issuecomment-1348249045.
packaging <22

View File

@@ -114,3 +114,8 @@ template = "changelog/_template.rst"
[tool.black]
target-version = ['py37']
# check-wheel-contents is executed by the build-and-inspect-python-package action.
[tool.check-wheel-contents]
# W009: Wheel contains multiple toplevel library entries
ignore = "W009"

View File

@@ -21,6 +21,7 @@ classifiers =
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Topic :: Software Development :: Libraries
Topic :: Software Development :: Testing
Topic :: Utilities

View File

@@ -275,7 +275,12 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader)
if sys.version_info >= (3, 10):
def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore
if sys.version_info >= (3, 12):
from importlib.resources.abc import TraversableResources
else:
from importlib.abc import TraversableResources
def get_resource_reader(self, name: str) -> TraversableResources: # type: ignore
if sys.version_info < (3, 11):
from importlib.readers import FileReader
else:

View File

@@ -32,7 +32,6 @@ from _pytest.python import Module
from _pytest.python import Package
from _pytest.reports import TestReport
README_CONTENT = """\
# pytest cache directory #
@@ -492,7 +491,7 @@ def pytest_addoption(parser: Parser) -> None:
def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
if config.option.cacheshow:
if config.option.cacheshow and not config.option.help:
from _pytest.main import wrap_session
return wrap_session(config, cacheshow)

View File

@@ -998,6 +998,8 @@ class Config:
self.hook.pytest_addoption.call_historic(
kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager)
)
self.args_source = Config.ArgsSource.ARGS
self.args: List[str] = []
if TYPE_CHECKING:
from _pytest.cacheprovider import Cache
@@ -1337,8 +1339,8 @@ class Config:
def parse(self, args: List[str], addopts: bool = True) -> None:
# Parse given cmdline arguments into this config object.
assert not hasattr(
self, "args"
assert (
self.args == []
), "can only parse cmdline args at most once per Config object"
self.hook.pytest_addhooks.call_historic(
kwargs=dict(pluginmanager=self.pluginmanager)

View File

@@ -203,8 +203,7 @@ def determine_setup(
else:
cwd = Path.cwd()
rootdir = get_common_ancestor([cwd, ancestor])
is_fs_root = os.path.splitdrive(str(rootdir))[1] == "/"
if is_fs_root:
if is_fs_root(rootdir):
rootdir = ancestor
if rootdir_cmd_arg:
rootdir = absolutepath(os.path.expandvars(rootdir_cmd_arg))
@@ -216,3 +215,11 @@ def determine_setup(
)
assert rootdir is not None
return rootdir, inipath, inicfg or {}
def is_fs_root(p: Path) -> bool:
r"""
Return True if the given path is pointing to the root of the
file system ("/" on Unix and "C:\\" on Windows for example).
"""
return os.path.splitdrive(str(p))[1] == os.sep

View File

@@ -58,6 +58,7 @@ from _pytest.mark import Mark
from _pytest.mark import ParameterSet
from _pytest.mark.structures import MarkDecorator
from _pytest.outcomes import fail
from _pytest.outcomes import skip
from _pytest.outcomes import TEST_OUTCOME
from _pytest.pathlib import absolutepath
from _pytest.pathlib import bestrelpath
@@ -1129,6 +1130,10 @@ def pytest_fixture_setup(
except TEST_OUTCOME:
exc_info = sys.exc_info()
assert exc_info[0] is not None
if isinstance(
exc_info[1], skip.Exception
) and not fixturefunc.__name__.startswith("xunit_setup"):
exc_info[1]._use_item_location = True # type: ignore[attr-defined]
fixturedef.cached_result = (None, my_cache_key, exc_info)
raise
fixturedef.cached_result = (result, my_cache_key, None)

View File

@@ -645,8 +645,8 @@ class LogXML:
def pytest_sessionfinish(self) -> None:
dirname = os.path.dirname(os.path.abspath(self.logfile))
if not os.path.isdir(dirname):
os.makedirs(dirname)
# exist_ok avoids filesystem race conditions between checking path existence and requesting creation
os.makedirs(dirname, exist_ok=True)
with open(self.logfile, "w", encoding="utf-8") as logfile:
suite_stop_time = timing.time()

View File

@@ -157,8 +157,12 @@ def skip(
The message to show the user as reason for the skip.
:param allow_module_level:
Allows this function to be called at module level, skipping the rest
of the module. Defaults to False.
Allows this function to be called at module level.
Raising the skip exception at module level will stop
the execution of the module and prevent the collection of all tests in the module,
even those defined before the `skip` call.
Defaults to False.
:param msg:
Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead.

View File

@@ -464,14 +464,14 @@ def import_path(
* `mode == ImportMode.prepend`: the directory containing the module (or package, taking
`__init__.py` files into account) will be put at the *start* of `sys.path` before
being imported with `__import__.
being imported with `importlib.import_module`.
* `mode == ImportMode.append`: same as `prepend`, but the directory will be appended
to the end of `sys.path`, if not already in `sys.path`.
* `mode == ImportMode.importlib`: uses more fine control mechanisms provided by `importlib`
to import the module, which avoids having to use `__import__` and muck with `sys.path`
at all. It effectively allows having same-named test modules in different places.
to import the module, which avoids having to muck with `sys.path` at all. It effectively
allows having same-named test modules in different places.
:param root:
Used as an anchor when mode == ImportMode.importlib to obtain

View File

@@ -848,7 +848,7 @@ class Class(PyCollector):
other fixtures (#517).
"""
setup_class = _get_first_non_fixture_func(self.obj, ("setup_class",))
teardown_class = getattr(self.obj, "teardown_class", None)
teardown_class = _get_first_non_fixture_func(self.obj, ("teardown_class",))
if setup_class is None and teardown_class is None:
return
@@ -885,12 +885,12 @@ class Class(PyCollector):
emit_nose_setup_warning = True
setup_method = _get_first_non_fixture_func(self.obj, (setup_name,))
teardown_name = "teardown_method"
teardown_method = getattr(self.obj, teardown_name, None)
teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,))
emit_nose_teardown_warning = False
if teardown_method is None and has_nose:
teardown_name = "teardown"
emit_nose_teardown_warning = True
teardown_method = getattr(self.obj, teardown_name, None)
teardown_method = _get_first_non_fixture_func(self.obj, (teardown_name,))
if setup_method is None and teardown_method is None:
return

View File

@@ -8,7 +8,7 @@ from types import TracebackType
from typing import Any
from typing import Callable
from typing import cast
from typing import Generic
from typing import ContextManager
from typing import List
from typing import Mapping
from typing import Optional
@@ -269,10 +269,16 @@ class ApproxMapping(ApproxBase):
max_abs_diff = max(
max_abs_diff, abs(approx_value.expected - other_value)
)
max_rel_diff = max(
max_rel_diff,
abs((approx_value.expected - other_value) / approx_value.expected),
)
if approx_value.expected == 0.0:
max_rel_diff = math.inf
else:
max_rel_diff = max(
max_rel_diff,
abs(
(approx_value.expected - other_value)
/ approx_value.expected
),
)
different_ids.append(approx_key)
message_data = [
@@ -957,7 +963,7 @@ raises.Exception = fail.Exception # type: ignore
@final
class RaisesContext(Generic[E]):
class RaisesContext(ContextManager[_pytest._code.ExceptionInfo[E]]):
def __init__(
self,
expected_exception: Union[Type[E], Tuple[Type[E], ...]],

View File

@@ -48,6 +48,10 @@ def pytest_configure(config: Config) -> None:
def pytest_sessionfinish(session: Session) -> None:
if not session.config.getoption("stepwise"):
assert session.config.cache is not None
if hasattr(session.config, "workerinput"):
# Do not update cache if this process is a xdist worker to prevent
# race conditions (#10641).
return
# Clear the list of failing tests if the plugin is not active.
session.config.cache.set(STEPWISE_CACHE_DIR, [])
@@ -119,4 +123,8 @@ class StepwisePlugin:
return None
def pytest_sessionfinish(self) -> None:
if hasattr(self.config, "workerinput"):
# Do not update cache if this process is a xdist worker to prevent
# race conditions (#10641).
return
self.cache.set(STEPWISE_CACHE_DIR, self.lastfailed)

View File

@@ -694,7 +694,14 @@ class TestInvocationVariants:
# mixed module and filenames:
monkeypatch.chdir("world")
result = pytester.runpytest("--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world")
# pgk_resources.declare_namespace has been deprecated in favor of implicit namespace packages.
# While we could change the test to use implicit namespace packages, seems better
# to still ensure the old declaration via declare_namespace still works.
ignore_w = r"-Wignore:Deprecated call to `pkg_resources.declare_namespace"
result = pytester.runpytest(
"--pyargs", "-v", "ns_pkg.hello", "ns_pkg/world", ignore_w
)
assert result.ret == 0
result.stdout.fnmatch_lines(
[

View File

@@ -157,6 +157,7 @@ def color_mapping():
"number": "\x1b[94m",
"str": "\x1b[33m",
"print": "\x1b[96m",
"endline": "\x1b[90m\x1b[39;49;00m",
}
RE_COLORS = {k: re.escape(v) for k, v in COLORS.items()}

View File

@@ -254,7 +254,7 @@ class TestTerminalWriterLineWidth:
pytest.param(
True,
True,
"{kw}assert{hl-reset} {number}0{hl-reset}\n",
"{kw}assert{hl-reset} {number}0{hl-reset}{endline}\n",
id="with markup and code_highlight",
),
pytest.param(

View File

@@ -630,6 +630,19 @@ class TestApprox:
def test_dict_vs_other(self):
assert 1 != approx({"a": 0})
def test_dict_for_div_by_zero(self, assert_approx_raises_regex):
assert_approx_raises_regex(
{"foo": 42.0},
{"foo": 0.0},
[
r" comparison failed. Mismatched elements: 1 / 1:",
rf" Max absolute difference: {SOME_FLOAT}",
r" Max relative difference: inf",
r" Index \| Obtained\s+\| Expected ",
rf" foo | {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
],
)
def test_numpy_array(self):
np = pytest.importorskip("numpy")

View File

@@ -3338,6 +3338,10 @@ class TestShowFixtures:
config = pytester.parseconfigure("--funcargs")
assert config.option.showfixtures
def test_show_help(self, pytester: Pytester) -> None:
result = pytester.runpytest("--fixtures", "--help")
assert not result.ret
def test_show_fixtures(self, pytester: Pytester) -> None:
result = pytester.runpytest("--fixtures")
result.stdout.fnmatch_lines(

View File

@@ -1664,15 +1664,7 @@ def test_raise_assertion_error_raising_repr(pytester: Pytester) -> None:
"""
)
result = pytester.runpytest()
if sys.version_info >= (3, 11):
# python 3.11 has native support for un-str-able exceptions
result.stdout.fnmatch_lines(
["E AssertionError: <exception str() failed>"]
)
else:
result.stdout.fnmatch_lines(
["E AssertionError: <unprintable AssertionError object>"]
)
result.stdout.fnmatch_lines(["E AssertionError: <exception str() failed>"])
def test_issue_1944(pytester: Pytester) -> None:

View File

@@ -1249,3 +1249,8 @@ def test_cachedir_tag(pytester: Pytester) -> None:
cache.set("foo", "bar")
cachedir_tag_path = cache._cachedir.joinpath("CACHEDIR.TAG")
assert cachedir_tag_path.read_bytes() == CACHEDIR_TAG_CONTENT
def test_clioption_with_cacheshow_and_help(pytester: Pytester) -> None:
result = pytester.runpytest("--cache-show", "--help")
assert result.ret == 0

View File

@@ -1,3 +1,4 @@
import os
from pathlib import Path
from textwrap import dedent
@@ -5,6 +6,7 @@ import pytest
from _pytest.config import UsageError
from _pytest.config.findpaths import get_common_ancestor
from _pytest.config.findpaths import get_dirs_from_args
from _pytest.config.findpaths import is_fs_root
from _pytest.config.findpaths import load_config_dict_from_file
@@ -133,3 +135,18 @@ def test_get_dirs_from_args(tmp_path):
assert get_dirs_from_args(
[str(fn), str(tmp_path / "does_not_exist"), str(d), option, xdist_rsync_option]
) == [fn.parent, d]
@pytest.mark.parametrize(
"path, expected",
[
pytest.param(
f"e:{os.sep}", True, marks=pytest.mark.skipif("sys.platform != 'win32'")
),
(f"{os.sep}", True),
(f"e:{os.sep}projects", False),
(f"{os.sep}projects", False),
],
)
def test_is_fs_root(path: Path, expected: bool) -> None:
assert is_fs_root(Path(path)) is expected

View File

@@ -425,6 +425,9 @@ def test_context_classmethod() -> None:
assert A.x == 1
@pytest.mark.filterwarnings(
"ignore:Deprecated call to `pkg_resources.declare_namespace"
)
def test_syspath_prepend_with_namespace_packages(
pytester: Pytester, monkeypatch: MonkeyPatch
) -> None:

View File

@@ -496,3 +496,24 @@ def test_nose_setup_skipped_if_non_callable(pytester: Pytester) -> None:
)
result = pytester.runpytest(p, "-p", "nose")
assert result.ret == 0
@pytest.mark.parametrize("fixture_name", ("teardown", "teardown_class"))
def test_teardown_fixture_not_called_directly(fixture_name, pytester: Pytester) -> None:
"""Regression test for #10597."""
p = pytester.makepyfile(
f"""
import pytest
class TestHello:
@pytest.fixture
def {fixture_name}(self):
yield
def test_hello(self, {fixture_name}):
assert True
"""
)
result = pytester.runpytest(p, "-p", "nose")
assert result.ret == 0

View File

@@ -1439,6 +1439,27 @@ def test_relpath_rootdir(pytester: Pytester) -> None:
)
def test_skip_from_fixture(pytester: Pytester) -> None:
pytester.makepyfile(
**{
"tests/test_1.py": """
import pytest
def test_pass(arg):
pass
@pytest.fixture
def arg():
condition = True
if condition:
pytest.skip("Fixture conditional skip")
""",
}
)
result = pytester.runpytest("-rs", "tests/test_1.py", "--rootdir=tests")
result.stdout.fnmatch_lines(
["SKIPPED [[]1[]] tests/test_1.py:2: Fixture conditional skip"]
)
def test_skip_using_reason_works_ok(pytester: Pytester) -> None:
p = pytester.makepyfile(
"""

View File

@@ -1,6 +1,10 @@
from pathlib import Path
import pytest
from _pytest.cacheprovider import Cache
from _pytest.monkeypatch import MonkeyPatch
from _pytest.pytester import Pytester
from _pytest.stepwise import STEPWISE_CACHE_DIR
@pytest.fixture
@@ -278,3 +282,76 @@ def test_stepwise_skip_is_independent(pytester: Pytester) -> None:
def test_sw_skip_help(pytester: Pytester) -> None:
result = pytester.runpytest("-h")
result.stdout.fnmatch_lines("*Implicitly enables --stepwise.")
def test_stepwise_xdist_dont_store_lastfailed(pytester: Pytester) -> None:
pytester.makefile(
ext=".ini",
pytest=f"[pytest]\ncache_dir = {pytester.path}\n",
)
pytester.makepyfile(
conftest="""
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config) -> None:
config.workerinput = True
"""
)
pytester.makepyfile(
test_one="""
def test_one():
assert False
"""
)
result = pytester.runpytest("--stepwise")
assert result.ret == pytest.ExitCode.INTERRUPTED
stepwise_cache_file = (
pytester.path / Cache._CACHE_PREFIX_VALUES / STEPWISE_CACHE_DIR
)
assert not Path(stepwise_cache_file).exists()
def test_disabled_stepwise_xdist_dont_clear_cache(pytester: Pytester) -> None:
pytester.makefile(
ext=".ini",
pytest=f"[pytest]\ncache_dir = {pytester.path}\n",
)
stepwise_cache_file = (
pytester.path / Cache._CACHE_PREFIX_VALUES / STEPWISE_CACHE_DIR
)
stepwise_cache_dir = stepwise_cache_file.parent
stepwise_cache_dir.mkdir(exist_ok=True, parents=True)
stepwise_cache_file_relative = f"{Cache._CACHE_PREFIX_VALUES}/{STEPWISE_CACHE_DIR}"
expected_value = '"test_one.py::test_one"'
content = {f"{stepwise_cache_file_relative}": expected_value}
pytester.makefile(ext="", **content)
pytester.makepyfile(
conftest="""
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config) -> None:
config.workerinput = True
"""
)
pytester.makepyfile(
test_one="""
def test_one():
assert True
"""
)
result = pytester.runpytest()
assert result.ret == 0
assert Path(stepwise_cache_file).exists()
with stepwise_cache_file.open() as file_handle:
observed_value = file_handle.readlines()
assert [expected_value] == observed_value

View File

@@ -1265,14 +1265,14 @@ def test_color_yes(pytester: Pytester, color_mapping) -> None:
"=*= FAILURES =*=",
"{red}{bold}_*_ test_this _*_{reset}",
"",
" {kw}def{hl-reset} {function}test_this{hl-reset}():",
"> fail()",
" {kw}def{hl-reset} {function}test_this{hl-reset}():{endline}",
"> fail(){endline}",
"",
"{bold}{red}test_color_yes.py{reset}:5: ",
"_ _ * _ _*",
"",
" {kw}def{hl-reset} {function}fail{hl-reset}():",
"> {kw}assert{hl-reset} {number}0{hl-reset}",
" {kw}def{hl-reset} {function}fail{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
"",
"{bold}{red}test_color_yes.py{reset}:2: AssertionError",
@@ -1292,9 +1292,9 @@ def test_color_yes(pytester: Pytester, color_mapping) -> None:
"=*= FAILURES =*=",
"{red}{bold}_*_ test_this _*_{reset}",
"{bold}{red}test_color_yes.py{reset}:5: in test_this",
" fail()",
" fail(){endline}",
"{bold}{red}test_color_yes.py{reset}:2: in fail",
" {kw}assert{hl-reset} {number}0{hl-reset}",
" {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
"{red}=*= {red}{bold}1 failed{reset}{red} in *s{reset}{red} =*={reset}",
]
@@ -2472,8 +2472,8 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}{endline}",
"{bold}{red}E assert 1 == 10{reset}",
]
)
@@ -2494,9 +2494,9 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
" {print}print{hl-reset}({str}'''{hl-reset}{str}{hl-reset}",
"> {str} {hl-reset}{str}'''{hl-reset}); {kw}assert{hl-reset} {number}0{hl-reset}",
"> {str} {hl-reset}{str}'''{hl-reset}); {kw}assert{hl-reset} {number}0{hl-reset}{endline}",
"{bold}{red}E assert 0{reset}",
]
)
@@ -2517,8 +2517,8 @@ class TestCodeHighlight:
result.stdout.fnmatch_lines(
color_mapping.format_for_fnmatch(
[
" {kw}def{hl-reset} {function}test_foo{hl-reset}():",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}",
" {kw}def{hl-reset} {function}test_foo{hl-reset}():{endline}",
"> {kw}assert{hl-reset} {number}1{hl-reset} == {number}10{hl-reset}{endline}",
"{bold}{red}E assert 1 == 10{reset}",
]
)

View File

@@ -3,6 +3,11 @@
This file is not executed, it is only checked by mypy to ensure that
none of the code triggers any mypy errors.
"""
import contextlib
from typing import Optional
from typing_extensions import assert_type
import pytest
@@ -22,3 +27,9 @@ def check_fixture_ids_callable() -> None:
@pytest.mark.parametrize("func", [str, int], ids=lambda x: str(x.__name__))
def check_parametrize_ids_callable(func) -> None:
pass
def check_raises_is_a_context_manager(val: bool) -> None:
with pytest.raises(RuntimeError) if val else contextlib.nullcontext() as excinfo:
pass
assert_type(excinfo, Optional[pytest.ExceptionInfo[RuntimeError]])

17
tox.ini
View File

@@ -9,6 +9,7 @@ envlist =
py39
py310
py311
py312
pypy3
py37-{pexpect,xdist,unittestextras,numpy,pluggymain,pylib}
doctesting
@@ -29,7 +30,11 @@ commands =
doctesting: {env:_PYTEST_TOX_COVERAGE_RUN:} pytest --doctest-modules --pyargs _pytest
coverage: coverage combine
coverage: coverage report -m
passenv = USER USERNAME COVERAGE_* PYTEST_ADDOPTS TERM SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
passenv =
COVERAGE_*
PYTEST_ADDOPTS
TERM
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
setenv =
_PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_DOCTESTING:} {env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_XDIST:}
@@ -92,13 +97,14 @@ commands =
[testenv:regen]
changedir = doc/en
basepython = python3
passenv = SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
passenv =
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST
deps =
dataclasses
PyYAML
regendoc>=0.8.1
sphinx
whitelist_externals =
allowlist_externals =
make
commands =
make regen
@@ -160,7 +166,10 @@ commands = python scripts/prepare-release-pr.py {posargs}
description = create GitHub release after deployment
basepython = python3
usedevelop = True
passenv = GH_RELEASE_NOTES_TOKEN GITHUB_REF GITHUB_REPOSITORY
passenv =
GH_RELEASE_NOTES_TOKEN
GITHUB_REF
GITHUB_REPOSITORY
deps =
github3.py
pypandoc