diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..54c74863f --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,56 @@ +name: deploy + +on: + push: + tags: + # These tags are protected, see: + # https://github.com/pytest-dev/pytest/settings/tag_protection + - "[0-9]+.[0-9]+.[0-9]+" + - "[0-9]+.[0-9]+.[0-9]+rc[0-9]+" + + +# Set permissions at the job level. +permissions: {} + +jobs: + + deploy: + if: github.repository == 'pytest-dev/pytest' + + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: write + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.7" + + - name: Install dependencies + 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 }} + + - name: Publish GitHub release notes + env: + GH_RELEASE_NOTES_TOKEN: ${{ github.token }} + run: | + sudo apt-get install pandoc + tox -e publish-gh-release-notes diff --git a/.github/workflows/main.yml b/.github/workflows/test.yml similarity index 80% rename from .github/workflows/main.yml rename to .github/workflows/test.yml index c8f216c41..0c5fda16e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: main +name: test on: push: @@ -37,6 +37,7 @@ jobs: "windows-py38", "windows-py39", "windows-py310", + "windows-py311", "ubuntu-py37", "ubuntu-py37-pluggy", @@ -44,6 +45,7 @@ jobs: "ubuntu-py38", "ubuntu-py39", "ubuntu-py310", + "ubuntu-py311", "ubuntu-pypy3", "macos-py37", @@ -75,9 +77,13 @@ jobs: os: windows-latest tox_env: "py39-xdist" - name: "windows-py310" - python: "3.10.1" + python: "3.10" os: windows-latest tox_env: "py310-xdist" + - name: "windows-py311" + python: "3.11-dev" + os: windows-latest + tox_env: "py311" - name: "ubuntu-py37" python: "3.7" @@ -101,9 +107,13 @@ jobs: os: ubuntu-latest tox_env: "py39-xdist" - name: "ubuntu-py310" - python: "3.10.1" + python: "3.10" os: ubuntu-latest tox_env: "py310-xdist" + - name: "ubuntu-py311" + python: "3.11-dev" + os: ubuntu-latest + tox_env: "py311" - name: "ubuntu-pypy3" python: "pypy-3.7" os: ubuntu-latest @@ -177,46 +187,3 @@ jobs: fail_ci_if_error: true files: ./coverage.xml verbose: true - - deploy: - if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') && github.repository == 'pytest-dev/pytest' - - runs-on: ubuntu-latest - timeout-minutes: 30 - permissions: - contents: write - - needs: [build] - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: "3.7" - - - name: Install dependencies - 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 }} - - - name: Publish GitHub release notes - env: - GH_RELEASE_NOTES_TOKEN: ${{ github.token }} - run: | - sudo apt-get install pandoc - tox -e publish-gh-release-notes diff --git a/.github/workflows/update-plugin-list.yml b/.github/workflows/update-plugin-list.yml index 17c6364f4..193469072 100644 --- a/.github/workflows/update-plugin-list.yml +++ b/.github/workflows/update-plugin-list.yml @@ -12,6 +12,7 @@ permissions: {} jobs: createPullRequest: + if: github.repository_owner == 'pytest-dev' runs-on: ubuntu-latest permissions: contents: write diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 125f5561d..261c525c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,14 @@ repos: - id: debug-statements exclude: _pytest/(debugging|hookspec).py language_version: python3 +- repo: https://github.com/myint/autoflake + rev: v1.4 + hooks: + - id: autoflake + name: autoflake + args: ["--in-place", "--remove-unused-variables", "--remove-all-unused-imports"] + language: python + files: \.py$ - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: @@ -29,12 +37,12 @@ repos: - flake8-typing-imports==1.12.0 - flake8-docstrings==1.5.0 - repo: https://github.com/asottile/reorder_python_imports - rev: v2.7.1 + rev: v3.0.1 hooks: - id: reorder-python-imports args: ['--application-directories=.:src', --py37-plus] - repo: https://github.com/asottile/pyupgrade - rev: v2.31.0 + rev: v2.31.1 hooks: - id: pyupgrade args: [--py37-plus] @@ -48,7 +56,7 @@ repos: hooks: - id: python-use-type-annotations - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.931 + rev: v0.940 hooks: - id: mypy files: ^(src/|testing/) diff --git a/AUTHORS b/AUTHORS index 9413f9c2e..69e71fa10 100644 --- a/AUTHORS +++ b/AUTHORS @@ -185,8 +185,10 @@ Katerina Koukiou Keri Volans Kevin Cox Kevin J. Foley +Kian Eliasi Kian-Meng Ang Kodi B. Arfer +Kojo Idrissa Kostis Anagnostopoulos Kristoffer Nordström Kyle Altendorf @@ -288,6 +290,7 @@ Ruaridh Williamson Russel Winder Ryan Wooden Saiprasad Kale +Samuel Colvin Samuel Dion-Girardeau Samuel Searles-Bryant Samuele Pedroni diff --git a/README.rst b/README.rst index f0fe35632..034034a40 100644 --- a/README.rst +++ b/README.rst @@ -20,8 +20,8 @@ :target: https://codecov.io/gh/pytest-dev/pytest :alt: Code coverage Status -.. image:: https://github.com/pytest-dev/pytest/workflows/main/badge.svg - :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Amain +.. image:: https://github.com/pytest-dev/pytest/workflows/test/badge.svg + :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Atest .. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main diff --git a/RELEASING.rst b/RELEASING.rst index 66775e7cf..b018dc489 100644 --- a/RELEASING.rst +++ b/RELEASING.rst @@ -142,7 +142,7 @@ Both automatic and manual processes described above follow the same steps from t Wait for the deploy to complete, then make sure it is `available on PyPI `_. -#. Merge the PR. +#. Merge the PR. **Make sure it's not squash-merged**, so that the tagged commit ends up in the main branch. #. Cherry-pick the CHANGELOG / announce files to the ``main`` branch:: diff --git a/changelog/8508.improvement.rst b/changelog/8508.improvement.rst new file mode 100644 index 000000000..36fb94582 --- /dev/null +++ b/changelog/8508.improvement.rst @@ -0,0 +1,2 @@ +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`. diff --git a/changelog/8838.breaking.rst b/changelog/8838.breaking.rst deleted file mode 100644 index f5c1fead8..000000000 --- a/changelog/8838.breaking.rst +++ /dev/null @@ -1,15 +0,0 @@ -As per our policy, the following features have been deprecated in the 6.X series and are now -removed: - -* ``pytest._fillfuncargs`` function. - -* ``pytest_warning_captured`` hook - use ``pytest_warning_recorded`` instead. - -* ``-k -foobar`` syntax - use ``-k 'not foobar'`` instead. - -* ``-k foobar:`` syntax. - -* ``pytest.collect`` module - import from ``pytest`` directly. - -For more information consult -`Deprecations and Removals `__ in the docs. diff --git a/changelog/9326.bugfix.rst b/changelog/9326.bugfix.rst deleted file mode 100644 index 1aaa424d3..000000000 --- a/changelog/9326.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Pytest will now avoid specialized assert formatting when it is detected that the default __eq__ is overridden diff --git a/changelog/9437.breaking.rst b/changelog/9437.breaking.rst deleted file mode 100644 index 60d4337f4..000000000 --- a/changelog/9437.breaking.rst +++ /dev/null @@ -1 +0,0 @@ -Dropped support for Python 3.6, which reached `end-of-life `__ at 2021-12-23. diff --git a/changelog/9493.bugfix.rst b/changelog/9493.bugfix.rst deleted file mode 100644 index d99c80b7d..000000000 --- a/changelog/9493.bugfix.rst +++ /dev/null @@ -1,10 +0,0 @@ -Symbolic link components are no longer resolved in conftest paths. -This means that if a conftest appears twice in collection tree, using symlinks, it will be executed twice. -For example, given - - tests/real/conftest.py - tests/real/test_it.py - tests/link -> tests/real - -running ``pytest tests`` now imports the conftest twice, once as ``tests/real/conftest.py`` and once as ``tests/link/conftest.py``. -This is a fix to match a similar change made to test collection itself in pytest 6.0 (see :pull:`6523` for details). diff --git a/changelog/9536.improvement.rst b/changelog/9536.improvement.rst deleted file mode 100644 index c7769602f..000000000 --- a/changelog/9536.improvement.rst +++ /dev/null @@ -1 +0,0 @@ -When ``-vv`` is given on command line, show skipping and xfail reasons in full instead of truncating them to fit the terminal width. diff --git a/changelog/9726.bugfix.rst b/changelog/9726.bugfix.rst new file mode 100644 index 000000000..66c04c4d9 --- /dev/null +++ b/changelog/9726.bugfix.rst @@ -0,0 +1 @@ +An unnecessary ``numpy`` import inside :func:`pytest.approx` was removed. diff --git a/changelog/9742.improvement.rst b/changelog/9742.improvement.rst new file mode 100644 index 000000000..a1abfc274 --- /dev/null +++ b/changelog/9742.improvement.rst @@ -0,0 +1 @@ +Display assertion message without escaped newline characters with ``-vv``. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 75dde1bd6..0da8b4037 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,9 @@ Release announcements :maxdepth: 2 + release-7.1.1 + release-7.1.0 + release-7.0.1 release-7.0.0 release-7.0.0rc1 release-6.2.5 diff --git a/doc/en/announce/release-7.0.1.rst b/doc/en/announce/release-7.0.1.rst new file mode 100644 index 000000000..5accfbad0 --- /dev/null +++ b/doc/en/announce/release-7.0.1.rst @@ -0,0 +1,20 @@ +pytest-7.0.1 +======================================= + +pytest 7.0.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 +* Ran Benita + + +Happy testing, +The pytest Development Team diff --git a/doc/en/announce/release-7.1.0.rst b/doc/en/announce/release-7.1.0.rst new file mode 100644 index 000000000..3361e1c8a --- /dev/null +++ b/doc/en/announce/release-7.1.0.rst @@ -0,0 +1,48 @@ +pytest-7.1.0 +======================================= + +The pytest team is proud to announce the 7.1.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: + +* Akuli +* Andrew Svetlov +* Anthony Sottile +* Brett Holman +* Bruno Oliveira +* Chris NeJame +* Dan Alvizu +* Elijah DeLee +* Emmanuel Arias +* Fabian Egli +* Florian Bruhin +* Gabor Szabo +* Hasan Ramezani +* Hugo van Kemenade +* Kian Meng, Ang +* Kojo Idrissa +* Masaru Tsuchiyama +* Olga Matoula +* P. L. Lim +* Ran Benita +* Tobias Deiminger +* Yuval Shimon +* eduardo naufel schettino +* Éric + + +Happy testing, +The pytest Development Team diff --git a/doc/en/announce/release-7.1.1.rst b/doc/en/announce/release-7.1.1.rst new file mode 100644 index 000000000..d271c4557 --- /dev/null +++ b/doc/en/announce/release-7.1.1.rst @@ -0,0 +1,18 @@ +pytest-7.1.1 +======================================= + +pytest 7.1.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: + +* Ran Benita + + +Happy testing, +The pytest Development Team diff --git a/doc/en/builtin.rst b/doc/en/builtin.rst index c7e7863b2..455ae8812 100644 --- a/doc/en/builtin.rst +++ b/doc/en/builtin.rst @@ -65,7 +65,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests. - pytestconfig [session scope] -- .../_pytest/fixtures.py:1365 + pytestconfig [session scope] -- .../_pytest/fixtures.py:1334 Session-scoped fixture that returns the session's :class:`pytest.Config` object. @@ -134,7 +134,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:483 + caplog -- .../_pytest/logging.py:487 Access and control log capturing. Captured logs are available through the following properties/methods:: diff --git a/doc/en/changelog.rst b/doc/en/changelog.rst index 9605d6bcf..6ff85883e 100644 --- a/doc/en/changelog.rst +++ b/doc/en/changelog.rst @@ -28,6 +28,131 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 7.1.1 (2022-03-17) +========================= + +Bug Fixes +--------- + +- `#9767 `_: Fixed a regression in pytest 7.1.0 where some conftest.py files outside of the source tree (e.g. in the `site-packages` directory) were not picked up. + + +pytest 7.1.0 (2022-03-13) +========================= + +Breaking Changes +---------------- + +- `#8838 `_: As per our policy, the following features have been deprecated in the 6.X series and are now + removed: + + * ``pytest._fillfuncargs`` function. + + * ``pytest_warning_captured`` hook - use ``pytest_warning_recorded`` instead. + + * ``-k -foobar`` syntax - use ``-k 'not foobar'`` instead. + + * ``-k foobar:`` syntax. + + * ``pytest.collect`` module - import from ``pytest`` directly. + + For more information consult + `Deprecations and Removals `__ in the docs. + + +- `#9437 `_: Dropped support for Python 3.6, which reached `end-of-life `__ at 2021-12-23. + + + +Improvements +------------ + +- `#5192 `_: Fixed test output for some data types where ``-v`` would show less information. + + Also, when showing diffs for sequences, ``-q`` would produce full diffs instead of the expected diff. + + +- `#9362 `_: pytest now avoids specialized assert formatting when it is detected that the default ``__eq__`` is overridden in ``attrs`` or ``dataclasses``. + + +- `#9536 `_: When ``-vv`` is given on command line, show skipping and xfail reasons in full instead of truncating them to fit the terminal width. + + +- `#9644 `_: More information about the location of resources that led Python to raise :class:`ResourceWarning` can now + be obtained by enabling :mod:`tracemalloc`. + + See :ref:`resource-warnings` for more information. + + +- `#9678 `_: More types are now accepted in the ``ids`` argument to ``@pytest.mark.parametrize``. + Previously only `str`, `float`, `int` and `bool` were accepted; + now `bytes`, `complex`, `re.Pattern`, `Enum` and anything with a `__name__` are also accepted. + + +- `#9692 `_: :func:`pytest.approx` now raises a :class:`TypeError` when given an unordered sequence (such as :class:`set`). + + Note that this implies that custom classes which only implement ``__iter__`` and ``__len__`` are no longer supported as they don't guarantee order. + + + +Bug Fixes +--------- + +- `#8242 `_: The deprecation of raising :class:`unittest.SkipTest` to skip collection of + tests during the pytest collection phase is reverted - this is now a supported + feature again. + + +- `#9493 `_: Symbolic link components are no longer resolved in conftest paths. + This means that if a conftest appears twice in collection tree, using symlinks, it will be executed twice. + For example, given + + tests/real/conftest.py + tests/real/test_it.py + tests/link -> tests/real + + running ``pytest tests`` now imports the conftest twice, once as ``tests/real/conftest.py`` and once as ``tests/link/conftest.py``. + This is a fix to match a similar change made to test collection itself in pytest 6.0 (see :pull:`6523` for details). + + +- `#9626 `_: Fixed count of selected tests on terminal collection summary when there were errors or skipped modules. + + If there were errors or skipped modules on collection, pytest would mistakenly subtract those from the selected count. + + +- `#9645 `_: Fixed regression where ``--import-mode=importlib`` used together with :envvar:`PYTHONPATH` or :confval:`pythonpath` would cause import errors in test suites. + + +- `#9708 `_: :fixture:`pytester` now requests a :fixture:`monkeypatch` fixture instead of creating one internally. This solves some issues with tests that involve pytest environment variables. + + +- `#9730 `_: Malformed ``pyproject.toml`` files now produce a clearer error message. + + +pytest 7.0.1 (2022-02-11) +========================= + +Bug Fixes +--------- + +- `#9608 `_: Fix invalid importing of ``importlib.readers`` in Python 3.9. + + +- `#9610 `_: Restore `UnitTestFunction.obj` to return unbound rather than bound method. + Fixes a crash during a failed teardown in unittest TestCases with non-default `__init__`. + Regressed in pytest 7.0.0. + + +- `#9636 `_: The ``pythonpath`` plugin was renamed to ``python_path``. This avoids a conflict with the ``pytest-pythonpath`` plugin. + + +- `#9642 `_: Fix running tests by id with ``::`` in the parametrize portion. + + +- `#9643 `_: Delay issuing a :class:`~pytest.PytestWarning` about diamond inheritance involving :class:`~pytest.Item` and + :class:`~pytest.Collector` so it can be filtered using :ref:`standard warning filters `. + + pytest 7.0.0 (2022-02-03) ========================= @@ -187,6 +312,8 @@ Deprecations :class:`unittest.SkipTest` / :meth:`unittest.TestCase.skipTest` / :func:`unittest.skip` in unittest test cases is fully supported. + .. note:: This deprecation has been reverted in pytest 7.1.0. + - `#8315 `_: Several behaviors of :meth:`Parser.addoption ` are now scheduled for removal in pytest 8 (deprecated since pytest 2.4.0): diff --git a/doc/en/conf.py b/doc/en/conf.py index b31616353..1adc3493a 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -382,7 +382,6 @@ texinfo_documents = [ ] -# Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { "pluggy": ("https://pluggy.readthedocs.io/en/stable", None), "python": ("https://docs.python.org/3", None), @@ -390,10 +389,6 @@ intersphinx_mapping = { "pip": ("https://pip.pypa.io/en/stable", None), "tox": ("https://tox.wiki/en/stable", None), "virtualenv": ("https://virtualenv.pypa.io/en/stable", None), - "django": ( - "http://docs.djangoproject.com/en/stable", - "http://docs.djangoproject.com/en/stable/_objects", - ), "setuptools": ("https://setuptools.pypa.io/en/stable", None), } diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index d9fb4d6b0..91944b758 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -16,7 +16,7 @@ Deprecated Features ------------------- Below is a complete list of all pytest features which are considered deprecated. Using those features will issue -:class:`PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. +:class:`~pytest.PytestWarning` or subclasses, which can be filtered using :ref:`standard warning filters `. .. _instance-collector-deprecation: @@ -241,19 +241,6 @@ scheduled for removal in pytest 8 (deprecated since pytest 2.4.0): - ``parser.addoption(..., type="int/string/float/complex")`` - use ``type=int`` etc. instead. -Raising ``unittest.SkipTest`` during collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 7.0 - -Raising :class:`unittest.SkipTest` to skip collection of tests during the -pytest collection phase is deprecated. Use :func:`pytest.skip` instead. - -Note: This deprecation only relates to using `unittest.SkipTest` during test -collection. You are probably not doing that. Ordinary usage of -:class:`unittest.SkipTest` / :meth:`unittest.TestCase.skipTest` / -:func:`unittest.skip` in unittest test cases is fully supported. - Using ``pytest.warns(None)`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -314,7 +301,7 @@ The ``pytest_warning_captured`` hook This hook has an `item` parameter which cannot be serialized by ``pytest-xdist``. -Use the ``pytest_warning_recored`` hook instead, which replaces the ``item`` parameter +Use the ``pytest_warning_recorded`` hook instead, which replaces the ``item`` parameter by a ``nodeid`` parameter. diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index cab931436..4c1ae1c05 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -155,7 +155,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert [0, 1, 2] == [0, 1, 3] E assert [0, 1, 2] == [0, 1, 3] E At index 2 diff: 2 != 3 - E Use -v to get the full diff + E Use -v to get more diff failure_demo.py:63: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ @@ -168,7 +168,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert a == b E assert [0, 0, 0, 0, 0, 0, ...] == [0, 0, 0, 0, 0, 0, ...] E At index 100 diff: 1 != 2 - E Use -v to get the full diff + E Use -v to get more diff failure_demo.py:68: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ @@ -215,7 +215,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert [1, 2] == [1, 2, 3] E assert [1, 2] == [1, 2, 3] E Right contains one more item: 3 - E Use -v to get the full diff + E Use -v to get more diff failure_demo.py:77: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index 4c948843a..b856803f1 100644 --- a/doc/en/getting-started.rst +++ b/doc/en/getting-started.rst @@ -22,7 +22,7 @@ Install ``pytest`` .. code-block:: bash $ pytest --version - pytest 7.0.0 + pytest 7.1.1 .. _`simpletest`: diff --git a/doc/en/how-to/assert.rst b/doc/en/how-to/assert.rst index cb70db6b8..65f161291 100644 --- a/doc/en/how-to/assert.rst +++ b/doc/en/how-to/assert.rst @@ -201,7 +201,7 @@ if you run this module: E '1' E Extra items in the right set: E '5' - E Use -v to get the full diff + E Use -v to get more diff test_assert2.py:4: AssertionError ========================= short test summary info ========================== diff --git a/doc/en/how-to/bash-completion.rst b/doc/en/how-to/bash-completion.rst index 245dfd6d9..117ff7ec1 100644 --- a/doc/en/how-to/bash-completion.rst +++ b/doc/en/how-to/bash-completion.rst @@ -5,7 +5,7 @@ How to set up bash completion ============================= When using bash as your shell, ``pytest`` can use argcomplete -(https://argcomplete.readthedocs.io/) for auto-completion. +(https://kislyuk.github.io/argcomplete/) for auto-completion. For this ``argcomplete`` needs to be installed **and** enabled. Install argcomplete using: diff --git a/doc/en/how-to/capture-warnings.rst b/doc/en/how-to/capture-warnings.rst index 065c11e61..4a27767e5 100644 --- a/doc/en/how-to/capture-warnings.rst +++ b/doc/en/how-to/capture-warnings.rst @@ -358,7 +358,7 @@ Additional use cases of warnings in tests Here are some use cases involving warnings that often come up in tests, and suggestions on how to deal with them: -- To ensure that **any** warning is emitted, use: +- To ensure that **at least one** warning is emitted, use: .. code-block:: python @@ -441,3 +441,18 @@ Please read our :ref:`backwards-compatibility` to learn how we proceed about dep features. The full list of warnings is listed in :ref:`the reference documentation `. + + +.. _`resource-warnings`: + +Resource Warnings +----------------- + +Additional information of the source of a :class:`ResourceWarning` can be obtained when captured by pytest if +:mod:`tracemalloc` module is enabled. + +One convenient way to enable :mod:`tracemalloc` when running tests is to set the :envvar:`PYTHONTRACEMALLOC` to a large +enough number of frames (say ``20``, but that number is application dependent). + +For more information, consult the `Python Development Mode `__ +section in the Python documentation. diff --git a/doc/en/how-to/output.rst b/doc/en/how-to/output.rst index 4b90988f4..dc3a86ba2 100644 --- a/doc/en/how-to/output.rst +++ b/doc/en/how-to/output.rst @@ -84,7 +84,7 @@ Executing pytest normally gives us this output (we are skipping the header to fo > assert fruits1 == fruits2 E AssertionError: assert ['banana', 'a...elon', 'kiwi'] == ['banana', 'a...elon', 'kiwi'] E At index 2 diff: 'grapes' != 'orange' - E Use -v to get the full diff + E Use -v to get more diff test_verbosity_example.py:8: AssertionError ____________________________ test_numbers_fail _____________________________ @@ -99,7 +99,7 @@ Executing pytest normally gives us this output (we are skipping the header to fo E {'1': 1, '2': 2, '3': 3, '4': 4} E Right contains 4 more items: E {'10': 10, '20': 20, '30': 30, '40': 40} - E Use -v to get the full diff + E Use -v to get more diff test_verbosity_example.py:14: AssertionError ___________________________ test_long_text_fail ____________________________ diff --git a/doc/en/how-to/plugins.rst b/doc/en/how-to/plugins.rst index de31bc04a..7a1948410 100644 --- a/doc/en/how-to/plugins.rst +++ b/doc/en/how-to/plugins.rst @@ -21,7 +21,7 @@ there is no need to activate it. Here is a little annotated list for some popular plugins: * :pypi:`pytest-django`: write tests - for :std:doc:`django ` apps, using pytest integration. + for `django `_ apps, using pytest integration. * :pypi:`pytest-twisted`: write tests for `twisted `_ apps, starting a reactor and diff --git a/doc/en/index.rst b/doc/en/index.rst index 9e9cf0b68..03a39aaaa 100644 --- a/doc/en/index.rst +++ b/doc/en/index.rst @@ -1,11 +1,16 @@ :orphan: +.. sidebar:: Next Open Trainings + + - `PyConDE `__, April 11th 2022 (3h), Berlin, Germany + - `PyConIT `__, June 3rd 2022 (4h), Florence, Italy + - `Professional Testing with Python `_, via `Python Academy `_, March 7th to 9th 2023 (3 day in-depth training), Remote and Leipzig, Germany + + Also see :doc:`previous talks and blogposts `. + .. - .. sidebar:: Next Open Trainings - - - `Professional Testing with Python `_, via `Python Academy `_, February 1st to 3rd, 2022, Leipzig (Germany) and remote. - - Also see `previous talks and blogposts `_. + - `Europython `__, July 11th to 17th (3h), Dublin, Ireland + - `CH Open Workshoptage `__ (German), September 6th to 8th (1 day), Bern, Switzerland .. _features: diff --git a/doc/en/reference/plugin_list.rst b/doc/en/reference/plugin_list.rst index f73ad773c..71e4d2347 100644 --- a/doc/en/reference/plugin_list.rst +++ b/doc/en/reference/plugin_list.rst @@ -11,7 +11,7 @@ automatically. Packages classified as inactive are excluded. creating a PDF, because otherwise the table gets far too wide for the page. -This list contains 995 plugins. +This list contains 1016 plugins. .. only:: not latex @@ -19,7 +19,7 @@ This list contains 995 plugins. name summary last release status requires =============================================== ======================================================================================================================================================================== ============== ===================== ================================================ :pypi:`pytest-accept` A pytest-plugin for updating doctest outputs Jan 07, 2022 N/A pytest (>=6,<8) - :pypi:`pytest-adaptavist` pytest plugin for generating test execution results within Jira Test Management (tm4j) Feb 01, 2022 N/A pytest (>=5.4.0) + :pypi:`pytest-adaptavist` pytest plugin for generating test execution results within Jira Test Management (tm4j) Feb 22, 2022 N/A pytest (>=5.4.0) :pypi:`pytest-addons-test` 用于测试pytest的插件 Aug 02, 2021 N/A pytest (>=6.2.4,<7.0.0) :pypi:`pytest-adf` Pytest plugin for writing Azure Data Factory integration tests May 10, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-adf-azure-identity` Pytest plugin for writing Azure Data Factory integration tests Mar 06, 2021 4 - Beta pytest (>=3.5.0) @@ -27,17 +27,18 @@ This list contains 995 plugins. :pypi:`pytest-aggreport` pytest plugin for pytest-repeat that generate aggregate report of the same test cases with additional statistics details. Mar 07, 2021 4 - Beta pytest (>=6.2.2) :pypi:`pytest-aio` Pytest plugin for testing async python code Oct 20, 2021 4 - Beta pytest :pypi:`pytest-aiofiles` pytest fixtures for writing aiofiles tests with pyfakefs May 14, 2017 5 - Production/Stable N/A - :pypi:`pytest-aiohttp` Pytest plugin for aiohttp support Jan 21, 2022 4 - Beta pytest (>=6.1.0) + :pypi:`pytest-aiohttp` Pytest plugin for aiohttp support Feb 12, 2022 4 - Beta pytest (>=6.1.0) :pypi:`pytest-aiohttp-client` Pytest \`client\` fixture for the Aiohttp Nov 01, 2020 N/A pytest (>=6) - :pypi:`pytest-aiomoto` pytest-aiomoto Dec 10, 2021 N/A pytest (>=6.2.5,<7.0.0) + :pypi:`pytest-aiomoto` pytest-aiomoto Mar 13, 2022 N/A pytest (>=6.2.5,<7.0.0) :pypi:`pytest-aioresponses` py.test integration for aioresponses Jul 29, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-aioworkers` A plugin to test aioworkers project with pytest Dec 04, 2019 4 - Beta pytest (>=3.5.0) :pypi:`pytest-airflow` pytest support for airflow. Apr 03, 2019 3 - Alpha pytest (>=4.4.0) :pypi:`pytest-airflow-utils` Nov 15, 2021 N/A N/A - :pypi:`pytest-alembic` A pytest plugin for verifying alembic migrations. Dec 21, 2021 N/A pytest (>=1.0) + :pypi:`pytest-alembic` A pytest plugin for verifying alembic migrations. Mar 12, 2022 N/A pytest (>=1.0) :pypi:`pytest-allclose` Pytest fixture extending Numpy's allclose function Jul 30, 2019 5 - Production/Stable pytest :pypi:`pytest-allure-adaptor` Plugin for py.test to generate allure xml reports Jan 10, 2018 N/A pytest (>=2.7.3) :pypi:`pytest-allure-adaptor2` Plugin for py.test to generate allure xml reports Oct 14, 2020 N/A pytest (>=2.7.3) + :pypi:`pytest-allure-collection` pytest plugin to collect allure markers without running any tests Feb 21, 2022 N/A pytest :pypi:`pytest-allure-dsl` pytest plugin to test case doc string dls instructions Oct 25, 2020 4 - Beta pytest :pypi:`pytest-allure-spec-coverage` The pytest plugin aimed to display test coverage of the specs(requirements) in Allure Oct 26, 2021 N/A pytest :pypi:`pytest-alphamoon` Static code checks used at Alphamoon Dec 30, 2021 5 - Production/Stable pytest (>=3.5.0) @@ -65,10 +66,10 @@ This list contains 995 plugins. :pypi:`pytest-assume` A pytest plugin that allows multiple failures per test Jun 24, 2021 N/A pytest (>=2.7) :pypi:`pytest-ast-back-to-python` A plugin for pytest devs to view how assertion rewriting recodes the AST Sep 29, 2019 4 - Beta N/A :pypi:`pytest-astropy` Meta-package containing dependencies for testing Sep 21, 2021 5 - Production/Stable pytest (>=4.6) - :pypi:`pytest-astropy-header` pytest plugin to add diagnostic information to the header of the test output Dec 27, 2021 3 - Alpha pytest (>=4.6) + :pypi:`pytest-astropy-header` pytest plugin to add diagnostic information to the header of the test output Mar 10, 2022 3 - Alpha pytest (>=4.6) :pypi:`pytest-ast-transformer` May 04, 2019 3 - Alpha pytest - :pypi:`pytest-asyncio` Pytest support for asyncio Jan 17, 2022 4 - Beta pytest (>=6.1.0) - :pypi:`pytest-asyncio-cooperative` Run all your asynchronous tests cooperatively. Jan 25, 2022 N/A N/A + :pypi:`pytest-asyncio` Pytest support for asyncio Mar 03, 2022 4 - Beta pytest (>=6.1.0) + :pypi:`pytest-asyncio-cooperative` Run all your asynchronous tests cooperatively. Mar 16, 2022 N/A N/A :pypi:`pytest-asyncio-network-simulator` pytest-asyncio-network-simulator: Plugin for pytest for simulator the network in tests Jul 31, 2018 3 - Alpha pytest (<3.7.0,>=3.3.2) :pypi:`pytest-async-mongodb` pytest plugin for async MongoDB Oct 18, 2017 5 - Production/Stable pytest (>=2.5.2) :pypi:`pytest-async-sqlalchemy` Database testing fixtures using the SQLAlchemy asyncio API Oct 07, 2021 4 - Beta pytest (>=6.0.0) @@ -84,7 +85,7 @@ This list contains 995 plugins. :pypi:`pytest-aws` pytest plugin for testing AWS resource configurations Oct 04, 2017 4 - Beta N/A :pypi:`pytest-aws-config` Protect your AWS credentials in unit tests May 28, 2021 N/A N/A :pypi:`pytest-axe` pytest plugin for axe-selenium-python Nov 12, 2018 N/A pytest (>=3.0.0) - :pypi:`pytest-azurepipelines` Formatting PyTest output for Azure Pipelines UI Jul 23, 2020 4 - Beta pytest (>=3.5.0) + :pypi:`pytest-azurepipelines` Formatting PyTest output for Azure Pipelines UI Mar 16, 2022 4 - Beta pytest (>=5.0.0) :pypi:`pytest-bandit` A bandit plugin for pytest Feb 23, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-base-url` pytest plugin for URL based testing Jun 19, 2020 5 - Production/Stable pytest (>=2.7.3) :pypi:`pytest-bdd` BDD for pytest Oct 25, 2021 6 - Mature pytest (>=4.3) @@ -101,14 +102,14 @@ This list contains 995 plugins. :pypi:`pytest-black` A pytest plugin to enable format checking with black Oct 05, 2020 4 - Beta N/A :pypi:`pytest-black-multipy` Allow '--black' on older Pythons Jan 14, 2021 5 - Production/Stable pytest (!=3.7.3,>=3.5) ; extra == 'testing' :pypi:`pytest-blame` A pytest plugin helps developers to debug by providing useful commits history. May 04, 2019 N/A pytest (>=4.4.0) - :pypi:`pytest-blender` Blender Pytest plugin. Oct 29, 2021 N/A pytest (==6.2.5) ; extra == 'dev' + :pypi:`pytest-blender` Blender Pytest plugin. Mar 11, 2022 N/A pytest ; extra == 'dev' :pypi:`pytest-blink1` Pytest plugin to emit notifications via the Blink(1) RGB LED Jan 07, 2018 4 - Beta N/A :pypi:`pytest-blockage` Disable network requests during a test run. Dec 21, 2021 N/A pytest :pypi:`pytest-blocker` pytest plugin to mark a test as blocker and skip all other tests Sep 07, 2015 4 - Beta N/A :pypi:`pytest-board` Local continuous test runner with pytest and watchdog. Jan 20, 2019 N/A N/A - :pypi:`pytest-bootstrap` Jan 28, 2022 N/A N/A + :pypi:`pytest-bootstrap` Mar 04, 2022 N/A N/A :pypi:`pytest-bpdb` A py.test plug-in to enable drop to bpdb debugger on test failure. Jan 19, 2015 2 - Pre-Alpha N/A - :pypi:`pytest-bravado` Pytest-bravado automatically generates from OpenAPI specification client fixtures. Jul 19, 2021 N/A N/A + :pypi:`pytest-bravado` Pytest-bravado automatically generates from OpenAPI specification client fixtures. Feb 15, 2022 N/A N/A :pypi:`pytest-breakword` Use breakword with pytest Aug 04, 2021 N/A pytest (>=6.2.4,<7.0.0) :pypi:`pytest-breed-adapter` A simple plugin to connect with breed-server Nov 07, 2018 4 - Beta pytest (>=3.5.0) :pypi:`pytest-briefcase` A pytest plugin for running tests on a Briefcase project. Jun 14, 2020 4 - Beta pytest (>=3.5.0) @@ -123,20 +124,22 @@ This list contains 995 plugins. :pypi:`pytest-builtin-types` Nov 17, 2021 N/A pytest :pypi:`pytest-bwrap` Run your tests in Bubblewrap sandboxes Oct 26, 2018 3 - Alpha N/A :pypi:`pytest-cache` pytest plugin with mechanisms for caching across test runs Jun 04, 2013 3 - Alpha N/A - :pypi:`pytest-cache-assert` Cache assertion data to simplify regression testing of complex serializable data Nov 03, 2021 4 - Beta pytest (>=5) + :pypi:`pytest-cache-assert` Cache assertion data to simplify regression testing of complex serializable data Mar 03, 2022 4 - Beta pytest (>=5.0.0) :pypi:`pytest-cagoule` Pytest plugin to only run tests affected by changes Jan 01, 2020 3 - Alpha N/A - :pypi:`pytest-cairo` Feb 04, 2022 N/A pytest + :pypi:`pytest-cairo` Pytest support for cairo-lang and starknet Mar 08, 2022 N/A pytest :pypi:`pytest-camel-collect` Enable CamelCase-aware pytest class collection Aug 02, 2020 N/A pytest (>=2.9) :pypi:`pytest-canonical-data` A plugin which allows to compare results with canonical results, based on previous runs May 08, 2020 2 - Pre-Alpha pytest (>=3.5.0) :pypi:`pytest-caprng` A plugin that replays pRNG state on failure. May 02, 2018 4 - Beta N/A :pypi:`pytest-capture-deprecatedwarnings` pytest plugin to capture all deprecatedwarnings and put them in one file Apr 30, 2019 N/A N/A - :pypi:`pytest-cases` Separate test code from test cases in pytest. Jan 07, 2022 5 - Production/Stable N/A + :pypi:`pytest-capture-warnings` pytest plugin to capture all warnings and put them in one file of your choice Mar 16, 2022 N/A pytest + :pypi:`pytest-cases` Separate test code from test cases in pytest. Mar 14, 2022 5 - Production/Stable N/A :pypi:`pytest-cassandra` Cassandra CCM Test Fixtures for pytest Nov 04, 2017 1 - Planning N/A :pypi:`pytest-catchlog` py.test plugin to catch log messages. This is a fork of pytest-capturelog. Jan 24, 2016 4 - Beta pytest (>=2.6) :pypi:`pytest-catch-server` Pytest plugin with server for catching HTTP requests. Dec 12, 2019 5 - Production/Stable N/A :pypi:`pytest-celery` pytest-celery a shim pytest plugin to enable celery.contrib.pytest May 06, 2021 N/A N/A :pypi:`pytest-chainmaker` pytest plugin for chainmaker Oct 15, 2021 N/A N/A :pypi:`pytest-chalice` A set of py.test fixtures for AWS Chalice Jul 01, 2020 4 - Beta N/A + :pypi:`pytest-change-demo` turn . into √,turn F into x Mar 02, 2022 N/A pytest :pypi:`pytest-change-report` turn . into √,turn F into x Sep 14, 2020 N/A pytest :pypi:`pytest-chdir` A pytest fixture for changing current working directory Jan 28, 2020 N/A pytest (>=5.0.0,<6.0.0) :pypi:`pytest-checkdocs` check the README when running tests Jul 31, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing' @@ -148,7 +151,7 @@ This list contains 995 plugins. :pypi:`pytest-ckan` Backport of CKAN 2.9 pytest plugin and fixtures to CAKN 2.8 Apr 28, 2020 4 - Beta pytest :pypi:`pytest-clarity` A plugin providing an alternative, colourful diff output for failing assertions. Jun 11, 2021 N/A N/A :pypi:`pytest-cldf` Easy quality control for CLDF datasets using pytest May 06, 2019 N/A N/A - :pypi:`pytest-click` Py.test plugin for Click Aug 29, 2020 5 - Production/Stable pytest (>=5.0) + :pypi:`pytest-click` Pytest plugin for Click Feb 11, 2022 5 - Production/Stable pytest (>=5.0) :pypi:`pytest-clld` Nov 29, 2021 N/A pytest (>=3.6) :pypi:`pytest-cloud` Distributed tests planner plugin for pytest testing framework. Oct 05, 2020 6 - Mature N/A :pypi:`pytest-cloudflare-worker` pytest plugin for testing cloudflare workers Mar 30, 2021 4 - Beta pytest (>=6.0.0) @@ -165,7 +168,7 @@ This list contains 995 plugins. :pypi:`pytest-concurrent` Concurrently execute test cases with multithread, multiprocess and gevent Jan 12, 2019 4 - Beta pytest (>=3.1.1) :pypi:`pytest-config` Base configurations and utilities for developing your Python project test suite with pytest. Nov 07, 2014 5 - Production/Stable N/A :pypi:`pytest-confluence-report` Package stands for pytest plugin to upload results into Confluence page. Nov 06, 2020 N/A N/A - :pypi:`pytest-console-scripts` Pytest plugin for testing console scripts Jan 06, 2022 4 - Beta N/A + :pypi:`pytest-console-scripts` Pytest plugin for testing console scripts Mar 18, 2022 4 - Beta N/A :pypi:`pytest-consul` pytest plugin with fixtures for testing consul aware apps Nov 24, 2018 3 - Alpha pytest :pypi:`pytest-container` Pytest fixtures for writing container based tests Feb 01, 2022 3 - Alpha pytest (>=3.10) :pypi:`pytest-contextfixture` Define pytest fixtures as context managers. Mar 12, 2013 4 - Beta N/A @@ -178,7 +181,8 @@ This list contains 995 plugins. :pypi:`pytest-coverage` Jun 17, 2015 N/A N/A :pypi:`pytest-coverage-context` Coverage dynamic context support for PyTest, including sub-processes Jan 04, 2021 4 - Beta pytest (>=6.1.0) :pypi:`pytest-cov-exclude` Pytest plugin for excluding tests based on coverage data Apr 29, 2016 4 - Beta pytest (>=2.8.0,<2.9.0); extra == 'dev' - :pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Dec 06, 2021 5 - Production/Stable pytest (!=5.4.0,!=5.4.1) + :pypi:`pytest-cpp` Use pytest's runner to discover and execute C++ tests Mar 18, 2022 5 - Production/Stable pytest (!=5.4.0,!=5.4.1) + :pypi:`pytest-cppython` A pytest plugin that imports CPPython testing types Mar 14, 2022 N/A N/A :pypi:`pytest-cram` Run cram tests with pytest. Aug 08, 2020 N/A N/A :pypi:`pytest-crate` Manages CrateDB instances during your integration tests May 28, 2019 3 - Alpha pytest (>=4.0) :pypi:`pytest-cricri` A Cricri plugin for pytest. Jan 27, 2018 N/A pytest @@ -199,6 +203,7 @@ This list contains 995 plugins. :pypi:`pytest-datadir` pytest plugin for test data directories and files Oct 22, 2019 5 - Production/Stable pytest (>=2.7.0) :pypi:`pytest-datadir-mgr` Manager for test data: downloads, artifact caching, and a tmpdir context. Jan 20, 2022 5 - Production/Stable pytest :pypi:`pytest-datadir-ng` Fixtures for pytest allowing test functions/methods to easily retrieve test resources from the local filesystem. Dec 25, 2019 5 - Production/Stable pytest + :pypi:`pytest-data-extractor` A pytest plugin to extract relevant metadata about tests into an external file (currently only json support) Mar 09, 2022 N/A pytest (>=7.0.1) :pypi:`pytest-data-file` Fixture "data" and "case_data" for test from yaml file Dec 04, 2019 N/A N/A :pypi:`pytest-datafiles` py.test plugin to create a 'tmpdir' containing predefined files/directories. Oct 07, 2018 5 - Production/Stable pytest (>=3.6) :pypi:`pytest-datafixtures` Data fixtures for pytest made simple Dec 05, 2020 5 - Production/Stable N/A @@ -210,7 +215,7 @@ This list contains 995 plugins. :pypi:`pytest-dbfixtures` Databases fixtures plugin for py.test. Dec 07, 2016 4 - Beta N/A :pypi:`pytest-db-plugin` Nov 27, 2021 N/A pytest (>=5.0) :pypi:`pytest-dbt-adapter` A pytest plugin for testing dbt adapter plugins Nov 24, 2021 N/A pytest (<7,>=6) - :pypi:`pytest-dbt-conventions` A pytest plugin for linting a dbt project's conventions Feb 04, 2022 N/A pytest (>=6.2.5,<7.0.0) + :pypi:`pytest-dbt-conventions` A pytest plugin for linting a dbt project's conventions Mar 02, 2022 N/A pytest (>=6.2.5,<7.0.0) :pypi:`pytest-dbt-core` Pytest extension for dbt. Jan 28, 2022 N/A pytest (>=6.2.5) ; extra == 'test' :pypi:`pytest-dbus-notification` D-BUS notifications for pytest results. Mar 05, 2014 5 - Production/Stable N/A :pypi:`pytest-deadfixtures` A simple plugin to list unused fixtures in pytest Jul 23, 2020 5 - Production/Stable N/A @@ -227,9 +232,10 @@ This list contains 995 plugins. :pypi:`pytest-dicom` pytest plugin to provide DICOM fixtures Dec 19, 2018 3 - Alpha pytest :pypi:`pytest-dictsdiff` Jul 26, 2019 N/A N/A :pypi:`pytest-diff` A simple plugin to use with pytest Mar 30, 2019 4 - Beta pytest (>=3.5.0) + :pypi:`pytest-diff-selector` Get tests affected by code changes (using git) Feb 24, 2022 4 - Beta pytest (>=6.2.2) ; extra == 'all' :pypi:`pytest-disable` pytest plugin to disable a test and skip it from testrun Sep 10, 2015 4 - Beta N/A :pypi:`pytest-disable-plugin` Disable plugins per test Feb 28, 2019 4 - Beta pytest (>=3.5.0) - :pypi:`pytest-discord` A pytest plugin to notify test results to a Discord channel. Mar 20, 2021 3 - Alpha pytest (!=6.0.0,<7,>=3.3.2) + :pypi:`pytest-discord` A pytest plugin to notify test results to a Discord channel. Feb 12, 2022 4 - Beta pytest (!=6.0.0,<8,>=3.3.2) :pypi:`pytest-django` A Django plugin for pytest. Dec 07, 2021 5 - Production/Stable pytest (>=5.4.0) :pypi:`pytest-django-ahead` A Django plugin for pytest. Oct 27, 2016 5 - Production/Stable pytest (>=2.9) :pypi:`pytest-djangoapp` Nice pytest plugin to help you with Django pluggable application testing. Aug 04, 2021 4 - Beta N/A @@ -239,7 +245,7 @@ This list contains 995 plugins. :pypi:`pytest-django-factories` Factories for your Django models that can be used as Pytest fixtures. Nov 12, 2020 4 - Beta N/A :pypi:`pytest-django-gcir` A Django plugin for pytest. Mar 06, 2018 5 - Production/Stable N/A :pypi:`pytest-django-haystack` Cleanup your Haystack indexes between tests Sep 03, 2017 5 - Production/Stable pytest (>=2.3.4) - :pypi:`pytest-django-ifactory` A model instance factory for pytest-django Jan 13, 2021 3 - Alpha N/A + :pypi:`pytest-django-ifactory` A model instance factory for pytest-django Feb 09, 2022 3 - Alpha N/A :pypi:`pytest-django-lite` The bare minimum to integrate py.test with Django. Jan 30, 2014 N/A N/A :pypi:`pytest-django-liveserver-ssl` Jan 20, 2022 3 - Alpha N/A :pypi:`pytest-django-model` A Simple Way to Test your Django Models Feb 14, 2019 4 - Beta N/A @@ -253,26 +259,27 @@ This list contains 995 plugins. :pypi:`pytest-docfiles` pytest plugin to test codeblocks in your documentation. Dec 22, 2021 4 - Beta pytest (>=3.7.0) :pypi:`pytest-docgen` An RST Documentation Generator for pytest-based test suites Apr 17, 2020 N/A N/A :pypi:`pytest-docker` Simple pytest fixtures for Docker and docker-compose based tests Jun 14, 2021 N/A pytest (<7.0,>=4.0) + :pypi:`pytest-docker-apache-fixtures` Pytest fixtures for testing with apache2 (httpd). Feb 16, 2022 4 - Beta pytest :pypi:`pytest-docker-butla` Jun 16, 2019 3 - Alpha N/A :pypi:`pytest-dockerc` Run, manage and stop Docker Compose project from Docker API Oct 09, 2020 5 - Production/Stable pytest (>=3.0) :pypi:`pytest-docker-compose` Manages Docker containers during your integration tests Jan 26, 2021 5 - Production/Stable pytest (>=3.3) :pypi:`pytest-docker-db` A plugin to use docker databases for pytests Mar 20, 2021 5 - Production/Stable pytest (>=3.1.1) :pypi:`pytest-docker-fixtures` pytest docker fixtures Nov 23, 2021 3 - Alpha N/A - :pypi:`pytest-docker-git-fixtures` Pytest fixtures for testing with git scm. Mar 11, 2021 4 - Beta pytest - :pypi:`pytest-docker-haproxy-fixtures` Pytest fixtures for testing with haproxy. Feb 01, 2022 4 - Beta pytest + :pypi:`pytest-docker-git-fixtures` Pytest fixtures for testing with git scm. Feb 09, 2022 4 - Beta pytest + :pypi:`pytest-docker-haproxy-fixtures` Pytest fixtures for testing with haproxy. Feb 09, 2022 4 - Beta pytest :pypi:`pytest-docker-pexpect` pytest plugin for writing functional tests with pexpect and docker Jan 14, 2019 N/A pytest :pypi:`pytest-docker-postgresql` A simple plugin to use with pytest Sep 24, 2019 4 - Beta pytest (>=3.5.0) :pypi:`pytest-docker-py` Easy to use, simple to extend, pytest plugin that minimally leverages docker-py. Nov 27, 2018 N/A pytest (==4.0.0) - :pypi:`pytest-docker-registry-fixtures` Pytest fixtures for testing with docker registries. Feb 01, 2022 4 - Beta pytest - :pypi:`pytest-docker-squid-fixtures` Pytest fixtures for testing with squid. Feb 04, 2022 4 - Beta pytest - :pypi:`pytest-docker-tools` Docker integration tests for pytest Jul 23, 2021 4 - Beta pytest (>=6.0.1,<7.0.0) + :pypi:`pytest-docker-registry-fixtures` Pytest fixtures for testing with docker registries. Feb 09, 2022 4 - Beta pytest + :pypi:`pytest-docker-service` pytest plugin to start docker container Mar 15, 2022 3 - Alpha pytest + :pypi:`pytest-docker-squid-fixtures` Pytest fixtures for testing with squid. Feb 09, 2022 4 - Beta pytest + :pypi:`pytest-docker-tools` Docker integration tests for pytest Feb 17, 2022 4 - Beta pytest (>=6.0.1) :pypi:`pytest-docs` Documentation tool for pytest Nov 11, 2018 4 - Beta pytest (>=3.5.0) :pypi:`pytest-docstyle` pytest plugin to run pydocstyle Mar 23, 2020 3 - Alpha N/A :pypi:`pytest-doctest-custom` A py.test plugin for customizing string representations of doctest results. Jul 25, 2016 4 - Beta N/A :pypi:`pytest-doctest-ellipsis-markers` Setup additional values for ELLIPSIS_MARKER for doctests Jan 12, 2018 4 - Beta N/A :pypi:`pytest-doctest-import` A simple pytest plugin to import names and add them to the doctest namespace. Nov 13, 2018 4 - Beta pytest (>=3.3.0) - :pypi:`pytest-doctestplus` Pytest plugin with advanced doctest features. Dec 09, 2021 3 - Alpha pytest (>=4.6) - :pypi:`pytest-doctest-ufunc` A plugin to run doctests in docstrings of Numpy ufuncs Aug 02, 2020 4 - Beta pytest (>=3.5.0) + :pypi:`pytest-doctestplus` Pytest plugin with advanced doctest features. Feb 25, 2022 3 - Alpha pytest (>=4.6) :pypi:`pytest-dolphin` Some extra stuff that we use ininternally Nov 30, 2016 4 - Beta pytest (==3.0.4) :pypi:`pytest-doorstop` A pytest plugin for adding test results into doorstop items. Jun 09, 2020 4 - Beta pytest (>=3.5.0) :pypi:`pytest-dotenv` A py.test plugin that parses environment files before running tests Jun 16, 2020 4 - Beta pytest (>=5.0.0) @@ -282,6 +289,7 @@ This list contains 995 plugins. :pypi:`pytest-dummynet` A py.test plugin providing access to a dummynet. Dec 15, 2021 5 - Production/Stable pytest :pypi:`pytest-dump2json` A pytest plugin for dumping test results to json. Jun 29, 2015 N/A N/A :pypi:`pytest-duration-insights` Jun 25, 2021 N/A N/A + :pypi:`pytest-durations` Pytest plugin reporting fixtures and test functions execution time. Mar 07, 2022 5 - Production/Stable pytest (>=4.6) :pypi:`pytest-dynamicrerun` A pytest plugin to rerun tests dynamically based off of test outcome and output. Aug 15, 2020 4 - Beta N/A :pypi:`pytest-dynamodb` DynamoDB fixtures for pytest Jun 03, 2021 5 - Production/Stable pytest :pypi:`pytest-easy-addoption` pytest-easy-addoption: Easy way to work with pytest addoption Jan 22, 2020 N/A N/A @@ -291,18 +299,18 @@ This list contains 995 plugins. :pypi:`pytest-easy-server` Pytest plugin for easy testing against servers May 01, 2021 4 - Beta pytest (<5.0.0,>=4.3.1) ; python_version < "3.5" :pypi:`pytest-ec2` Pytest execution on EC2 instance Oct 22, 2019 3 - Alpha N/A :pypi:`pytest-echo` pytest plugin with mechanisms for echoing environment variables, package version and generic attributes Jan 08, 2020 5 - Production/Stable N/A - :pypi:`pytest-elasticsearch` Elasticsearch fixtures and fixture factories for Pytest. May 12, 2021 5 - Production/Stable pytest (>=3.0.0) + :pypi:`pytest-elasticsearch` Elasticsearch fixtures and fixture factories for Pytest. Mar 01, 2022 5 - Production/Stable pytest (>=6.2.0) :pypi:`pytest-elements` Tool to help automate user interfaces Jan 13, 2021 N/A pytest (>=5.4,<6.0) :pypi:`pytest-elk-reporter` A simple plugin to use with pytest Jan 24, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-email` Send execution result email Jul 08, 2020 N/A pytest - :pypi:`pytest-embedded` pytest embedded plugin Jan 21, 2022 N/A pytest (>=6.2.0) - :pypi:`pytest-embedded-arduino` pytest embedded plugin for Arduino projects Jan 21, 2022 N/A N/A - :pypi:`pytest-embedded-idf` pytest embedded plugin for esp-idf project Jan 21, 2022 N/A N/A - :pypi:`pytest-embedded-jtag` pytest embedded plugin for testing with jtag Jan 21, 2022 N/A N/A - :pypi:`pytest-embedded-qemu` pytest embedded plugin for qemu, not target chip Jan 21, 2022 N/A N/A + :pypi:`pytest-embedded` pytest embedded plugin Mar 18, 2022 N/A pytest (>=7.0) + :pypi:`pytest-embedded-arduino` pytest embedded plugin for Arduino projects Mar 18, 2022 N/A N/A + :pypi:`pytest-embedded-idf` pytest embedded plugin for esp-idf project Mar 18, 2022 N/A N/A + :pypi:`pytest-embedded-jtag` pytest embedded plugin for testing with jtag Mar 18, 2022 N/A N/A + :pypi:`pytest-embedded-qemu` pytest embedded plugin for qemu, not target chip Mar 18, 2022 N/A N/A :pypi:`pytest-embedded-qemu-idf` pytest embedded plugin for esp-idf project by qemu, not target chip Jun 29, 2021 N/A N/A - :pypi:`pytest-embedded-serial` pytest embedded plugin for testing serial ports Jan 21, 2022 N/A N/A - :pypi:`pytest-embedded-serial-esp` pytest embedded plugin for testing espressif boards via serial ports Jan 21, 2022 N/A N/A + :pypi:`pytest-embedded-serial` pytest embedded plugin for testing serial ports Mar 18, 2022 N/A N/A + :pypi:`pytest-embedded-serial-esp` pytest embedded plugin for testing espressif boards via serial ports Mar 18, 2022 N/A N/A :pypi:`pytest-emoji` A pytest plugin that adds emojis to your test result report Feb 19, 2019 4 - Beta pytest (>=4.2.1) :pypi:`pytest-emoji-output` Pytest plugin to represent test output with emoji support Oct 10, 2021 4 - Beta pytest (==6.0.1) :pypi:`pytest-enabler` Enable installed pytest plugins Nov 08, 2021 5 - Production/Stable pytest (>=6) ; extra == 'testing' @@ -331,7 +339,7 @@ This list contains 995 plugins. :pypi:`pytest-expectr` This plugin is used to expect multiple assert using pytest framework. Oct 05, 2018 N/A pytest (>=2.4.2) :pypi:`pytest-experiments` A pytest plugin to help developers of research-oriented software projects keep track of the results of their numerical experiments. Dec 13, 2021 4 - Beta pytest (>=6.2.5,<7.0.0) :pypi:`pytest-explicit` A Pytest plugin to ignore certain marked tests by default Jun 15, 2021 5 - Production/Stable pytest - :pypi:`pytest-exploratory` Interactive console for pytest. Aug 03, 2021 N/A pytest (>=5.3) + :pypi:`pytest-exploratory` Interactive console for pytest. Feb 21, 2022 N/A pytest (>=6.2) :pypi:`pytest-external-blockers` a special outcome for tests that are blocked for external reasons Oct 05, 2021 N/A pytest :pypi:`pytest-extra-durations` A pytest plugin to get durations on a per-function basis and per module basis. Apr 21, 2020 4 - Beta pytest (>=3.5.0) :pypi:`pytest-fabric` Provides test utilities to run fabric task tests by using docker containers Sep 12, 2018 5 - Production/Stable N/A @@ -364,12 +372,13 @@ This list contains 995 plugins. :pypi:`pytest-fixture-maker` Pytest plugin to load fixtures from YAML files Sep 21, 2021 N/A N/A :pypi:`pytest-fixture-marker` A pytest plugin to add markers based on fixtures used. Oct 11, 2020 5 - Production/Stable N/A :pypi:`pytest-fixture-order` pytest plugin to control fixture evaluation order Aug 25, 2020 N/A pytest (>=3.0) + :pypi:`pytest-fixture-rtttg` Warn or fail on fixture name clash Feb 23, 2022 N/A pytest (>=7.0.1,<8.0.0) :pypi:`pytest-fixtures` Common fixtures for pytest May 01, 2019 5 - Production/Stable N/A :pypi:`pytest-fixture-tools` Plugin for pytest which provides tools for fixtures Aug 18, 2020 6 - Mature pytest :pypi:`pytest-fixture-typecheck` A pytest plugin to assert type annotations at runtime. Aug 24, 2021 N/A pytest - :pypi:`pytest-flake8` pytest plugin to check FLAKE8 requirements Dec 16, 2020 4 - Beta pytest (>=3.5) + :pypi:`pytest-flake8` pytest plugin to check FLAKE8 requirements Mar 18, 2022 4 - Beta pytest (>=7.0) :pypi:`pytest-flake8-path` A pytest fixture for testing flake8 plugins. Jan 10, 2022 5 - Production/Stable pytest - :pypi:`pytest-flake8-v2` pytest plugin to check FLAKE8 requirements Jan 25, 2022 4 - Beta pytest (>=6.0) + :pypi:`pytest-flake8-v2` pytest plugin to check FLAKE8 requirements Mar 01, 2022 5 - Production/Stable pytest (>=7.0) :pypi:`pytest-flakefinder` Runs tests multiple times to expose flakiness. Jul 28, 2020 4 - Beta pytest (>=2.7.1) :pypi:`pytest-flakes` pytest plugin to check source code with pyflakes Dec 02, 2021 5 - Production/Stable pytest (>=5) :pypi:`pytest-flaptastic` Flaptastic py.test plugin Mar 17, 2019 N/A N/A @@ -378,23 +387,25 @@ This list contains 995 plugins. :pypi:`pytest-flask-sqlalchemy-transactions` Run tests in transactions using pytest, Flask, and SQLalchemy. Aug 02, 2018 4 - Beta pytest (>=3.2.1) :pypi:`pytest-flyte` Pytest fixtures for simplifying Flyte integration testing May 03, 2021 N/A pytest :pypi:`pytest-focus` A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest + :pypi:`pytest-fold` Fold console output and drop user into interactive text user interface Feb 20, 2022 4 - Beta pytest (>=6.2.5) :pypi:`pytest-forcefail` py.test plugin to make the test failing regardless of pytest.mark.xfail May 15, 2018 4 - Beta N/A :pypi:`pytest-forward-compatability` A name to avoid typosquating pytest-foward-compatibility Sep 06, 2020 N/A N/A :pypi:`pytest-forward-compatibility` A pytest plugin to shim pytest commandline options for fowards compatibility Sep 29, 2020 N/A N/A :pypi:`pytest-freezegun` Wrap tests with fixtures in freeze_time Jul 19, 2020 4 - Beta pytest (>=3.0.0) :pypi:`pytest-freeze-reqs` Check if requirement files are frozen Apr 29, 2021 N/A N/A - :pypi:`pytest-frozen-uuids` Deterministically frozen UUID's for your tests Dec 08, 2021 N/A pytest (>=3.0) + :pypi:`pytest-frozen-uuids` Deterministically frozen UUID's for your tests Feb 14, 2022 N/A pytest (>=3.0) :pypi:`pytest-func-cov` Pytest plugin for measuring function coverage Apr 15, 2021 3 - Alpha pytest (>=5) :pypi:`pytest-funparam` An alternative way to parametrize test cases. Dec 02, 2021 4 - Beta pytest >=4.6.0 :pypi:`pytest-fxa` pytest plugin for Firefox Accounts Aug 28, 2018 5 - Production/Stable N/A :pypi:`pytest-fxtest` Oct 27, 2020 N/A N/A + :pypi:`pytest-gather-fixtures` set up asynchronous pytest fixtures concurrently Mar 15, 2022 N/A pytest (>=6.0.0,<7.0.0) :pypi:`pytest-gc` The garbage collector plugin for py.test Feb 01, 2018 N/A N/A :pypi:`pytest-gcov` Uses gcov to measure test coverage of a C library Feb 01, 2018 3 - Alpha N/A :pypi:`pytest-gevent` Ensure that gevent is properly patched when invoking pytest Feb 25, 2020 N/A pytest :pypi:`pytest-gherkin` A flexible framework for executing BDD gherkin tests Jul 27, 2019 3 - Alpha pytest (>=5.0.0) :pypi:`pytest-gh-log-group` pytest plugin for gh actions Jan 11, 2022 3 - Alpha pytest :pypi:`pytest-ghostinspector` For finding/executing Ghost Inspector tests May 17, 2016 3 - Alpha N/A - :pypi:`pytest-girder` A set of pytest fixtures for testing Girder applications. Jan 10, 2022 N/A N/A + :pypi:`pytest-girder` A set of pytest fixtures for testing Girder applications. Mar 01, 2022 N/A N/A :pypi:`pytest-git` Git repository fixture for py.test May 28, 2019 5 - Production/Stable pytest :pypi:`pytest-gitcov` Pytest plugin for reporting on coverage of the last git commit. Jan 11, 2020 2 - Pre-Alpha N/A :pypi:`pytest-git-fixtures` Pytest fixtures for testing with git. Mar 11, 2021 4 - Beta pytest @@ -419,20 +430,21 @@ This list contains 995 plugins. :pypi:`pytest-historic` Custom report to display pytest historical execution records Apr 08, 2020 N/A pytest :pypi:`pytest-historic-hook` Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report Apr 08, 2020 N/A pytest :pypi:`pytest-homeassistant` A pytest plugin for use with homeassistant custom components. Aug 12, 2020 4 - Beta N/A - :pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Feb 05, 2022 3 - Alpha pytest (==6.2.5) + :pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components Mar 16, 2022 3 - Alpha pytest (==7.0.1) :pypi:`pytest-honey` A simple plugin to use with pytest Jan 07, 2022 4 - Beta pytest (>=3.5.0) :pypi:`pytest-honors` Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A :pypi:`pytest-hoverfly` Simplify working with Hoverfly from pytest Jan 20, 2022 N/A pytest (>=5.0) - :pypi:`pytest-hoverfly-wrapper` Integrates the Hoverfly HTTP proxy into Pytest Aug 29, 2021 4 - Beta N/A + :pypi:`pytest-hoverfly-wrapper` Integrates the Hoverfly HTTP proxy into Pytest Feb 22, 2022 5 - Production/Stable N/A :pypi:`pytest-hpfeeds` Helpers for testing hpfeeds in your python project Aug 27, 2021 4 - Beta pytest (>=6.2.4,<7.0.0) :pypi:`pytest-html` pytest plugin for generating HTML reports Dec 13, 2020 5 - Production/Stable pytest (!=6.0.0,>=5.0) :pypi:`pytest-html-lee` optimized pytest plugin for generating HTML reports Jun 30, 2020 5 - Production/Stable pytest (>=5.0) - :pypi:`pytest-html-object-storage` Pytest report plugin for send HTML report on object-storage Jan 31, 2022 5 - Production/Stable N/A + :pypi:`pytest-html-merger` Pytest HTML reports merging utility Mar 02, 2022 N/A N/A + :pypi:`pytest-html-object-storage` Pytest report plugin for send HTML report on object-storage Mar 04, 2022 5 - Production/Stable N/A :pypi:`pytest-html-profiling` Pytest plugin for generating HTML reports with per-test profiling and optionally call graph visualizations. Based on pytest-html by Dave Hunt. Feb 11, 2020 5 - Production/Stable pytest (>=3.0) - :pypi:`pytest-html-reporter` Generates a static html report based on pytest framework Apr 25, 2021 N/A N/A + :pypi:`pytest-html-reporter` Generates a static html report based on pytest framework Feb 13, 2022 N/A N/A :pypi:`pytest-html-thread` pytest plugin for generating HTML reports Dec 29, 2020 5 - Production/Stable N/A :pypi:`pytest-http` Fixture "http" for http requests Dec 05, 2019 N/A N/A - :pypi:`pytest-httpbin` Easily test your HTTP library against a local copy of httpbin Dec 25, 2021 5 - Production/Stable N/A + :pypi:`pytest-httpbin` Easily test your HTTP library against a local copy of httpbin Mar 16, 2022 5 - Production/Stable pytest ; extra == 'test' :pypi:`pytest-http-mocker` Pytest plugin for http mocking (via https://github.com/vilus/mocker) Oct 20, 2019 N/A N/A :pypi:`pytest-httpretty` A thin wrapper of HTTPretty for pytest Feb 16, 2014 3 - Alpha N/A :pypi:`pytest-httpserver` pytest-httpserver is a httpserver for pytest Jan 27, 2022 3 - Alpha N/A @@ -446,7 +458,7 @@ This list contains 995 plugins. :pypi:`pytest-idapro` A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api Nov 03, 2018 N/A N/A :pypi:`pytest-idempotent` Pytest plugin for testing function idempotence. Jan 30, 2022 N/A N/A :pypi:`pytest-ignore-flaky` ignore failures from flaky tests (pytest plugin) Apr 23, 2021 5 - Production/Stable N/A - :pypi:`pytest-image-diff` Jan 20, 2022 3 - Alpha pytest + :pypi:`pytest-image-diff` Mar 17, 2022 3 - Alpha pytest :pypi:`pytest-incremental` an incremental test runner (pytest plugin) Apr 24, 2021 5 - Production/Stable N/A :pypi:`pytest-influxdb` Plugin for influxdb and pytest integration. Apr 20, 2021 N/A N/A :pypi:`pytest-info-collector` pytest plugin to collect information from tests May 26, 2019 3 - Alpha N/A @@ -454,32 +466,32 @@ This list contains 995 plugins. :pypi:`pytest-infrastructure` pytest stack validation prior to testing executing Apr 12, 2020 4 - Beta N/A :pypi:`pytest-ini` Reuse pytest.ini to store env variables Sep 30, 2021 N/A N/A :pypi:`pytest-inmanta` A py.test plugin providing fixtures to simplify inmanta modules testing. Jan 26, 2022 5 - Production/Stable N/A - :pypi:`pytest-inmanta-extensions` Inmanta tests package Feb 03, 2022 5 - Production/Stable N/A + :pypi:`pytest-inmanta-extensions` Inmanta tests package Feb 11, 2022 5 - Production/Stable N/A :pypi:`pytest-Inomaly` A simple image diff plugin for pytest Feb 13, 2018 4 - Beta N/A - :pypi:`pytest-insta` A practical snapshot testing plugin for pytest Apr 07, 2021 N/A pytest (>=6.0.2,<7.0.0) + :pypi:`pytest-insta` A practical snapshot testing plugin for pytest Feb 28, 2022 N/A pytest (>=6.0.2) :pypi:`pytest-instafail` pytest plugin to show failures instantly Jun 14, 2020 4 - Beta pytest (>=2.9) :pypi:`pytest-instrument` pytest plugin to instrument tests Apr 05, 2020 5 - Production/Stable pytest (>=5.1.0) :pypi:`pytest-integration` Organizing pytests by integration or not Apr 16, 2020 N/A N/A :pypi:`pytest-integration-mark` Automatic integration test marking and excluding plugin for pytest Jul 19, 2021 N/A pytest (>=5.2,<7.0) :pypi:`pytest-interactive` A pytest plugin for console based interactive test selection just after the collection phase Nov 30, 2017 3 - Alpha N/A :pypi:`pytest-intercept-remote` Pytest plugin for intercepting outgoing connection requests during pytest run. May 24, 2021 4 - Beta pytest (>=4.6) - :pypi:`pytest-invenio` Pytest fixtures for Invenio. May 11, 2021 5 - Production/Stable pytest (<7,>=6) + :pypi:`pytest-invenio` Pytest fixtures for Invenio. Feb 17, 2022 5 - Production/Stable pytest (<7,>=6) :pypi:`pytest-involve` Run tests covering a specific file or changeset Feb 02, 2020 4 - Beta pytest (>=3.5.0) :pypi:`pytest-ipdb` A py.test plug-in to enable drop to ipdb debugger on test failure. Sep 02, 2014 2 - Pre-Alpha N/A :pypi:`pytest-ipynb` THIS PROJECT IS ABANDONED Jan 29, 2019 3 - Alpha N/A - :pypi:`pytest-isort` py.test plugin to check import ordering using isort Apr 27, 2021 5 - Production/Stable N/A + :pypi:`pytest-isort` py.test plugin to check import ordering using isort Feb 08, 2022 5 - Production/Stable pytest (>=5.0) :pypi:`pytest-is-running` pytest plugin providing a function to check if pytest is running. Jan 10, 2022 5 - Production/Stable pytest :pypi:`pytest-it` Pytest plugin to display test reports as a plaintext spec, inspired by Rspec: https://github.com/mattduck/pytest-it. Jan 22, 2020 4 - Beta N/A :pypi:`pytest-iterassert` Nicer list and iterable assertion messages for pytest May 11, 2020 3 - Alpha N/A :pypi:`pytest-jasmine` Run jasmine tests from your pytest test suite Nov 04, 2017 1 - Planning N/A :pypi:`pytest-jest` A custom jest-pytest oriented Pytest reporter May 22, 2018 4 - Beta pytest (>=3.3.2) :pypi:`pytest-jira` py.test JIRA integration plugin, using markers Dec 02, 2021 3 - Alpha N/A - :pypi:`pytest-jira-xray` pytest plugin to integrate tests with JIRA XRAY Dec 10, 2021 3 - Alpha pytest + :pypi:`pytest-jira-xray` pytest plugin to integrate tests with JIRA XRAY Mar 09, 2022 3 - Alpha pytest :pypi:`pytest-jobserver` Limit parallel tests with posix jobserver. May 15, 2019 5 - Production/Stable pytest :pypi:`pytest-joke` Test failures are better served with humor. Oct 08, 2019 4 - Beta pytest (>=4.2.1) :pypi:`pytest-json` Generate JSON test reports Jan 18, 2016 4 - Beta N/A :pypi:`pytest-jsonlint` UNKNOWN Aug 04, 2016 N/A N/A - :pypi:`pytest-json-report` A pytest plugin to report test results as JSON files Sep 24, 2021 4 - Beta pytest (>=3.8.0) + :pypi:`pytest-json-report` A pytest plugin to report test results as JSON files Mar 15, 2022 4 - Beta pytest (>=3.8.0) :pypi:`pytest-kafka` Zookeeper, Kafka server, and Kafka consumer fixtures for Pytest Aug 24, 2021 N/A pytest :pypi:`pytest-kafkavents` A plugin to send pytest events to Kafka Sep 08, 2021 4 - Beta pytest :pypi:`pytest-kind` Kubernetes test support with KIND for pytest Jan 24, 2021 5 - Production/Stable N/A @@ -496,7 +508,7 @@ This list contains 995 plugins. :pypi:`pytest-leaks` A pytest plugin to trace resource leaks. Nov 27, 2019 1 - Planning N/A :pypi:`pytest-level` Select tests of a given level or lower Oct 21, 2019 N/A pytest :pypi:`pytest-libfaketime` A python-libfaketime plugin for pytest. Dec 22, 2018 4 - Beta pytest (>=3.0.0) - :pypi:`pytest-libiio` A pytest plugin to manage interfacing with libiio contexts Dec 15, 2021 4 - Beta N/A + :pypi:`pytest-libiio` A pytest plugin to manage interfacing with libiio contexts Feb 23, 2022 4 - Beta N/A :pypi:`pytest-libnotify` Pytest plugin that shows notifications about the test run Apr 02, 2021 3 - Alpha pytest :pypi:`pytest-ligo` Jan 16, 2020 4 - Beta N/A :pypi:`pytest-lineno` A pytest plugin to show the line numbers of test functions Dec 04, 2020 N/A pytest @@ -508,7 +520,7 @@ This list contains 995 plugins. :pypi:`pytest-localftpserver` A PyTest plugin which provides an FTP fixture for your tests Aug 25, 2021 5 - Production/Stable pytest :pypi:`pytest-localserver` py.test plugin to test server connections locally. Dec 13, 2021 4 - Beta N/A :pypi:`pytest-localstack` Pytest plugin for AWS integration tests Aug 22, 2019 4 - Beta pytest (>=3.3.0) - :pypi:`pytest-lockable` lockable resource plugin for pytest Nov 09, 2021 5 - Production/Stable pytest + :pypi:`pytest-lockable` lockable resource plugin for pytest Feb 28, 2022 5 - Production/Stable pytest :pypi:`pytest-locker` Used to lock object during testing. Essentially changing assertions from being hard coded to asserting that nothing changed Oct 29, 2021 N/A pytest (>=5.4) :pypi:`pytest-log` print log Aug 15, 2021 N/A pytest (>=3.8) :pypi:`pytest-logbook` py.test plugin to capture logbook log messages Nov 23, 2015 5 - Production/Stable pytest (>=2.8) @@ -517,6 +529,7 @@ This list contains 995 plugins. :pypi:`pytest-logger` Plugin configuring handlers for loggers from Python logging module. Jul 25, 2019 4 - Beta pytest (>=3.2) :pypi:`pytest-logging` Configures logging and allows tweaking the log level with a py.test flag Nov 04, 2015 4 - Beta N/A :pypi:`pytest-log-report` Package for creating a pytest test run reprot Dec 26, 2019 N/A N/A + :pypi:`pytest-loguru` Pytest Loguru Feb 27, 2022 5 - Production/Stable N/A :pypi:`pytest-manual-marker` pytest marker for marking manual tests Oct 11, 2021 3 - Alpha pytest (>=6) :pypi:`pytest-markdown` Test your markdown docs with pytest Jan 15, 2021 4 - Beta pytest (>=6.0.1,<7.0.0) :pypi:`pytest-marker-bugzilla` py.test bugzilla integration plugin, using markers Jan 09, 2020 N/A N/A @@ -530,12 +543,12 @@ This list contains 995 plugins. :pypi:`pytest-matrix` Provide tools for generating tests from combinations of fixtures. Jun 24, 2020 5 - Production/Stable pytest (>=5.4.3,<6.0.0) :pypi:`pytest-mccabe` pytest plugin to run the mccabe code complexity checker. Jul 22, 2020 3 - Alpha pytest (>=5.4.0) :pypi:`pytest-md` Plugin for generating Markdown reports for pytest results Jul 11, 2019 3 - Alpha pytest (>=4.2.1) - :pypi:`pytest-md-report` A pytest plugin to make a test results report with Markdown table format. May 04, 2021 4 - Beta pytest (!=6.0.0,<7,>=3.3.2) + :pypi:`pytest-md-report` A pytest plugin to make a test results report with Markdown table format. Feb 06, 2022 4 - Beta pytest (!=6.0.0,<8,>=3.3.2) :pypi:`pytest-memprof` Estimates memory consumption of test functions Mar 29, 2019 4 - Beta N/A :pypi:`pytest-menu` A pytest plugin for console based interactive test selection just after the collection phase Oct 04, 2017 3 - Alpha pytest (>=2.4.2) :pypi:`pytest-mercurial` pytest plugin to write integration tests for projects using Mercurial Python internals Nov 21, 2020 1 - Planning N/A :pypi:`pytest-message` Pytest plugin for sending report message of marked tests execution Jan 05, 2022 N/A pytest (>=6.2.5) - :pypi:`pytest-messenger` Pytest to Slack reporting plugin Dec 16, 2020 5 - Production/Stable N/A + :pypi:`pytest-messenger` Pytest to Slack reporting plugin Feb 07, 2022 5 - Production/Stable N/A :pypi:`pytest-metadata` pytest plugin for test session metadata Nov 27, 2020 5 - Production/Stable pytest (>=2.9.0) :pypi:`pytest-metrics` Custom metrics report for pytest Apr 04, 2020 N/A pytest :pypi:`pytest-mimesis` Mimesis integration with the pytest test runner Mar 21, 2020 5 - Production/Stable pytest (>=4.2) @@ -545,11 +558,11 @@ This list contains 995 plugins. :pypi:`pytest-mocha` pytest plugin to display test execution output like a mochajs Apr 02, 2020 4 - Beta pytest (>=5.4.0) :pypi:`pytest-mock` Thin-wrapper around the mock package for easier use with pytest Jan 28, 2022 5 - Production/Stable pytest (>=5.0) :pypi:`pytest-mock-api` A mock API server with configurable routes and responses available as a fixture. Feb 13, 2019 1 - Planning pytest (>=4.0.0) - :pypi:`pytest-mock-generator` A pytest fixture wrapper for https://pypi.org/project/mock-generator Jan 05, 2022 5 - Production/Stable N/A + :pypi:`pytest-mock-generator` A pytest fixture wrapper for https://pypi.org/project/mock-generator Mar 08, 2022 5 - Production/Stable N/A :pypi:`pytest-mock-helper` Help you mock HTTP call and generate mock code Jan 24, 2018 N/A pytest :pypi:`pytest-mockito` Base fixtures for mockito Jul 11, 2018 4 - Beta N/A :pypi:`pytest-mockredis` An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database. Jan 02, 2018 2 - Pre-Alpha N/A - :pypi:`pytest-mock-resources` A pytest plugin for easily instantiating reproducible mock resources. Jan 11, 2022 N/A pytest (>=1.0) + :pypi:`pytest-mock-resources` A pytest plugin for easily instantiating reproducible mock resources. Feb 26, 2022 N/A pytest (>=1.0) :pypi:`pytest-mock-server` Mock server plugin for pytest Jan 09, 2022 4 - Beta pytest (>=3.5.0) :pypi:`pytest-mockservers` A set of fixtures to test your requests to HTTP/UDP servers Mar 31, 2020 N/A pytest (>=4.3.0) :pypi:`pytest-modified-env` Pytest plugin to fail a test if it leaves modified \`os.environ\` afterwards. Jan 29, 2022 4 - Beta N/A @@ -565,27 +578,29 @@ This list contains 995 plugins. :pypi:`pytest-motor` A pytest plugin for motor, the non-blocking MongoDB driver. Jul 21, 2021 3 - Alpha pytest :pypi:`pytest-mp` A test batcher for multiprocessed Pytest runs May 23, 2018 4 - Beta pytest :pypi:`pytest-mpi` pytest plugin to collect information from tests Jan 08, 2022 3 - Alpha pytest - :pypi:`pytest-mpl` pytest plugin to help with testing figures output from Matplotlib Jul 02, 2021 4 - Beta pytest - :pypi:`pytest-mproc` low-startup-overhead, scalable, distributed-testing pytest plugin Mar 07, 2021 4 - Beta pytest + :pypi:`pytest-mpl` pytest plugin to help with testing figures output from Matplotlib Feb 09, 2022 4 - Beta pytest + :pypi:`pytest-mproc` low-startup-overhead, scalable, distributed-testing pytest plugin Feb 28, 2022 4 - Beta pytest :pypi:`pytest-multi-check` Pytest-плагин, реализует возможность мульти проверок и мягких проверок Jun 03, 2021 N/A pytest :pypi:`pytest-multihost` Utility for writing multi-host tests for pytest Apr 07, 2020 4 - Beta N/A :pypi:`pytest-multilog` Multi-process logs handling and other helpers for pytest Jun 10, 2021 N/A N/A :pypi:`pytest-multithreading` a pytest plugin for th and concurrent testing Aug 12, 2021 N/A pytest (>=3.6) :pypi:`pytest-mutagen` Add the mutation testing feature to pytest Jul 24, 2020 N/A pytest (>=5.4) - :pypi:`pytest-mypy` Mypy static type checker plugin for Pytest Jan 30, 2022 4 - Beta pytest (>=6.2) ; python_version >= "3.10" + :pypi:`pytest-mypy` Mypy static type checker plugin for Pytest Feb 07, 2022 4 - Beta pytest (>=6.2) ; python_version >= "3.10" :pypi:`pytest-mypyd` Mypy static type checker plugin for Pytest Aug 20, 2019 4 - Beta pytest (<4.7,>=2.8) ; python_version < "3.5" :pypi:`pytest-mypy-plugins` pytest plugin for writing tests for mypy plugins Jan 11, 2022 3 - Alpha pytest (>=6.0.0) :pypi:`pytest-mypy-plugins-shim` Substitute for "pytest-mypy-plugins" for Python implementations which aren't supported by mypy. Apr 12, 2021 N/A N/A - :pypi:`pytest-mypy-testing` Pytest plugin to check mypy output. Jun 13, 2021 N/A pytest - :pypi:`pytest-mysql` MySQL process and client fixtures for pytest Nov 22, 2021 5 - Production/Stable pytest + :pypi:`pytest-mypy-testing` Pytest plugin to check mypy output. Mar 02, 2022 N/A N/A + :pypi:`pytest-mysql` MySQL process and client fixtures for pytest Feb 15, 2022 5 - Production/Stable pytest (>=6.2) :pypi:`pytest-needle` pytest plugin for visual testing websites using selenium Dec 10, 2018 4 - Beta pytest (<5.0.0,>=3.0.0) :pypi:`pytest-neo` pytest-neo is a plugin for pytest that shows tests like screen of Matrix. Jan 08, 2022 3 - Alpha pytest (>=6.2.0) :pypi:`pytest-network` A simple plugin to disable network on socket level. May 07, 2020 N/A N/A + :pypi:`pytest-network-endpoints` Network endpoints plugin for pytest Mar 06, 2022 N/A pytest :pypi:`pytest-never-sleep` pytest plugin helps to avoid adding tests without mock \`time.sleep\` May 05, 2021 3 - Alpha pytest (>=3.5.1) :pypi:`pytest-nginx` nginx fixture for pytest Aug 12, 2017 5 - Production/Stable N/A :pypi:`pytest-nginx-iplweb` nginx fixture for pytest - iplweb temporary fork Mar 01, 2019 5 - Production/Stable N/A :pypi:`pytest-ngrok` Jan 20, 2022 3 - Alpha pytest :pypi:`pytest-ngsfixtures` pytest ngs fixtures Sep 06, 2019 2 - Pre-Alpha pytest (>=5.0.0) + :pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies Mar 15, 2022 N/A pytest (==6.2.5) :pypi:`pytest-nice` A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest :pypi:`pytest-nice-parametrize` A small snippet for nicer PyTest's Parametrize Apr 17, 2021 5 - Production/Stable N/A :pypi:`pytest-nlcov` Pytest plugin to get the coverage of the new lines (based on git diff) only Jul 07, 2021 N/A N/A @@ -597,17 +612,17 @@ This list contains 995 plugins. :pypi:`pytest-notifier` A pytest plugin to notify test result Jun 12, 2020 3 - Alpha pytest :pypi:`pytest-notimplemented` Pytest markers for not implemented features and tests. Aug 27, 2019 N/A pytest (>=5.1,<6.0) :pypi:`pytest-notion` A PyTest Reporter to send test runs to Notion.so Aug 07, 2019 N/A N/A - :pypi:`pytest-nunit` A pytest plugin for generating NUnit3 test result XML output Aug 04, 2020 4 - Beta pytest (>=3.5.0) + :pypi:`pytest-nunit` A pytest plugin for generating NUnit3 test result XML output Mar 16, 2022 4 - Beta pytest (>=4.6.0) :pypi:`pytest-ochrus` pytest results data-base and HTML reporter Feb 21, 2018 4 - Beta N/A - :pypi:`pytest-odoo` py.test plugin to run Odoo tests Nov 04, 2021 4 - Beta pytest (>=2.9) + :pypi:`pytest-odoo` py.test plugin to run Odoo tests Feb 08, 2022 4 - Beta N/A :pypi:`pytest-odoo-fixtures` Project description Jun 25, 2019 N/A N/A :pypi:`pytest-oerp` pytest plugin to test OpenERP modules Feb 28, 2012 3 - Alpha N/A :pypi:`pytest-ok` The ultimate pytest output plugin Apr 01, 2019 4 - Beta N/A :pypi:`pytest-only` Use @pytest.mark.only to run a single test Jan 19, 2020 N/A N/A :pypi:`pytest-oot` Run object-oriented tests in a simple format Sep 18, 2016 4 - Beta N/A :pypi:`pytest-openfiles` Pytest plugin for detecting inadvertent open file handles Apr 16, 2020 3 - Alpha pytest (>=4.6) - :pypi:`pytest-opentmi` pytest plugin for publish results to opentmi Jan 19, 2022 5 - Production/Stable pytest (>=5.0) - :pypi:`pytest-operator` Fixtures for Operators Jan 31, 2022 N/A N/A + :pypi:`pytest-opentmi` pytest plugin for publish results to opentmi Feb 28, 2022 5 - Production/Stable pytest (>=5.0) + :pypi:`pytest-operator` Fixtures for Operators Mar 17, 2022 N/A pytest :pypi:`pytest-optional` include/exclude values of fixtures in pytest Oct 07, 2015 N/A N/A :pypi:`pytest-optional-tests` Easy declaration of optional tests (i.e., that are not run by default) Jul 09, 2019 4 - Beta pytest (>=4.5.0) :pypi:`pytest-orchestration` A pytest plugin for orchestrating tests Jul 18, 2019 N/A N/A @@ -622,7 +637,7 @@ This list contains 995 plugins. :pypi:`pytest-param` pytest plugin to test all, first, last or random params Sep 11, 2016 4 - Beta pytest (>=2.6.0) :pypi:`pytest-paramark` Configure pytest fixtures using a combination of"parametrize" and markers Jan 10, 2020 4 - Beta pytest (>=4.5.0) :pypi:`pytest-parametrization` Simpler PyTest parametrization Nov 30, 2021 5 - Production/Stable pytest - :pypi:`pytest-parametrize-cases` A more user-friendly way to write parametrized tests. Dec 12, 2020 N/A pytest (>=6.1.2,<7.0.0) + :pypi:`pytest-parametrize-cases` A more user-friendly way to write parametrized tests. Mar 13, 2022 N/A pytest (>=6.1.2) :pypi:`pytest-parametrized` Pytest plugin for parametrizing tests with default iterables. Oct 19, 2020 5 - Production/Stable pytest :pypi:`pytest-parawtf` Finally spell paramete?ri[sz]e correctly Dec 03, 2018 4 - Beta pytest (>=3.6.0) :pypi:`pytest-pass` Check out https://github.com/elilutsky/pytest-pass Dec 04, 2019 N/A N/A @@ -636,7 +651,7 @@ This list contains 995 plugins. :pypi:`pytest-percent` Change the exit code of pytest test sessions when a required percent of tests pass. May 21, 2020 N/A pytest (>=5.2.0) :pypi:`pytest-perf` pytest-perf Feb 05, 2022 5 - Production/Stable pytest (>=6) ; extra == 'testing' :pypi:`pytest-performance` A simple plugin to ensure the execution of critical sections of code has not been impacted Sep 11, 2020 5 - Production/Stable pytest (>=3.7.0) - :pypi:`pytest-persistence` Pytest tool for persistent objects Dec 07, 2021 N/A N/A + :pypi:`pytest-persistence` Pytest tool for persistent objects Mar 14, 2022 N/A N/A :pypi:`pytest-pg` Helps to run PostgreSQL in docker as pytest fixture Jan 18, 2022 5 - Production/Stable pytest (>=6.0.0) :pypi:`pytest-pgsql` Pytest plugins and helpers for tests using a Postgres database. May 13, 2020 5 - Production/Stable pytest (>=3.0.0) :pypi:`pytest-phmdoctest` pytest plugin to test Python examples in Markdown using phmdoctest. Nov 10, 2021 4 - Beta pytest (>=6.2) ; extra == 'test' @@ -651,7 +666,7 @@ This list contains 995 plugins. :pypi:`pytest-platform-markers` Markers for pytest to skip tests on specific platforms Sep 09, 2019 4 - Beta pytest (>=3.6.0) :pypi:`pytest-play` pytest plugin that let you automate actions and assertions with test metrics reporting executing plain YAML files Jun 12, 2019 5 - Production/Stable N/A :pypi:`pytest-playbook` Pytest plugin for reading playbooks. Jan 21, 2021 3 - Alpha pytest (>=6.1.2,<7.0.0) - :pypi:`pytest-playwright` A pytest wrapper with fixtures for Playwright to automate web browsers Oct 28, 2021 N/A pytest + :pypi:`pytest-playwright` A pytest wrapper with fixtures for Playwright to automate web browsers Mar 16, 2022 N/A pytest :pypi:`pytest-playwrights` A pytest wrapper with fixtures for Playwright to automate web browsers Dec 02, 2021 N/A N/A :pypi:`pytest-playwright-snapshot` A pytest wrapper for snapshot testing with playwright Aug 19, 2021 N/A N/A :pypi:`pytest-plt` Fixtures for quickly making Matplotlib plots in tests Aug 17, 2020 5 - Production/Stable pytest @@ -668,7 +683,7 @@ This list contains 995 plugins. :pypi:`pytest-pop` A pytest plugin to help with testing pop projects Aug 19, 2021 5 - Production/Stable pytest :pypi:`pytest-portion` Select a portion of the collected tests Jan 28, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-postgres` Run PostgreSQL in Docker container in Pytest. Mar 22, 2020 N/A pytest - :pypi:`pytest-postgresql` Postgresql fixtures and fixture factories for Pytest. Dec 22, 2021 5 - Production/Stable pytest (>=6.2.0) + :pypi:`pytest-postgresql` Postgresql fixtures and fixture factories for Pytest. Mar 11, 2022 5 - Production/Stable pytest (>=6.2.0) :pypi:`pytest-power` pytest plugin with powerful fixtures Dec 31, 2020 N/A pytest (>=5.4) :pypi:`pytest-pretty-terminal` pytest plugin for generating prettier terminal output Jan 31, 2022 N/A pytest (>=3.4.1) :pypi:`pytest-pride` Minitest-style test colors Apr 02, 2016 3 - Alpha N/A @@ -677,17 +692,17 @@ This list contains 995 plugins. :pypi:`pytest-profiling` Profiling plugin for py.test May 28, 2019 5 - Production/Stable pytest :pypi:`pytest-progress` pytest plugin for instant test progress status Jan 31, 2022 5 - Production/Stable N/A :pypi:`pytest-prometheus` Report test pass / failures to a Prometheus PushGateway Oct 03, 2017 N/A N/A - :pypi:`pytest-prometheus-pushgateway` Pytest report plugin for Zulip Jan 31, 2022 5 - Production/Stable pytest + :pypi:`pytest-prometheus-pushgateway` Pytest report plugin for Zulip Feb 23, 2022 5 - Production/Stable pytest :pypi:`pytest-prosper` Test helpers for Prosper projects Sep 24, 2018 N/A N/A :pypi:`pytest-pspec` A rspec format reporter for Python ptest Jun 02, 2020 4 - Beta pytest (>=3.0.0) :pypi:`pytest-psqlgraph` pytest plugin for testing applications that use psqlgraph Oct 19, 2021 4 - Beta pytest (>=6.0) - :pypi:`pytest-ptera` Use ptera probes in tests Oct 20, 2021 N/A pytest (>=6.2.4,<7.0.0) + :pypi:`pytest-ptera` Use ptera probes in tests Mar 01, 2022 N/A pytest (>=6.2.4,<7.0.0) :pypi:`pytest-pudb` Pytest PuDB debugger integration Oct 25, 2018 3 - Alpha pytest (>=2.0) :pypi:`pytest-purkinje` py.test plugin for purkinje test runner Oct 28, 2017 2 - Pre-Alpha N/A :pypi:`pytest-pycharm` Plugin for py.test to enter PyCharm debugger on uncaught exceptions Aug 13, 2020 5 - Production/Stable pytest (>=2.3) - :pypi:`pytest-pycodestyle` pytest plugin to run pycodestyle Aug 10, 2020 3 - Alpha N/A + :pypi:`pytest-pycodestyle` pytest plugin to run pycodestyle Mar 13, 2022 3 - Alpha N/A :pypi:`pytest-pydev` py.test plugin to connect to a remote debug server with PyDev or PyCharm. Nov 15, 2017 3 - Alpha N/A - :pypi:`pytest-pydocstyle` pytest plugin to run pydocstyle Aug 10, 2020 3 - Alpha N/A + :pypi:`pytest-pydocstyle` pytest plugin to run pydocstyle Mar 13, 2022 3 - Alpha N/A :pypi:`pytest-pylint` pytest plugin to check source code with pylint Nov 09, 2020 5 - Production/Stable pytest (>=5.4) :pypi:`pytest-pypi` Easily test your HTTP library against a local copy of pypi Mar 04, 2018 3 - Alpha N/A :pypi:`pytest-pypom-navigation` Core engine for cookiecutter-qa and pytest-play packages Feb 18, 2019 4 - Beta pytest (>=3.0.7) @@ -697,35 +712,35 @@ This list contains 995 plugins. :pypi:`pytest-pyramid-server` Pyramid server fixture for py.test May 28, 2019 5 - Production/Stable pytest :pypi:`pytest-pyright` Pytest plugin for type checking code with Pyright Aug 16, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-pytestrail` Pytest plugin for interaction with TestRail Aug 27, 2020 4 - Beta pytest (>=3.8.0) - :pypi:`pytest-pythonpath` pytest plugin for adding to the PYTHONPATH from command line or configs. Aug 22, 2018 5 - Production/Stable N/A + :pypi:`pytest-pythonpath` pytest plugin for adding to the PYTHONPATH from command line or configs. Feb 10, 2022 5 - Production/Stable pytest (<7,>=2.5.2) :pypi:`pytest-pytorch` pytest plugin for a better developer experience when working with the PyTorch test suite May 25, 2021 4 - Beta pytest :pypi:`pytest-qasync` Pytest support for qasync. Jul 12, 2021 4 - Beta pytest (>=5.4.0) :pypi:`pytest-qatouch` Pytest plugin for uploading test results to your QA Touch Testrun. Jun 26, 2021 4 - Beta pytest (>=6.2.0) - :pypi:`pytest-qgis` A pytest plugin for testing QGIS python plugins Jan 18, 2022 5 - Production/Stable pytest (>=6.2.3) + :pypi:`pytest-qgis` A pytest plugin for testing QGIS python plugins Mar 17, 2022 5 - Production/Stable pytest (>=6.2.3) :pypi:`pytest-qml` Run QML Tests with pytest Dec 02, 2020 4 - Beta pytest (>=6.0.0) :pypi:`pytest-qr` pytest plugin to generate test result QR codes Nov 25, 2021 4 - Beta N/A :pypi:`pytest-qt` pytest support for PyQt and PySide applications Jun 13, 2021 5 - Production/Stable pytest (>=3.0.0) :pypi:`pytest-qt-app` QT app fixture for py.test Dec 23, 2015 5 - Production/Stable N/A :pypi:`pytest-quarantine` A plugin for pytest to manage expected test failures Nov 24, 2019 5 - Production/Stable pytest (>=4.6) :pypi:`pytest-quickcheck` pytest plugin to generate random data inspired by QuickCheck Nov 15, 2020 4 - Beta pytest (<6.0.0,>=4.0) - :pypi:`pytest-rabbitmq` RabbitMQ process and client fixtures for pytest Jun 02, 2021 5 - Production/Stable pytest (>=3.0.0) + :pypi:`pytest-rabbitmq` RabbitMQ process and client fixtures for pytest Feb 11, 2022 5 - Production/Stable pytest (>=3.0.0) :pypi:`pytest-race` Race conditions tester for pytest Nov 21, 2016 4 - Beta N/A :pypi:`pytest-rage` pytest plugin to implement PEP712 Oct 21, 2011 3 - Alpha N/A :pypi:`pytest-rail` pytest plugin for creating TestRail runs and adding results Feb 04, 2022 N/A pytest (>=3.6) - :pypi:`pytest-railflow-testrail-reporter` Generate json reports along with specified metadata defined in test markers. Dec 02, 2021 5 - Production/Stable pytest + :pypi:`pytest-railflow-testrail-reporter` Generate json reports along with specified metadata defined in test markers. Feb 25, 2022 5 - Production/Stable pytest :pypi:`pytest-raises` An implementation of pytest.raises as a pytest.mark fixture Apr 23, 2020 N/A pytest (>=3.2.2) :pypi:`pytest-raisesregexp` Simple pytest plugin to look for regex in Exceptions Dec 18, 2015 N/A N/A - :pypi:`pytest-raisin` Plugin enabling the use of exception instances with pytest.raises Jun 25, 2020 N/A pytest + :pypi:`pytest-raisin` Plugin enabling the use of exception instances with pytest.raises Feb 06, 2022 N/A pytest :pypi:`pytest-random` py.test plugin to randomize tests Apr 28, 2013 3 - Alpha N/A :pypi:`pytest-randomly` Pytest plugin to randomly order tests and control random.seed. Jan 10, 2022 5 - Production/Stable pytest :pypi:`pytest-randomness` Pytest plugin about random seed management May 30, 2019 3 - Alpha N/A :pypi:`pytest-random-num` Randomise the order in which pytest tests are run with some control over the randomness Oct 19, 2020 5 - Production/Stable N/A :pypi:`pytest-random-order` Randomise the order in which pytest tests are run with some control over the randomness Nov 30, 2018 5 - Production/Stable pytest (>=3.0.0) :pypi:`pytest-readme` Test your README.md file Dec 28, 2014 5 - Production/Stable N/A - :pypi:`pytest-reana` Pytest fixtures for REANA. Jan 05, 2022 3 - Alpha N/A + :pypi:`pytest-reana` Pytest fixtures for REANA. Feb 26, 2022 3 - Alpha N/A :pypi:`pytest-recording` A pytest plugin that allows you recording of network interactions via VCR.py Jul 08, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-recordings` Provides pytest plugins for reporting request/response traffic, screenshots, and more to ReportPortal Aug 13, 2020 N/A N/A - :pypi:`pytest-redis` Redis fixtures and fixture factories for Pytest. Dec 07, 2021 5 - Production/Stable pytest + :pypi:`pytest-redis` Redis fixtures and fixture factories for Pytest. Feb 10, 2022 5 - Production/Stable pytest (>=6.2.0) :pypi:`pytest-redislite` Pytest plugin for testing code using Redis Sep 19, 2021 4 - Beta pytest :pypi:`pytest-redmine` Pytest plugin for redmine Mar 19, 2018 1 - Planning N/A :pypi:`pytest-ref` A plugin to store reference files to ease regression testing Nov 23, 2019 4 - Beta pytest (>=3.5.0) @@ -750,21 +765,24 @@ This list contains 995 plugins. :pypi:`pytest-reportlog` Replacement for the --resultlog option, focused in simplicity and extensibility Dec 11, 2020 3 - Alpha pytest (>=5.2) :pypi:`pytest-report-me` A pytest plugin to generate report. Dec 31, 2020 N/A pytest :pypi:`pytest-report-parameters` pytest plugin for adding tests' parameters to junit report Jun 18, 2020 3 - Alpha pytest (>=2.4.2) - :pypi:`pytest-reportportal` Agent for Reporting results of tests to the Report Portal Jan 11, 2022 N/A pytest (>=3.8.0) + :pypi:`pytest-reportportal` Agent for Reporting results of tests to the Report Portal Feb 22, 2022 N/A pytest (>=3.8.0) :pypi:`pytest-reqs` pytest plugin to check pinned requirements May 12, 2019 N/A pytest (>=2.4.2) :pypi:`pytest-requests` A simple plugin to use with pytest Jun 24, 2019 4 - Beta pytest (>=3.5.0) :pypi:`pytest-requires` A pytest plugin to elegantly skip tests with optional requirements Dec 21, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-reraise` Make multi-threaded pytest test cases fail when they should Jun 17, 2021 5 - Production/Stable pytest (>=4.6) :pypi:`pytest-rerun` Re-run only changed files in specified branch Jul 08, 2019 N/A pytest (>=3.6) :pypi:`pytest-rerunfailures` pytest plugin to re-run tests to eliminate flaky failures Sep 17, 2021 5 - Production/Stable pytest (>=5.3) - :pypi:`pytest-resilient-circuits` Resilient Circuits fixtures for PyTest. Jan 20, 2022 N/A N/A + :pypi:`pytest-rerunfailures-all-logs` pytest plugin to re-run tests to eliminate flaky failures Mar 07, 2022 5 - Production/Stable N/A + :pypi:`pytest-resilient-circuits` Resilient Circuits fixtures for PyTest. Mar 07, 2022 N/A N/A :pypi:`pytest-resource` Load resource fixture plugin to use with pytest Nov 14, 2018 4 - Beta N/A :pypi:`pytest-resource-path` Provides path for uniform access to test resources in isolated directory May 01, 2021 5 - Production/Stable pytest (>=3.5.0) - :pypi:`pytest-responsemock` Simplified requests calls mocking for pytest Feb 04, 2022 5 - Production/Stable N/A + :pypi:`pytest-responsemock` Simplified requests calls mocking for pytest Mar 10, 2022 5 - Production/Stable N/A :pypi:`pytest-responses` py.test integration for responses Apr 26, 2021 N/A pytest (>=2.5) :pypi:`pytest-restrict` Pytest plugin to restrict the test types allowed Jan 10, 2022 5 - Production/Stable pytest :pypi:`pytest-rethinkdb` A RethinkDB plugin for pytest. Jul 24, 2016 4 - Beta N/A :pypi:`pytest-reverse` Pytest plugin to reverse test order. Jan 10, 2022 5 - Production/Stable pytest + :pypi:`pytest-rich` Leverage rich for richer test session output Mar 03, 2022 4 - Beta pytest (>=7.0) + :pypi:`pytest-rich-reporter` A pytest plugin using Rich for beautiful test result formatting. Feb 17, 2022 1 - Planning pytest (>=5.0.0) :pypi:`pytest-ringo` pytest plugin to test webapplications using the Ringo webframework Sep 27, 2017 3 - Alpha N/A :pypi:`pytest-rng` Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest :pypi:`pytest-roast` pytest plugin for ROAST configuration override and fixtures Jul 29, 2021 5 - Production/Stable pytest @@ -776,23 +794,23 @@ This list contains 995 plugins. :pypi:`pytest-rts` Coverage-based regression test selection (RTS) plugin for pytest May 17, 2021 N/A pytest :pypi:`pytest-run-changed` Pytest plugin that runs changed tests only Apr 02, 2021 3 - Alpha pytest :pypi:`pytest-runfailed` implement a --failed option for pytest Mar 24, 2016 N/A N/A - :pypi:`pytest-runner` Invoke py.test as distutils command with dependency resolution May 19, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing' + :pypi:`pytest-runner` Invoke py.test as distutils command with dependency resolution Feb 25, 2022 5 - Production/Stable pytest (>=6) ; extra == 'testing' :pypi:`pytest-runtime-xfail` Call runtime_xfail() to mark running test as xfail. Aug 26, 2021 N/A N/A :pypi:`pytest-salt` Pytest Salt Plugin Jan 27, 2020 4 - Beta N/A :pypi:`pytest-salt-containers` A Pytest plugin that builds and creates docker containers Nov 09, 2016 4 - Beta N/A - :pypi:`pytest-salt-factories` Pytest Salt Plugin Jan 27, 2022 4 - Beta pytest (>=6.0.0) + :pypi:`pytest-salt-factories` Pytest Salt Plugin Mar 12, 2022 4 - Beta pytest (>=6.0.0) :pypi:`pytest-salt-from-filenames` Simple PyTest Plugin For Salt's Test Suite Specifically Jan 29, 2019 4 - Beta pytest (>=4.1) :pypi:`pytest-salt-runtests-bridge` Simple PyTest Plugin For Salt's Test Suite Specifically Dec 05, 2019 4 - Beta pytest (>=4.1) :pypi:`pytest-sanic` a pytest plugin for Sanic Oct 25, 2021 N/A pytest (>=5.2) :pypi:`pytest-sanity` Dec 07, 2020 N/A N/A :pypi:`pytest-sa-pg` May 14, 2019 N/A N/A - :pypi:`pytest-sbase` A complete web automation framework for end-to-end testing. Feb 04, 2022 5 - Production/Stable N/A + :pypi:`pytest-sbase` A complete web automation framework for end-to-end testing. Mar 18, 2022 5 - Production/Stable N/A :pypi:`pytest-scenario` pytest plugin for test scenarios Feb 06, 2017 3 - Alpha N/A - :pypi:`pytest-schema` 👍 Validate return values against a schema-like object in testing Aug 31, 2020 5 - Production/Stable pytest (>=3.5.0) + :pypi:`pytest-schema` 👍 Validate return values against a schema-like object in testing Mar 14, 2022 5 - Production/Stable pytest (>=3.5.0) :pypi:`pytest-securestore` An encrypted password store for use within pytest cases Nov 08, 2021 4 - Beta N/A :pypi:`pytest-select` A pytest plugin which allows to (de-)select tests from a file. Jan 18, 2019 3 - Alpha pytest (>=3.0) :pypi:`pytest-selenium` pytest plugin for Selenium Sep 19, 2020 5 - Production/Stable pytest (>=5.0.0) - :pypi:`pytest-seleniumbase` A complete web automation framework for end-to-end testing. Feb 04, 2022 5 - Production/Stable N/A + :pypi:`pytest-seleniumbase` A complete web automation framework for end-to-end testing. Mar 18, 2022 5 - Production/Stable N/A :pypi:`pytest-selenium-enhancer` pytest plugin for Selenium Dec 16, 2021 5 - Production/Stable N/A :pypi:`pytest-selenium-pdiff` A pytest package implementing perceptualdiff for Selenium tests. Apr 06, 2017 2 - Pre-Alpha N/A :pypi:`pytest-send-email` Send pytest execution result email Dec 04, 2019 N/A N/A @@ -806,7 +824,7 @@ This list contains 995 plugins. :pypi:`pytest-sftpserver` py.test plugin to locally test sftp server connections. Sep 16, 2019 4 - Beta N/A :pypi:`pytest-shard` Dec 11, 2020 4 - Beta pytest :pypi:`pytest-shell` A pytest plugin to help with testing shell scripts / black box commands Nov 07, 2021 N/A N/A - :pypi:`pytest-shell-utilities` Pytest plugin to simplify running shell commands against the system Feb 05, 2022 4 - Beta pytest (>=6.0.0) + :pypi:`pytest-shell-utilities` Pytest plugin to simplify running shell commands against the system Feb 21, 2022 4 - Beta pytest (>=6.0.0) :pypi:`pytest-sheraf` Versatile ZODB abstraction layer - pytest fixtures Feb 11, 2020 N/A pytest :pypi:`pytest-sherlock` pytest plugin help to find coupled tests Nov 18, 2021 5 - Production/Stable pytest (>=3.5.1) :pypi:`pytest-shortcuts` Expand command-line shortcuts listed in pytest configuration Oct 29, 2020 4 - Beta pytest (>=3.5.0) @@ -815,7 +833,7 @@ This list contains 995 plugins. :pypi:`pytest-simple-plugin` Simple pytest plugin Nov 27, 2019 N/A N/A :pypi:`pytest-simple-settings` simple-settings plugin for pytest Nov 17, 2020 4 - Beta pytest :pypi:`pytest-single-file-logging` Allow for multiple processes to log to a single file May 05, 2016 4 - Beta pytest (>=2.8.1) - :pypi:`pytest-skip-markers` Pytest Salt Plugin Feb 05, 2022 5 - Production/Stable pytest (>=6.0.0) + :pypi:`pytest-skip-markers` Pytest Salt Plugin Feb 22, 2022 5 - Production/Stable pytest (>=6.0.0) :pypi:`pytest-skipper` A plugin that selects only tests with changes in execution path Mar 26, 2017 3 - Alpha pytest (>=3.0.6) :pypi:`pytest-skippy` Automatically skip tests that don't need to run! Jan 27, 2018 3 - Alpha pytest (>=2.3.4) :pypi:`pytest-skip-slow` A pytest plugin to skip \`@pytest.mark.slow\` tests by default. Sep 28, 2021 N/A N/A @@ -826,7 +844,7 @@ This list contains 995 plugins. :pypi:`pytest-smtp` Send email with pytest execution result Feb 20, 2021 N/A pytest :pypi:`pytest-snail` Plugin for adding a marker to slow running tests. 🐌 Nov 04, 2019 3 - Alpha pytest (>=5.0.1) :pypi:`pytest-snapci` py.test plugin for Snap-CI Nov 12, 2015 N/A N/A - :pypi:`pytest-snapshot` A plugin for snapshot testing with pytest. Dec 02, 2021 4 - Beta pytest (>=3.0.0) + :pypi:`pytest-snapshot` A plugin for snapshot testing with pytest. Feb 11, 2022 4 - Beta pytest (>=3.0.0) :pypi:`pytest-snmpserver` May 12, 2021 N/A N/A :pypi:`pytest-snowflake-bdd` Setup test data and run tests on snowflake in BDD style! Jan 05, 2022 4 - Beta pytest (>=6.2.0) :pypi:`pytest-socket` Pytest Plugin to disable socket calls during tests Jan 23, 2022 4 - Beta pytest (>=3.6.3) @@ -834,25 +852,26 @@ This list contains 995 plugins. :pypi:`pytest-solidity` A PyTest library plugin for Solidity language. Jan 15, 2022 1 - Planning pytest (<7,>=6.0.1) ; extra == 'tests' :pypi:`pytest-solr` Solr process and client fixtures for py.test. May 11, 2020 3 - Alpha pytest (>=3.0.0) :pypi:`pytest-sorter` A simple plugin to first execute tests that historically failed more Apr 20, 2021 4 - Beta pytest (>=3.1.1) - :pypi:`pytest-sosu` Unofficial PyTest plugin for Sauce Labs Dec 20, 2021 2 - Pre-Alpha pytest + :pypi:`pytest-sosu` Unofficial PyTest plugin for Sauce Labs Feb 21, 2022 2 - Pre-Alpha pytest :pypi:`pytest-sourceorder` Test-ordering plugin for pytest Sep 01, 2021 4 - Beta pytest :pypi:`pytest-spark` pytest plugin to run the tests with support of pyspark. Feb 23, 2020 4 - Beta pytest :pypi:`pytest-spawner` py.test plugin to spawn process and communicate with them. Jul 31, 2015 4 - Beta N/A :pypi:`pytest-spec` Library pytest-spec is a pytest plugin to display test execution output like a SPECIFICATION. May 04, 2021 N/A N/A :pypi:`pytest-sphinx` Doctest plugin for pytest with support for Sphinx-specific doctest-directives Aug 05, 2020 4 - Beta N/A - :pypi:`pytest-spiratest` Exports unit tests as test runs in SpiraTest/Team/Plan Oct 13, 2021 N/A N/A + :pypi:`pytest-spiratest` Exports unit tests as test runs in SpiraTest/Team/Plan Feb 08, 2022 N/A N/A :pypi:`pytest-splinter` Splinter plugin for pytest testing framework Dec 25, 2020 6 - Mature N/A :pypi:`pytest-splinter4` Pytest plugin for the splinter automation library Dec 22, 2021 6 - Mature pytest (>=6.2.4) - :pypi:`pytest-split` Pytest plugin which splits the test suite to equally sized sub suites based on test execution time. Jan 10, 2022 4 - Beta pytest (>=5,<7) + :pypi:`pytest-split` Pytest plugin which splits the test suite to equally sized sub suites based on test execution time. Mar 13, 2022 4 - Beta pytest (>=5,<8) :pypi:`pytest-splitio` Split.io SDK integration for e2e tests Sep 22, 2020 N/A pytest (<7,>=5.0) :pypi:`pytest-split-tests` A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Forked from Mark Adams' original project pytest-test-groups. Jul 30, 2021 5 - Production/Stable pytest (>=2.5) :pypi:`pytest-split-tests-tresorit` Feb 22, 2021 1 - Planning N/A - :pypi:`pytest-splunk-addon` A Dynamic test tool for Splunk Apps and Add-ons Jan 25, 2022 N/A pytest (>5.4.0,<6.3) - :pypi:`pytest-splunk-addon-ui-smartx` Library to support testing Splunk Add-on UX Dec 06, 2021 N/A N/A + :pypi:`pytest-splunk-addon` A Dynamic test tool for Splunk Apps and Add-ons Mar 16, 2022 N/A pytest (>5.4.0,<6.3) + :pypi:`pytest-splunk-addon-ui-smartx` Library to support testing Splunk Add-on UX Mar 16, 2022 N/A N/A :pypi:`pytest-splunk-env` pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud Oct 22, 2020 N/A pytest (>=6.1.1,<7.0.0) :pypi:`pytest-sqitch` sqitch for pytest Apr 06, 2020 4 - Beta N/A :pypi:`pytest-sqlalchemy` pytest plugin with sqlalchemy related fixtures Mar 13, 2018 3 - Alpha N/A :pypi:`pytest-sql-bigquery` Yet another SQL-testing framework for BigQuery provided by pytest plugin Dec 19, 2019 N/A pytest + :pypi:`pytest-squadcast` Pytest report plugin for Squadcast Feb 22, 2022 5 - Production/Stable pytest :pypi:`pytest-srcpaths` Add paths to sys.path Oct 15, 2021 N/A N/A :pypi:`pytest-ssh` pytest plugin for ssh command run May 27, 2019 N/A pytest :pypi:`pytest-start-from` Start pytest run from a given point Apr 11, 2016 N/A N/A @@ -867,16 +886,16 @@ This list contains 995 plugins. :pypi:`pytest-stub` Stub packages, modules and attributes. Apr 28, 2020 5 - Production/Stable N/A :pypi:`pytest-stubprocess` Provide stub implementations for subprocesses in Python tests Sep 17, 2018 3 - Alpha pytest (>=3.5.0) :pypi:`pytest-study` A pytest plugin to organize long run tests (named studies) without interfering the regular tests Sep 26, 2017 3 - Alpha pytest (>=2.0) - :pypi:`pytest-subprocess` A plugin to fake subprocess for pytest Jan 23, 2022 5 - Production/Stable pytest (>=4.0.0) + :pypi:`pytest-subprocess` A plugin to fake subprocess for pytest Feb 09, 2022 5 - Production/Stable pytest (>=4.0.0) :pypi:`pytest-subtesthack` A hack to explicitly set up and tear down fixtures. Mar 02, 2021 N/A N/A - :pypi:`pytest-subtests` unittest subTest() support and subtests fixture Jan 15, 2022 4 - Beta pytest (>=6.0) + :pypi:`pytest-subtests` unittest subTest() support and subtests fixture Feb 13, 2022 4 - Beta pytest (>=7.0) :pypi:`pytest-subunit` pytest-subunit is a plugin for py.test which outputs testsresult in subunit format. Aug 29, 2017 N/A N/A :pypi:`pytest-sugar` pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly). Jul 06, 2020 3 - Alpha N/A :pypi:`pytest-sugar-bugfix159` Workaround for https://github.com/Frozenball/pytest-sugar/issues/159 Nov 07, 2018 5 - Production/Stable pytest (!=3.7.3,>=3.5); extra == 'testing' :pypi:`pytest-super-check` Pytest plugin to check your TestCase classes call super in setUp, tearDown, etc. Jan 10, 2022 5 - Production/Stable pytest :pypi:`pytest-svn` SVN repository fixture for py.test May 28, 2019 5 - Production/Stable pytest :pypi:`pytest-symbols` pytest-symbols is a pytest plugin that adds support for passing test environment symbols into pytest tests. Nov 20, 2017 3 - Alpha N/A - :pypi:`pytest-system-statistics` Pytest plugin to track and report system usage statistics Jan 26, 2022 5 - Production/Stable pytest (>=6.0.0) + :pypi:`pytest-system-statistics` Pytest plugin to track and report system usage statistics Feb 16, 2022 5 - Production/Stable pytest (>=6.0.0) :pypi:`pytest-system-test-plugin` Pyst - Pytest System-Test Plugin Feb 03, 2022 N/A N/A :pypi:`pytest-takeltest` Fixtures for ansible, testinfra and molecule Jan 04, 2022 N/A N/A :pypi:`pytest-talisker` Nov 28, 2021 N/A N/A @@ -891,17 +910,17 @@ This list contains 995 plugins. :pypi:`pytest-terraform-fixture` generate terraform resources to use with pytest Nov 14, 2018 4 - Beta N/A :pypi:`pytest-testbook` A plugin to run tests written in Jupyter notebook Dec 11, 2016 3 - Alpha N/A :pypi:`pytest-testconfig` Test configuration plugin for pytest. Jan 11, 2020 4 - Beta pytest (>=3.5.0) - :pypi:`pytest-testdirectory` A py.test plugin providing temporary directories in unit tests. Nov 06, 2018 5 - Production/Stable pytest + :pypi:`pytest-testdirectory` A py.test plugin providing temporary directories in unit tests. Feb 21, 2022 5 - Production/Stable pytest :pypi:`pytest-testdox` A testdox format reporter for pytest Dec 05, 2021 5 - Production/Stable pytest (>=4.6.0) :pypi:`pytest-test-groups` A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Oct 25, 2016 5 - Production/Stable N/A - :pypi:`pytest-testinfra` Test infrastructures Dec 07, 2021 5 - Production/Stable pytest (!=3.0.2) + :pypi:`pytest-testinfra` Test infrastructures Feb 10, 2022 5 - Production/Stable pytest (!=3.0.2) :pypi:`pytest-testlink-adaptor` pytest reporting plugin for testlink Dec 20, 2018 4 - Beta pytest (>=2.6) - :pypi:`pytest-testmon` selects tests affected by changed files and methods Feb 05, 2022 4 - Beta N/A + :pypi:`pytest-testmon` selects tests affected by changed files and methods Mar 11, 2022 4 - Beta N/A :pypi:`pytest-testobject` Plugin to use TestObject Suites with Pytest Sep 24, 2019 4 - Beta pytest (>=3.1.1) :pypi:`pytest-testpluggy` set your encoding Jan 07, 2022 N/A pytest :pypi:`pytest-testrail` pytest plugin for creating TestRail runs and adding results Aug 27, 2020 N/A pytest (>=3.6) :pypi:`pytest-testrail2` A small example package Nov 17, 2020 N/A pytest (>=5) - :pypi:`pytest-testrail-api` Плагин Pytest, для интеграции с TestRail Dec 17, 2021 N/A pytest (>=5.5) + :pypi:`pytest-testrail-api` Плагин Pytest, для интеграции с TestRail Mar 11, 2022 N/A pytest (>=5.5) :pypi:`pytest-testrail-api-client` TestRail Api Python Client Dec 14, 2021 N/A pytest :pypi:`pytest-testrail-appetize` pytest plugin for creating TestRail runs and adding results Sep 29, 2021 N/A N/A :pypi:`pytest-testrail-client` pytest plugin for Testrail Sep 29, 2020 5 - Production/Stable N/A @@ -928,6 +947,7 @@ This list contains 995 plugins. :pypi:`pytest-tipsi-testing` Better fixtures management. Various helpers Nov 04, 2020 4 - Beta pytest (>=3.3.0) :pypi:`pytest-tldr` A pytest plugin that limits the output to just the things you need. Mar 12, 2021 4 - Beta pytest (>=3.5.0) :pypi:`pytest-tm4j-reporter` Cloud Jira Test Management (TM4J) PyTest reporter plugin Sep 01, 2020 N/A pytest + :pypi:`pytest-tmnet` A small example package Mar 01, 2022 N/A N/A :pypi:`pytest-tmreport` this is a vue-element ui report for pytest Nov 17, 2021 N/A N/A :pypi:`pytest-todo` A small plugin for the pytest testing framework, marking TODO comments as failure May 23, 2019 4 - Beta pytest :pypi:`pytest-tomato` Mar 01, 2019 5 - Production/Stable N/A @@ -946,10 +966,11 @@ This list contains 995 plugins. :pypi:`pytest-trio` Pytest plugin for trio Oct 16, 2020 N/A N/A :pypi:`pytest-trytond` Pytest plugin for the Tryton server framework Feb 02, 2022 3 - Alpha pytest (>=5) :pypi:`pytest-tspwplib` A simple plugin to use with tspwplib Jan 08, 2021 4 - Beta pytest (>=3.5.0) + :pypi:`pytest-tst` Customize pytest options, output and exit code to make it compatible with tst Mar 13, 2022 N/A pytest (>=5.0.0) :pypi:`pytest-tstcls` Test Class Base Mar 23, 2020 5 - Production/Stable N/A :pypi:`pytest-twisted` A twisted plugin for pytest. Aug 30, 2021 5 - Production/Stable pytest (>=2.3) :pypi:`pytest-typechecker` Run type checkers on specified test files Feb 04, 2022 N/A pytest (>=6.2.5,<7.0.0) - :pypi:`pytest-typhoon-xray` Typhoon HIL plugin for pytest Nov 03, 2021 4 - Beta N/A + :pypi:`pytest-typhoon-xray` Typhoon HIL plugin for pytest Mar 07, 2022 4 - Beta N/A :pypi:`pytest-tytest` Typhoon HIL plugin for pytest May 25, 2020 4 - Beta pytest (>=5.4.2) :pypi:`pytest-ubersmith` Easily mock calls to ubersmith at the \`requests\` level. Apr 13, 2015 N/A N/A :pypi:`pytest-ui` Text User Interface for running python tests Jul 05, 2021 4 - Beta pytest @@ -1010,9 +1031,9 @@ This list contains 995 plugins. :pypi:`pytest-yuk` Display tests you are uneasy with, using 🤢/🤮 for pass/fail of tests marked with yuk. Mar 26, 2021 N/A N/A :pypi:`pytest-zafira` A Zafira plugin for pytest Sep 18, 2019 5 - Production/Stable pytest (==4.1.1) :pypi:`pytest-zap` OWASP ZAP plugin for py.test. May 12, 2014 4 - Beta N/A - :pypi:`pytest-zebrunner` Pytest connector for Zebrunner reporting Feb 02, 2022 5 - Production/Stable pytest (>=4.5.0) + :pypi:`pytest-zebrunner` Pytest connector for Zebrunner reporting Mar 10, 2022 5 - Production/Stable pytest (>=4.5.0) :pypi:`pytest-zigzag` Extend py.test for RPC OpenStack testing. Feb 27, 2019 4 - Beta pytest (~=3.6) - :pypi:`pytest-zulip` Pytest report plugin for Zulip Jan 31, 2022 5 - Production/Stable pytest + :pypi:`pytest-zulip` Pytest report plugin for Zulip Mar 04, 2022 5 - Production/Stable pytest =============================================== ======================================================================================================================================================================== ============== ===================== ================================================ .. only:: latex @@ -1026,7 +1047,7 @@ This list contains 995 plugins. A pytest-plugin for updating doctest outputs :pypi:`pytest-adaptavist` - *last release*: Feb 01, 2022, + *last release*: Feb 22, 2022, *status*: N/A, *requires*: pytest (>=5.4.0) @@ -1082,7 +1103,7 @@ This list contains 995 plugins. pytest fixtures for writing aiofiles tests with pyfakefs :pypi:`pytest-aiohttp` - *last release*: Jan 21, 2022, + *last release*: Feb 12, 2022, *status*: 4 - Beta, *requires*: pytest (>=6.1.0) @@ -1096,7 +1117,7 @@ This list contains 995 plugins. Pytest \`client\` fixture for the Aiohttp :pypi:`pytest-aiomoto` - *last release*: Dec 10, 2021, + *last release*: Mar 13, 2022, *status*: N/A, *requires*: pytest (>=6.2.5,<7.0.0) @@ -1131,7 +1152,7 @@ This list contains 995 plugins. :pypi:`pytest-alembic` - *last release*: Dec 21, 2021, + *last release*: Mar 12, 2022, *status*: N/A, *requires*: pytest (>=1.0) @@ -1158,6 +1179,13 @@ This list contains 995 plugins. Plugin for py.test to generate allure xml reports + :pypi:`pytest-allure-collection` + *last release*: Feb 21, 2022, + *status*: N/A, + *requires*: pytest + + pytest plugin to collect allure markers without running any tests + :pypi:`pytest-allure-dsl` *last release*: Oct 25, 2020, *status*: 4 - Beta, @@ -1348,7 +1376,7 @@ This list contains 995 plugins. Meta-package containing dependencies for testing :pypi:`pytest-astropy-header` - *last release*: Dec 27, 2021, + *last release*: Mar 10, 2022, *status*: 3 - Alpha, *requires*: pytest (>=4.6) @@ -1362,14 +1390,14 @@ This list contains 995 plugins. :pypi:`pytest-asyncio` - *last release*: Jan 17, 2022, + *last release*: Mar 03, 2022, *status*: 4 - Beta, *requires*: pytest (>=6.1.0) Pytest support for asyncio :pypi:`pytest-asyncio-cooperative` - *last release*: Jan 25, 2022, + *last release*: Mar 16, 2022, *status*: N/A, *requires*: N/A @@ -1481,9 +1509,9 @@ This list contains 995 plugins. pytest plugin for axe-selenium-python :pypi:`pytest-azurepipelines` - *last release*: Jul 23, 2020, + *last release*: Mar 16, 2022, *status*: 4 - Beta, - *requires*: pytest (>=3.5.0) + *requires*: pytest (>=5.0.0) Formatting PyTest output for Azure Pipelines UI @@ -1600,9 +1628,9 @@ This list contains 995 plugins. A pytest plugin helps developers to debug by providing useful commits history. :pypi:`pytest-blender` - *last release*: Oct 29, 2021, + *last release*: Mar 11, 2022, *status*: N/A, - *requires*: pytest (==6.2.5) ; extra == 'dev' + *requires*: pytest ; extra == 'dev' Blender Pytest plugin. @@ -1635,7 +1663,7 @@ This list contains 995 plugins. Local continuous test runner with pytest and watchdog. :pypi:`pytest-bootstrap` - *last release*: Jan 28, 2022, + *last release*: Mar 04, 2022, *status*: N/A, *requires*: N/A @@ -1649,7 +1677,7 @@ This list contains 995 plugins. A py.test plug-in to enable drop to bpdb debugger on test failure. :pypi:`pytest-bravado` - *last release*: Jul 19, 2021, + *last release*: Feb 15, 2022, *status*: N/A, *requires*: N/A @@ -1754,9 +1782,9 @@ This list contains 995 plugins. pytest plugin with mechanisms for caching across test runs :pypi:`pytest-cache-assert` - *last release*: Nov 03, 2021, + *last release*: Mar 03, 2022, *status*: 4 - Beta, - *requires*: pytest (>=5) + *requires*: pytest (>=5.0.0) Cache assertion data to simplify regression testing of complex serializable data @@ -1768,11 +1796,11 @@ This list contains 995 plugins. Pytest plugin to only run tests affected by changes :pypi:`pytest-cairo` - *last release*: Feb 04, 2022, + *last release*: Mar 08, 2022, *status*: N/A, *requires*: pytest - + Pytest support for cairo-lang and starknet :pypi:`pytest-camel-collect` *last release*: Aug 02, 2020, @@ -1802,8 +1830,15 @@ This list contains 995 plugins. pytest plugin to capture all deprecatedwarnings and put them in one file + :pypi:`pytest-capture-warnings` + *last release*: Mar 16, 2022, + *status*: N/A, + *requires*: pytest + + pytest plugin to capture all warnings and put them in one file of your choice + :pypi:`pytest-cases` - *last release*: Jan 07, 2022, + *last release*: Mar 14, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -1851,6 +1886,13 @@ This list contains 995 plugins. A set of py.test fixtures for AWS Chalice + :pypi:`pytest-change-demo` + *last release*: Mar 02, 2022, + *status*: N/A, + *requires*: pytest + + turn . into √,turn F into x + :pypi:`pytest-change-report` *last release*: Sep 14, 2020, *status*: N/A, @@ -1929,11 +1971,11 @@ This list contains 995 plugins. Easy quality control for CLDF datasets using pytest :pypi:`pytest-click` - *last release*: Aug 29, 2020, + *last release*: Feb 11, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=5.0) - Py.test plugin for Click + Pytest plugin for Click :pypi:`pytest-clld` *last release*: Nov 29, 2021, @@ -2048,7 +2090,7 @@ This list contains 995 plugins. Package stands for pytest plugin to upload results into Confluence page. :pypi:`pytest-console-scripts` - *last release*: Jan 06, 2022, + *last release*: Mar 18, 2022, *status*: 4 - Beta, *requires*: N/A @@ -2139,12 +2181,19 @@ This list contains 995 plugins. Pytest plugin for excluding tests based on coverage data :pypi:`pytest-cpp` - *last release*: Dec 06, 2021, + *last release*: Mar 18, 2022, *status*: 5 - Production/Stable, *requires*: pytest (!=5.4.0,!=5.4.1) Use pytest's runner to discover and execute C++ tests + :pypi:`pytest-cppython` + *last release*: Mar 14, 2022, + *status*: N/A, + *requires*: N/A + + A pytest plugin that imports CPPython testing types + :pypi:`pytest-cram` *last release*: Aug 08, 2020, *status*: N/A, @@ -2285,6 +2334,13 @@ This list contains 995 plugins. Fixtures for pytest allowing test functions/methods to easily retrieve test resources from the local filesystem. + :pypi:`pytest-data-extractor` + *last release*: Mar 09, 2022, + *status*: N/A, + *requires*: pytest (>=7.0.1) + + A pytest plugin to extract relevant metadata about tests into an external file (currently only json support) + :pypi:`pytest-data-file` *last release*: Dec 04, 2019, *status*: N/A, @@ -2363,7 +2419,7 @@ This list contains 995 plugins. A pytest plugin for testing dbt adapter plugins :pypi:`pytest-dbt-conventions` - *last release*: Feb 04, 2022, + *last release*: Mar 02, 2022, *status*: N/A, *requires*: pytest (>=6.2.5,<7.0.0) @@ -2481,6 +2537,13 @@ This list contains 995 plugins. A simple plugin to use with pytest + :pypi:`pytest-diff-selector` + *last release*: Feb 24, 2022, + *status*: 4 - Beta, + *requires*: pytest (>=6.2.2) ; extra == 'all' + + Get tests affected by code changes (using git) + :pypi:`pytest-disable` *last release*: Sep 10, 2015, *status*: 4 - Beta, @@ -2496,9 +2559,9 @@ This list contains 995 plugins. Disable plugins per test :pypi:`pytest-discord` - *last release*: Mar 20, 2021, - *status*: 3 - Alpha, - *requires*: pytest (!=6.0.0,<7,>=3.3.2) + *last release*: Feb 12, 2022, + *status*: 4 - Beta, + *requires*: pytest (!=6.0.0,<8,>=3.3.2) A pytest plugin to notify test results to a Discord channel. @@ -2566,7 +2629,7 @@ This list contains 995 plugins. Cleanup your Haystack indexes between tests :pypi:`pytest-django-ifactory` - *last release*: Jan 13, 2021, + *last release*: Feb 09, 2022, *status*: 3 - Alpha, *requires*: N/A @@ -2663,6 +2726,13 @@ This list contains 995 plugins. Simple pytest fixtures for Docker and docker-compose based tests + :pypi:`pytest-docker-apache-fixtures` + *last release*: Feb 16, 2022, + *status*: 4 - Beta, + *requires*: pytest + + Pytest fixtures for testing with apache2 (httpd). + :pypi:`pytest-docker-butla` *last release*: Jun 16, 2019, *status*: 3 - Alpha, @@ -2699,14 +2769,14 @@ This list contains 995 plugins. pytest docker fixtures :pypi:`pytest-docker-git-fixtures` - *last release*: Mar 11, 2021, + *last release*: Feb 09, 2022, *status*: 4 - Beta, *requires*: pytest Pytest fixtures for testing with git scm. :pypi:`pytest-docker-haproxy-fixtures` - *last release*: Feb 01, 2022, + *last release*: Feb 09, 2022, *status*: 4 - Beta, *requires*: pytest @@ -2734,23 +2804,30 @@ This list contains 995 plugins. Easy to use, simple to extend, pytest plugin that minimally leverages docker-py. :pypi:`pytest-docker-registry-fixtures` - *last release*: Feb 01, 2022, + *last release*: Feb 09, 2022, *status*: 4 - Beta, *requires*: pytest Pytest fixtures for testing with docker registries. + :pypi:`pytest-docker-service` + *last release*: Mar 15, 2022, + *status*: 3 - Alpha, + *requires*: pytest + + pytest plugin to start docker container + :pypi:`pytest-docker-squid-fixtures` - *last release*: Feb 04, 2022, + *last release*: Feb 09, 2022, *status*: 4 - Beta, *requires*: pytest Pytest fixtures for testing with squid. :pypi:`pytest-docker-tools` - *last release*: Jul 23, 2021, + *last release*: Feb 17, 2022, *status*: 4 - Beta, - *requires*: pytest (>=6.0.1,<7.0.0) + *requires*: pytest (>=6.0.1) Docker integration tests for pytest @@ -2790,19 +2867,12 @@ This list contains 995 plugins. A simple pytest plugin to import names and add them to the doctest namespace. :pypi:`pytest-doctestplus` - *last release*: Dec 09, 2021, + *last release*: Feb 25, 2022, *status*: 3 - Alpha, *requires*: pytest (>=4.6) Pytest plugin with advanced doctest features. - :pypi:`pytest-doctest-ufunc` - *last release*: Aug 02, 2020, - *status*: 4 - Beta, - *requires*: pytest (>=3.5.0) - - A plugin to run doctests in docstrings of Numpy ufuncs - :pypi:`pytest-dolphin` *last release*: Nov 30, 2016, *status*: 4 - Beta, @@ -2866,6 +2936,13 @@ This list contains 995 plugins. + :pypi:`pytest-durations` + *last release*: Mar 07, 2022, + *status*: 5 - Production/Stable, + *requires*: pytest (>=4.6) + + Pytest plugin reporting fixtures and test functions execution time. + :pypi:`pytest-dynamicrerun` *last release*: Aug 15, 2020, *status*: 4 - Beta, @@ -2930,9 +3007,9 @@ This list contains 995 plugins. pytest plugin with mechanisms for echoing environment variables, package version and generic attributes :pypi:`pytest-elasticsearch` - *last release*: May 12, 2021, + *last release*: Mar 01, 2022, *status*: 5 - Production/Stable, - *requires*: pytest (>=3.0.0) + *requires*: pytest (>=6.2.0) Elasticsearch fixtures and fixture factories for Pytest. @@ -2958,35 +3035,35 @@ This list contains 995 plugins. Send execution result email :pypi:`pytest-embedded` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, - *requires*: pytest (>=6.2.0) + *requires*: pytest (>=7.0) pytest embedded plugin :pypi:`pytest-embedded-arduino` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A pytest embedded plugin for Arduino projects :pypi:`pytest-embedded-idf` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A pytest embedded plugin for esp-idf project :pypi:`pytest-embedded-jtag` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A pytest embedded plugin for testing with jtag :pypi:`pytest-embedded-qemu` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A @@ -3000,14 +3077,14 @@ This list contains 995 plugins. pytest embedded plugin for esp-idf project by qemu, not target chip :pypi:`pytest-embedded-serial` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A pytest embedded plugin for testing serial ports :pypi:`pytest-embedded-serial-esp` - *last release*: Jan 21, 2022, + *last release*: Mar 18, 2022, *status*: N/A, *requires*: N/A @@ -3210,9 +3287,9 @@ This list contains 995 plugins. A Pytest plugin to ignore certain marked tests by default :pypi:`pytest-exploratory` - *last release*: Aug 03, 2021, + *last release*: Feb 21, 2022, *status*: N/A, - *requires*: pytest (>=5.3) + *requires*: pytest (>=6.2) Interactive console for pytest. @@ -3440,6 +3517,13 @@ This list contains 995 plugins. pytest plugin to control fixture evaluation order + :pypi:`pytest-fixture-rtttg` + *last release*: Feb 23, 2022, + *status*: N/A, + *requires*: pytest (>=7.0.1,<8.0.0) + + Warn or fail on fixture name clash + :pypi:`pytest-fixtures` *last release*: May 01, 2019, *status*: 5 - Production/Stable, @@ -3462,9 +3546,9 @@ This list contains 995 plugins. A pytest plugin to assert type annotations at runtime. :pypi:`pytest-flake8` - *last release*: Dec 16, 2020, + *last release*: Mar 18, 2022, *status*: 4 - Beta, - *requires*: pytest (>=3.5) + *requires*: pytest (>=7.0) pytest plugin to check FLAKE8 requirements @@ -3476,9 +3560,9 @@ This list contains 995 plugins. A pytest fixture for testing flake8 plugins. :pypi:`pytest-flake8-v2` - *last release*: Jan 25, 2022, - *status*: 4 - Beta, - *requires*: pytest (>=6.0) + *last release*: Mar 01, 2022, + *status*: 5 - Production/Stable, + *requires*: pytest (>=7.0) pytest plugin to check FLAKE8 requirements @@ -3538,6 +3622,13 @@ This list contains 995 plugins. A pytest plugin that alerts user of failed test cases with screen notifications + :pypi:`pytest-fold` + *last release*: Feb 20, 2022, + *status*: 4 - Beta, + *requires*: pytest (>=6.2.5) + + Fold console output and drop user into interactive text user interface + :pypi:`pytest-forcefail` *last release*: May 15, 2018, *status*: 4 - Beta, @@ -3574,7 +3665,7 @@ This list contains 995 plugins. Check if requirement files are frozen :pypi:`pytest-frozen-uuids` - *last release*: Dec 08, 2021, + *last release*: Feb 14, 2022, *status*: N/A, *requires*: pytest (>=3.0) @@ -3608,6 +3699,13 @@ This list contains 995 plugins. + :pypi:`pytest-gather-fixtures` + *last release*: Mar 15, 2022, + *status*: N/A, + *requires*: pytest (>=6.0.0,<7.0.0) + + set up asynchronous pytest fixtures concurrently + :pypi:`pytest-gc` *last release*: Feb 01, 2018, *status*: N/A, @@ -3651,7 +3749,7 @@ This list contains 995 plugins. For finding/executing Ghost Inspector tests :pypi:`pytest-girder` - *last release*: Jan 10, 2022, + *last release*: Mar 01, 2022, *status*: N/A, *requires*: N/A @@ -3826,9 +3924,9 @@ This list contains 995 plugins. A pytest plugin for use with homeassistant custom components. :pypi:`pytest-homeassistant-custom-component` - *last release*: Feb 05, 2022, + *last release*: Mar 16, 2022, *status*: 3 - Alpha, - *requires*: pytest (==6.2.5) + *requires*: pytest (==7.0.1) Experimental package to automatically extract test plugins for Home Assistant custom components @@ -3854,8 +3952,8 @@ This list contains 995 plugins. Simplify working with Hoverfly from pytest :pypi:`pytest-hoverfly-wrapper` - *last release*: Aug 29, 2021, - *status*: 4 - Beta, + *last release*: Feb 22, 2022, + *status*: 5 - Production/Stable, *requires*: N/A Integrates the Hoverfly HTTP proxy into Pytest @@ -3881,8 +3979,15 @@ This list contains 995 plugins. optimized pytest plugin for generating HTML reports + :pypi:`pytest-html-merger` + *last release*: Mar 02, 2022, + *status*: N/A, + *requires*: N/A + + Pytest HTML reports merging utility + :pypi:`pytest-html-object-storage` - *last release*: Jan 31, 2022, + *last release*: Mar 04, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -3896,7 +4001,7 @@ This list contains 995 plugins. Pytest plugin for generating HTML reports with per-test profiling and optionally call graph visualizations. Based on pytest-html by Dave Hunt. :pypi:`pytest-html-reporter` - *last release*: Apr 25, 2021, + *last release*: Feb 13, 2022, *status*: N/A, *requires*: N/A @@ -3917,9 +4022,9 @@ This list contains 995 plugins. Fixture "http" for http requests :pypi:`pytest-httpbin` - *last release*: Dec 25, 2021, + *last release*: Mar 16, 2022, *status*: 5 - Production/Stable, - *requires*: N/A + *requires*: pytest ; extra == 'test' Easily test your HTTP library against a local copy of httpbin @@ -4015,7 +4120,7 @@ This list contains 995 plugins. ignore failures from flaky tests (pytest plugin) :pypi:`pytest-image-diff` - *last release*: Jan 20, 2022, + *last release*: Mar 17, 2022, *status*: 3 - Alpha, *requires*: pytest @@ -4071,7 +4176,7 @@ This list contains 995 plugins. A py.test plugin providing fixtures to simplify inmanta modules testing. :pypi:`pytest-inmanta-extensions` - *last release*: Feb 03, 2022, + *last release*: Feb 11, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -4085,9 +4190,9 @@ This list contains 995 plugins. A simple image diff plugin for pytest :pypi:`pytest-insta` - *last release*: Apr 07, 2021, + *last release*: Feb 28, 2022, *status*: N/A, - *requires*: pytest (>=6.0.2,<7.0.0) + *requires*: pytest (>=6.0.2) A practical snapshot testing plugin for pytest @@ -4134,7 +4239,7 @@ This list contains 995 plugins. Pytest plugin for intercepting outgoing connection requests during pytest run. :pypi:`pytest-invenio` - *last release*: May 11, 2021, + *last release*: Feb 17, 2022, *status*: 5 - Production/Stable, *requires*: pytest (<7,>=6) @@ -4162,9 +4267,9 @@ This list contains 995 plugins. THIS PROJECT IS ABANDONED :pypi:`pytest-isort` - *last release*: Apr 27, 2021, + *last release*: Feb 08, 2022, *status*: 5 - Production/Stable, - *requires*: N/A + *requires*: pytest (>=5.0) py.test plugin to check import ordering using isort @@ -4211,7 +4316,7 @@ This list contains 995 plugins. py.test JIRA integration plugin, using markers :pypi:`pytest-jira-xray` - *last release*: Dec 10, 2021, + *last release*: Mar 09, 2022, *status*: 3 - Alpha, *requires*: pytest @@ -4246,7 +4351,7 @@ This list contains 995 plugins. UNKNOWN :pypi:`pytest-json-report` - *last release*: Sep 24, 2021, + *last release*: Mar 15, 2022, *status*: 4 - Beta, *requires*: pytest (>=3.8.0) @@ -4365,7 +4470,7 @@ This list contains 995 plugins. A python-libfaketime plugin for pytest. :pypi:`pytest-libiio` - *last release*: Dec 15, 2021, + *last release*: Feb 23, 2022, *status*: 4 - Beta, *requires*: N/A @@ -4449,7 +4554,7 @@ This list contains 995 plugins. Pytest plugin for AWS integration tests :pypi:`pytest-lockable` - *last release*: Nov 09, 2021, + *last release*: Feb 28, 2022, *status*: 5 - Production/Stable, *requires*: pytest @@ -4511,6 +4616,13 @@ This list contains 995 plugins. Package for creating a pytest test run reprot + :pypi:`pytest-loguru` + *last release*: Feb 27, 2022, + *status*: 5 - Production/Stable, + *requires*: N/A + + Pytest Loguru + :pypi:`pytest-manual-marker` *last release*: Oct 11, 2021, *status*: 3 - Alpha, @@ -4603,9 +4715,9 @@ This list contains 995 plugins. Plugin for generating Markdown reports for pytest results :pypi:`pytest-md-report` - *last release*: May 04, 2021, + *last release*: Feb 06, 2022, *status*: 4 - Beta, - *requires*: pytest (!=6.0.0,<7,>=3.3.2) + *requires*: pytest (!=6.0.0,<8,>=3.3.2) A pytest plugin to make a test results report with Markdown table format. @@ -4638,7 +4750,7 @@ This list contains 995 plugins. Pytest plugin for sending report message of marked tests execution :pypi:`pytest-messenger` - *last release*: Dec 16, 2020, + *last release*: Feb 07, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -4708,7 +4820,7 @@ This list contains 995 plugins. A mock API server with configurable routes and responses available as a fixture. :pypi:`pytest-mock-generator` - *last release*: Jan 05, 2022, + *last release*: Mar 08, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -4736,7 +4848,7 @@ This list contains 995 plugins. An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database. :pypi:`pytest-mock-resources` - *last release*: Jan 11, 2022, + *last release*: Feb 26, 2022, *status*: N/A, *requires*: pytest (>=1.0) @@ -4848,14 +4960,14 @@ This list contains 995 plugins. pytest plugin to collect information from tests :pypi:`pytest-mpl` - *last release*: Jul 02, 2021, + *last release*: Feb 09, 2022, *status*: 4 - Beta, *requires*: pytest pytest plugin to help with testing figures output from Matplotlib :pypi:`pytest-mproc` - *last release*: Mar 07, 2021, + *last release*: Feb 28, 2022, *status*: 4 - Beta, *requires*: pytest @@ -4897,7 +5009,7 @@ This list contains 995 plugins. Add the mutation testing feature to pytest :pypi:`pytest-mypy` - *last release*: Jan 30, 2022, + *last release*: Feb 07, 2022, *status*: 4 - Beta, *requires*: pytest (>=6.2) ; python_version >= "3.10" @@ -4925,16 +5037,16 @@ This list contains 995 plugins. Substitute for "pytest-mypy-plugins" for Python implementations which aren't supported by mypy. :pypi:`pytest-mypy-testing` - *last release*: Jun 13, 2021, + *last release*: Mar 02, 2022, *status*: N/A, - *requires*: pytest + *requires*: N/A Pytest plugin to check mypy output. :pypi:`pytest-mysql` - *last release*: Nov 22, 2021, + *last release*: Feb 15, 2022, *status*: 5 - Production/Stable, - *requires*: pytest + *requires*: pytest (>=6.2) MySQL process and client fixtures for pytest @@ -4959,6 +5071,13 @@ This list contains 995 plugins. A simple plugin to disable network on socket level. + :pypi:`pytest-network-endpoints` + *last release*: Mar 06, 2022, + *status*: N/A, + *requires*: pytest + + Network endpoints plugin for pytest + :pypi:`pytest-never-sleep` *last release*: May 05, 2021, *status*: 3 - Alpha, @@ -4994,6 +5113,13 @@ This list contains 995 plugins. pytest ngs fixtures + :pypi:`pytest-nhsd-apim` + *last release*: Mar 15, 2022, + *status*: N/A, + *requires*: pytest (==6.2.5) + + Pytest plugin accessing NHSDigital's APIM proxies + :pypi:`pytest-nice` *last release*: May 04, 2019, *status*: 4 - Beta, @@ -5072,9 +5198,9 @@ This list contains 995 plugins. A PyTest Reporter to send test runs to Notion.so :pypi:`pytest-nunit` - *last release*: Aug 04, 2020, + *last release*: Mar 16, 2022, *status*: 4 - Beta, - *requires*: pytest (>=3.5.0) + *requires*: pytest (>=4.6.0) A pytest plugin for generating NUnit3 test result XML output @@ -5086,9 +5212,9 @@ This list contains 995 plugins. pytest results data-base and HTML reporter :pypi:`pytest-odoo` - *last release*: Nov 04, 2021, + *last release*: Feb 08, 2022, *status*: 4 - Beta, - *requires*: pytest (>=2.9) + *requires*: N/A py.test plugin to run Odoo tests @@ -5135,16 +5261,16 @@ This list contains 995 plugins. Pytest plugin for detecting inadvertent open file handles :pypi:`pytest-opentmi` - *last release*: Jan 19, 2022, + *last release*: Feb 28, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=5.0) pytest plugin for publish results to opentmi :pypi:`pytest-operator` - *last release*: Jan 31, 2022, + *last release*: Mar 17, 2022, *status*: N/A, - *requires*: N/A + *requires*: pytest Fixtures for Operators @@ -5247,9 +5373,9 @@ This list contains 995 plugins. Simpler PyTest parametrization :pypi:`pytest-parametrize-cases` - *last release*: Dec 12, 2020, + *last release*: Mar 13, 2022, *status*: N/A, - *requires*: pytest (>=6.1.2,<7.0.0) + *requires*: pytest (>=6.1.2) A more user-friendly way to write parametrized tests. @@ -5345,7 +5471,7 @@ This list contains 995 plugins. A simple plugin to ensure the execution of critical sections of code has not been impacted :pypi:`pytest-persistence` - *last release*: Dec 07, 2021, + *last release*: Mar 14, 2022, *status*: N/A, *requires*: N/A @@ -5450,7 +5576,7 @@ This list contains 995 plugins. Pytest plugin for reading playbooks. :pypi:`pytest-playwright` - *last release*: Oct 28, 2021, + *last release*: Mar 16, 2022, *status*: N/A, *requires*: pytest @@ -5569,7 +5695,7 @@ This list contains 995 plugins. Run PostgreSQL in Docker container in Pytest. :pypi:`pytest-postgresql` - *last release*: Dec 22, 2021, + *last release*: Mar 11, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=6.2.0) @@ -5632,7 +5758,7 @@ This list contains 995 plugins. Report test pass / failures to a Prometheus PushGateway :pypi:`pytest-prometheus-pushgateway` - *last release*: Jan 31, 2022, + *last release*: Feb 23, 2022, *status*: 5 - Production/Stable, *requires*: pytest @@ -5660,7 +5786,7 @@ This list contains 995 plugins. pytest plugin for testing applications that use psqlgraph :pypi:`pytest-ptera` - *last release*: Oct 20, 2021, + *last release*: Mar 01, 2022, *status*: N/A, *requires*: pytest (>=6.2.4,<7.0.0) @@ -5688,7 +5814,7 @@ This list contains 995 plugins. Plugin for py.test to enter PyCharm debugger on uncaught exceptions :pypi:`pytest-pycodestyle` - *last release*: Aug 10, 2020, + *last release*: Mar 13, 2022, *status*: 3 - Alpha, *requires*: N/A @@ -5702,7 +5828,7 @@ This list contains 995 plugins. py.test plugin to connect to a remote debug server with PyDev or PyCharm. :pypi:`pytest-pydocstyle` - *last release*: Aug 10, 2020, + *last release*: Mar 13, 2022, *status*: 3 - Alpha, *requires*: N/A @@ -5772,9 +5898,9 @@ This list contains 995 plugins. Pytest plugin for interaction with TestRail :pypi:`pytest-pythonpath` - *last release*: Aug 22, 2018, + *last release*: Feb 10, 2022, *status*: 5 - Production/Stable, - *requires*: N/A + *requires*: pytest (<7,>=2.5.2) pytest plugin for adding to the PYTHONPATH from command line or configs. @@ -5800,7 +5926,7 @@ This list contains 995 plugins. Pytest plugin for uploading test results to your QA Touch Testrun. :pypi:`pytest-qgis` - *last release*: Jan 18, 2022, + *last release*: Mar 17, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=6.2.3) @@ -5849,7 +5975,7 @@ This list contains 995 plugins. pytest plugin to generate random data inspired by QuickCheck :pypi:`pytest-rabbitmq` - *last release*: Jun 02, 2021, + *last release*: Feb 11, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=3.0.0) @@ -5877,7 +6003,7 @@ This list contains 995 plugins. pytest plugin for creating TestRail runs and adding results :pypi:`pytest-railflow-testrail-reporter` - *last release*: Dec 02, 2021, + *last release*: Feb 25, 2022, *status*: 5 - Production/Stable, *requires*: pytest @@ -5898,7 +6024,7 @@ This list contains 995 plugins. Simple pytest plugin to look for regex in Exceptions :pypi:`pytest-raisin` - *last release*: Jun 25, 2020, + *last release*: Feb 06, 2022, *status*: N/A, *requires*: pytest @@ -5947,7 +6073,7 @@ This list contains 995 plugins. Test your README.md file :pypi:`pytest-reana` - *last release*: Jan 05, 2022, + *last release*: Feb 26, 2022, *status*: 3 - Alpha, *requires*: N/A @@ -5968,9 +6094,9 @@ This list contains 995 plugins. Provides pytest plugins for reporting request/response traffic, screenshots, and more to ReportPortal :pypi:`pytest-redis` - *last release*: Dec 07, 2021, + *last release*: Feb 10, 2022, *status*: 5 - Production/Stable, - *requires*: pytest + *requires*: pytest (>=6.2.0) Redis fixtures and fixture factories for Pytest. @@ -6143,7 +6269,7 @@ This list contains 995 plugins. pytest plugin for adding tests' parameters to junit report :pypi:`pytest-reportportal` - *last release*: Jan 11, 2022, + *last release*: Feb 22, 2022, *status*: N/A, *requires*: pytest (>=3.8.0) @@ -6191,8 +6317,15 @@ This list contains 995 plugins. pytest plugin to re-run tests to eliminate flaky failures + :pypi:`pytest-rerunfailures-all-logs` + *last release*: Mar 07, 2022, + *status*: 5 - Production/Stable, + *requires*: N/A + + pytest plugin to re-run tests to eliminate flaky failures + :pypi:`pytest-resilient-circuits` - *last release*: Jan 20, 2022, + *last release*: Mar 07, 2022, *status*: N/A, *requires*: N/A @@ -6213,7 +6346,7 @@ This list contains 995 plugins. Provides path for uniform access to test resources in isolated directory :pypi:`pytest-responsemock` - *last release*: Feb 04, 2022, + *last release*: Mar 10, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -6247,6 +6380,20 @@ This list contains 995 plugins. Pytest plugin to reverse test order. + :pypi:`pytest-rich` + *last release*: Mar 03, 2022, + *status*: 4 - Beta, + *requires*: pytest (>=7.0) + + Leverage rich for richer test session output + + :pypi:`pytest-rich-reporter` + *last release*: Feb 17, 2022, + *status*: 1 - Planning, + *requires*: pytest (>=5.0.0) + + A pytest plugin using Rich for beautiful test result formatting. + :pypi:`pytest-ringo` *last release*: Sep 27, 2017, *status*: 3 - Alpha, @@ -6325,9 +6472,9 @@ This list contains 995 plugins. implement a --failed option for pytest :pypi:`pytest-runner` - *last release*: May 19, 2021, + *last release*: Feb 25, 2022, *status*: 5 - Production/Stable, - *requires*: pytest (>=4.6) ; extra == 'testing' + *requires*: pytest (>=6) ; extra == 'testing' Invoke py.test as distutils command with dependency resolution @@ -6353,7 +6500,7 @@ This list contains 995 plugins. A Pytest plugin that builds and creates docker containers :pypi:`pytest-salt-factories` - *last release*: Jan 27, 2022, + *last release*: Mar 12, 2022, *status*: 4 - Beta, *requires*: pytest (>=6.0.0) @@ -6395,7 +6542,7 @@ This list contains 995 plugins. :pypi:`pytest-sbase` - *last release*: Feb 04, 2022, + *last release*: Mar 18, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -6409,7 +6556,7 @@ This list contains 995 plugins. pytest plugin for test scenarios :pypi:`pytest-schema` - *last release*: Aug 31, 2020, + *last release*: Mar 14, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=3.5.0) @@ -6437,7 +6584,7 @@ This list contains 995 plugins. pytest plugin for Selenium :pypi:`pytest-seleniumbase` - *last release*: Feb 04, 2022, + *last release*: Mar 18, 2022, *status*: 5 - Production/Stable, *requires*: N/A @@ -6535,7 +6682,7 @@ This list contains 995 plugins. A pytest plugin to help with testing shell scripts / black box commands :pypi:`pytest-shell-utilities` - *last release*: Feb 05, 2022, + *last release*: Feb 21, 2022, *status*: 4 - Beta, *requires*: pytest (>=6.0.0) @@ -6598,7 +6745,7 @@ This list contains 995 plugins. Allow for multiple processes to log to a single file :pypi:`pytest-skip-markers` - *last release*: Feb 05, 2022, + *last release*: Feb 22, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=6.0.0) @@ -6675,7 +6822,7 @@ This list contains 995 plugins. py.test plugin for Snap-CI :pypi:`pytest-snapshot` - *last release*: Dec 02, 2021, + *last release*: Feb 11, 2022, *status*: 4 - Beta, *requires*: pytest (>=3.0.0) @@ -6731,7 +6878,7 @@ This list contains 995 plugins. A simple plugin to first execute tests that historically failed more :pypi:`pytest-sosu` - *last release*: Dec 20, 2021, + *last release*: Feb 21, 2022, *status*: 2 - Pre-Alpha, *requires*: pytest @@ -6773,7 +6920,7 @@ This list contains 995 plugins. Doctest plugin for pytest with support for Sphinx-specific doctest-directives :pypi:`pytest-spiratest` - *last release*: Oct 13, 2021, + *last release*: Feb 08, 2022, *status*: N/A, *requires*: N/A @@ -6794,9 +6941,9 @@ This list contains 995 plugins. Pytest plugin for the splinter automation library :pypi:`pytest-split` - *last release*: Jan 10, 2022, + *last release*: Mar 13, 2022, *status*: 4 - Beta, - *requires*: pytest (>=5,<7) + *requires*: pytest (>=5,<8) Pytest plugin which splits the test suite to equally sized sub suites based on test execution time. @@ -6822,14 +6969,14 @@ This list contains 995 plugins. :pypi:`pytest-splunk-addon` - *last release*: Jan 25, 2022, + *last release*: Mar 16, 2022, *status*: N/A, *requires*: pytest (>5.4.0,<6.3) A Dynamic test tool for Splunk Apps and Add-ons :pypi:`pytest-splunk-addon-ui-smartx` - *last release*: Dec 06, 2021, + *last release*: Mar 16, 2022, *status*: N/A, *requires*: N/A @@ -6863,6 +7010,13 @@ This list contains 995 plugins. Yet another SQL-testing framework for BigQuery provided by pytest plugin + :pypi:`pytest-squadcast` + *last release*: Feb 22, 2022, + *status*: 5 - Production/Stable, + *requires*: pytest + + Pytest report plugin for Squadcast + :pypi:`pytest-srcpaths` *last release*: Oct 15, 2021, *status*: N/A, @@ -6962,7 +7116,7 @@ This list contains 995 plugins. A pytest plugin to organize long run tests (named studies) without interfering the regular tests :pypi:`pytest-subprocess` - *last release*: Jan 23, 2022, + *last release*: Feb 09, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=4.0.0) @@ -6976,9 +7130,9 @@ This list contains 995 plugins. A hack to explicitly set up and tear down fixtures. :pypi:`pytest-subtests` - *last release*: Jan 15, 2022, + *last release*: Feb 13, 2022, *status*: 4 - Beta, - *requires*: pytest (>=6.0) + *requires*: pytest (>=7.0) unittest subTest() support and subtests fixture @@ -7025,7 +7179,7 @@ This list contains 995 plugins. pytest-symbols is a pytest plugin that adds support for passing test environment symbols into pytest tests. :pypi:`pytest-system-statistics` - *last release*: Jan 26, 2022, + *last release*: Feb 16, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=6.0.0) @@ -7130,7 +7284,7 @@ This list contains 995 plugins. Test configuration plugin for pytest. :pypi:`pytest-testdirectory` - *last release*: Nov 06, 2018, + *last release*: Feb 21, 2022, *status*: 5 - Production/Stable, *requires*: pytest @@ -7151,7 +7305,7 @@ This list contains 995 plugins. A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. :pypi:`pytest-testinfra` - *last release*: Dec 07, 2021, + *last release*: Feb 10, 2022, *status*: 5 - Production/Stable, *requires*: pytest (!=3.0.2) @@ -7165,7 +7319,7 @@ This list contains 995 plugins. pytest reporting plugin for testlink :pypi:`pytest-testmon` - *last release*: Feb 05, 2022, + *last release*: Mar 11, 2022, *status*: 4 - Beta, *requires*: N/A @@ -7200,7 +7354,7 @@ This list contains 995 plugins. A small example package :pypi:`pytest-testrail-api` - *last release*: Dec 17, 2021, + *last release*: Mar 11, 2022, *status*: N/A, *requires*: pytest (>=5.5) @@ -7388,6 +7542,13 @@ This list contains 995 plugins. Cloud Jira Test Management (TM4J) PyTest reporter plugin + :pypi:`pytest-tmnet` + *last release*: Mar 01, 2022, + *status*: N/A, + *requires*: N/A + + A small example package + :pypi:`pytest-tmreport` *last release*: Nov 17, 2021, *status*: N/A, @@ -7514,6 +7675,13 @@ This list contains 995 plugins. A simple plugin to use with tspwplib + :pypi:`pytest-tst` + *last release*: Mar 13, 2022, + *status*: N/A, + *requires*: pytest (>=5.0.0) + + Customize pytest options, output and exit code to make it compatible with tst + :pypi:`pytest-tstcls` *last release*: Mar 23, 2020, *status*: 5 - Production/Stable, @@ -7536,7 +7704,7 @@ This list contains 995 plugins. Run type checkers on specified test files :pypi:`pytest-typhoon-xray` - *last release*: Nov 03, 2021, + *last release*: Mar 07, 2022, *status*: 4 - Beta, *requires*: N/A @@ -7963,7 +8131,7 @@ This list contains 995 plugins. OWASP ZAP plugin for py.test. :pypi:`pytest-zebrunner` - *last release*: Feb 02, 2022, + *last release*: Mar 10, 2022, *status*: 5 - Production/Stable, *requires*: pytest (>=4.5.0) @@ -7977,7 +8145,7 @@ This list contains 995 plugins. Extend py.test for RPC OpenStack testing. :pypi:`pytest-zulip` - *last release*: Jan 31, 2022, + *last release*: Mar 04, 2022, *status*: 5 - Production/Stable, *requires*: pytest diff --git a/doc/en/talks.rst b/doc/en/talks.rst index 6843c82ba..160345614 100644 --- a/doc/en/talks.rst +++ b/doc/en/talks.rst @@ -11,9 +11,14 @@ Books - `Python Testing with pytest, by Brian Okken (2017) `_. +- `Python Testing with pytest, Second Edition, by Brian Okken (2022) + `_. + Talks and blog postings --------------------------------------------- +- `pytest: Simple, rapid and fun testing with Python, `_ (@ 4:22:32), Florian Bruhin, WeAreDevelopers World Congress 2021 + - Webinar: `pytest: Test Driven Development für Python (German) `_, Florian Bruhin, via mylearning.ch, 2020 - Webinar: `Simplify Your Tests with Fixtures `_, Oliver Bestwalter, via JetBrains, 2020 diff --git a/extra/setup-py.test/setup.py b/extra/setup-py.test/setup.py index d0560ce1f..97883852e 100644 --- a/extra/setup-py.test/setup.py +++ b/extra/setup-py.test/setup.py @@ -1,4 +1,5 @@ import sys + from distutils.core import setup if __name__ == "__main__": diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 5b758a884..304a5cbd7 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -672,10 +672,11 @@ class ExceptionInfo(Generic[E]): If it matches `True` is returned, otherwise an `AssertionError` is raised. """ __tracebackhide__ = True - msg = "Regex pattern {!r} does not match {!r}." - if regexp == str(self.value): - msg += " Did you mean to `re.escape()` the regex?" - assert re.search(regexp, str(self.value)), msg.format(regexp, str(self.value)) + value = str(self.value) + msg = f"Regex pattern did not match.\n Regex: {regexp!r}\n Input: {value!r}" + if regexp == value: + msg += "\n Did you mean to `re.escape()` the regex?" + assert re.search(regexp, value), msg # Return True to allow for "assert excinfo.match()". return True diff --git a/src/_pytest/_io/saferepr.py b/src/_pytest/_io/saferepr.py index e7ff5cab2..a27e8c2a6 100644 --- a/src/_pytest/_io/saferepr.py +++ b/src/_pytest/_io/saferepr.py @@ -107,6 +107,23 @@ def saferepr(obj: object, maxsize: Optional[int] = DEFAULT_REPR_MAX_SIZE) -> str return SafeRepr(maxsize).repr(obj) +def saferepr_unlimited(obj: object) -> str: + """Return an unlimited-size safe repr-string for the given object. + + As with saferepr, failing __repr__ functions of user instances + will be represented with a short exception info. + + This function is a wrapper around simple repr. + + Note: a cleaner solution would be to alter ``saferepr``this way + when maxsize=None, but that might affect some other code. + """ + try: + return repr(obj) + except Exception as exc: + return _format_repr_exception(exc, obj) + + class AlwaysDispatchingPrettyPrinter(pprint.PrettyPrinter): """PrettyPrinter that always dispatches (regardless of width).""" diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index f0922870a..81096764e 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -273,13 +273,15 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) with open(pathname, "rb") as f: return f.read() - if sys.version_info >= (3, 9): + if sys.version_info >= (3, 10): def get_resource_reader(self, name: str) -> importlib.abc.TraversableResources: # type: ignore - from types import SimpleNamespace - from importlib.readers import FileReader + if sys.version_info < (3, 11): + from importlib.readers import FileReader + else: + from importlib.resources.readers import FileReader - return FileReader(SimpleNamespace(path=self._rewritten_names[name])) + return FileReader(types.SimpleNamespace(path=self._rewritten_names[name])) def _write_pyc_fp( diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 14512a7c5..75026730d 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -14,8 +14,8 @@ from typing import Sequence import _pytest._code from _pytest import outcomes from _pytest._io.saferepr import _pformat_dispatch -from _pytest._io.saferepr import safeformat from _pytest._io.saferepr import saferepr +from _pytest._io.saferepr import saferepr_unlimited from _pytest.config import Config # The _reprcompare attribute on the util module is used by the new assertion @@ -160,8 +160,8 @@ def assertrepr_compare(config, op: str, left: Any, right: Any) -> Optional[List[ """Return specialised explanations for some operators/operands.""" verbose = config.getoption("verbose") if verbose > 1: - left_repr = safeformat(left) - right_repr = safeformat(right) + left_repr = saferepr_unlimited(left) + right_repr = saferepr_unlimited(right) else: # XXX: "15 chars indentation" is wrong # ("E AssertionError: assert "); should use term width. @@ -223,8 +223,6 @@ def _compare_eq_any(left: Any, right: Any, verbose: int = 0) -> List[str]: explanation = _compare_eq_set(left, right, verbose) elif isdict(left) and isdict(right): explanation = _compare_eq_dict(left, right, verbose) - elif verbose > 0: - explanation = _compare_eq_verbose(left, right) if isiterable(left) and isiterable(right): expl = _compare_eq_iterable(left, right, verbose) @@ -281,18 +279,6 @@ def _diff_text(left: str, right: str, verbose: int = 0) -> List[str]: return explanation -def _compare_eq_verbose(left: Any, right: Any) -> List[str]: - keepends = True - left_lines = repr(left).splitlines(keepends) - right_lines = repr(right).splitlines(keepends) - - explanation: List[str] = [] - explanation += ["+" + line for line in left_lines] - explanation += ["-" + line for line in right_lines] - - return explanation - - def _surrounding_parens_on_own_lines(lines: List[str]) -> None: """Move opening/closing parenthesis/bracket to own lines.""" opening = lines[0][:1] @@ -308,8 +294,8 @@ def _surrounding_parens_on_own_lines(lines: List[str]) -> None: def _compare_eq_iterable( left: Iterable[Any], right: Iterable[Any], verbose: int = 0 ) -> List[str]: - if not verbose and not running_on_ci(): - return ["Use -v to get the full diff"] + if verbose <= 0 and not running_on_ci(): + return ["Use -v to get more diff"] # dynamic import to speedup pytest import difflib diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 59c88885d..05abaa8ed 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -254,7 +254,7 @@ default_plugins = essential_plugins + ( "warnings", "logging", "reports", - "pythonpath", + "python_path", *(["unraisableexception", "threadexception"] if sys.version_info >= (3, 8) else []), "faulthandler", ) @@ -309,7 +309,9 @@ def _prepareconfig( elif isinstance(args, os.PathLike): args = [os.fspath(args)] elif not isinstance(args, list): - msg = "`args` parameter expected to be a list of strings, got: {!r} (type: {})" + msg = ( # type:ignore[unreachable] + "`args` parameter expected to be a list of strings, got: {!r} (type: {})" + ) raise TypeError(msg.format(args, type(args))) config = get_config(args, plugins) @@ -538,11 +540,7 @@ class PytestPluginManager(PluginManager): """ if self._confcutdir is None: return True - try: - path.relative_to(self._confcutdir) - except ValueError: - return False - return True + return path not in self._confcutdir.parents def _try_load_conftest( self, anchor: Path, importmode: Union[str, ImportMode], rootpath: Path diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 89ade5f23..c082e652d 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -70,7 +70,7 @@ def load_config_dict_from_file( try: config = tomli.loads(toml_text) except tomli.TOMLDecodeError as exc: - raise UsageError(str(exc)) from exc + raise UsageError(f"{filepath}: {exc}") from exc result = config.get("tool", {}).get("pytest", {}).get("ini_options", None) if result is not None: diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 4534fbcab..f2d79760a 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -47,11 +47,6 @@ STRICT_OPTION = PytestRemovedIn8Warning( # This deprecation is never really meant to be removed. PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.") -UNITTEST_SKIP_DURING_COLLECTION = PytestRemovedIn8Warning( - "Raising unittest.SkipTest to skip tests during collection is deprecated. " - "Use pytest.skip() instead." -) - ARGUMENT_PERCENT_DEFAULT = PytestRemovedIn8Warning( 'pytest now uses argparse. "%default" should be changed to "%(default)s"', ) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index be03fb2a8..ee3e93f19 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -597,8 +597,17 @@ class FixtureRequest: funcitem = self._pyfuncitem scope = fixturedef._scope try: - param = funcitem.callspec.getparam(argname) - except (AttributeError, ValueError): + callspec = funcitem.callspec + except AttributeError: + callspec = None + if callspec is not None and argname in callspec.params: + param = callspec.params[argname] + param_index = callspec.indices[argname] + # If a parametrize invocation set a scope it will override + # the static scope defined with the fixture function. + with suppress(KeyError): + scope = callspec._arg2scope[argname] + else: param = NOTSET param_index = 0 has_params = fixturedef.params is not None @@ -638,12 +647,6 @@ class FixtureRequest: ) ) fail(msg, pytrace=False) - else: - param_index = funcitem.callspec.indices[argname] - # If a parametrize invocation set a scope it will override - # the static scope defined with the fixture function. - with suppress(KeyError): - scope = funcitem.callspec._arg2scope[argname] subrequest = SubRequest( self, scope, param, param_index, fixturedef, _ispytest=True @@ -927,7 +930,7 @@ def _eval_scope_callable( @final class FixtureDef(Generic[FixtureValue]): - """A container for a factory definition.""" + """A container for a fixture definition.""" def __init__( self, @@ -939,33 +942,56 @@ class FixtureDef(Generic[FixtureValue]): params: Optional[Sequence[object]], unittest: bool = False, ids: Optional[ - Union[ - Tuple[Union[None, str, float, int, bool], ...], - Callable[[Any], Optional[object]], - ] + Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]] ] = None, ) -> None: self._fixturemanager = fixturemanager + # The "base" node ID for the fixture. + # + # This is a node ID prefix. A fixture is only available to a node (e.g. + # a `Function` item) if the fixture's baseid is a parent of the node's + # nodeid (see the `iterparentnodeids` function for what constitutes a + # "parent" and a "prefix" in this context). + # + # For a fixture found in a Collector's object (e.g. a `Module`s module, + # a `Class`'s class), the baseid is the Collector's nodeid. + # + # For a fixture found in a conftest plugin, the baseid is the conftest's + # directory path relative to the rootdir. + # + # For other plugins, the baseid is the empty string (always matches). self.baseid = baseid or "" + # Whether the fixture was found from a node or a conftest in the + # collection tree. Will be false for fixtures defined in non-conftest + # plugins. self.has_location = baseid is not None + # The fixture factory function. self.func = func + # The name by which the fixture may be requested. self.argname = argname if scope is None: scope = Scope.Function elif callable(scope): scope = _eval_scope_callable(scope, argname, fixturemanager.config) - if isinstance(scope, str): scope = Scope.from_user( scope, descr=f"Fixture '{func.__name__}'", where=baseid ) self._scope = scope + # If the fixture is directly parametrized, the parameter values. self.params: Optional[Sequence[object]] = params - self.argnames: Tuple[str, ...] = getfuncargnames( - func, name=argname, is_method=unittest - ) - self.unittest = unittest + # If the fixture is directly parametrized, a tuple of explicit IDs to + # assign to the parameter values, or a callable to generate an ID given + # a parameter value. self.ids = ids + # The names requested by the fixtures. + self.argnames = getfuncargnames(func, name=argname, is_method=unittest) + # Whether the fixture was collected from a unittest TestCase class. + # Note that it really only makes sense to define autouse fixtures in + # unittest TestCases. + self.unittest = unittest + # If the fixture was executed, the current value of the fixture. + # Can change if the fixture is executed with different parameters. self.cached_result: Optional[_FixtureCachedResult[FixtureValue]] = None self._finalizers: List[Callable[[], object]] = [] @@ -1093,18 +1119,8 @@ def pytest_fixture_setup( def _ensure_immutable_ids( - ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] - ], -) -> Optional[ - Union[ - Tuple[Union[None, str, float, int, bool], ...], - Callable[[Any], Optional[object]], - ] -]: + ids: Optional[Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]]] +) -> Optional[Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]]]: if ids is None: return None if callable(ids): @@ -1148,9 +1164,8 @@ class FixtureFunctionMarker: scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" params: Optional[Tuple[object, ...]] = attr.ib(converter=_params_converter) autouse: bool = False - ids: Union[ - Tuple[Union[None, str, float, int, bool], ...], - Callable[[Any], Optional[object]], + ids: Optional[ + Union[Tuple[Optional[object], ...], Callable[[Any], Optional[object]]] ] = attr.ib( default=None, converter=_ensure_immutable_ids, @@ -1191,10 +1206,7 @@ def fixture( params: Optional[Iterable[object]] = ..., autouse: bool = ..., ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] ] = ..., name: Optional[str] = ..., ) -> FixtureFunction: @@ -1209,10 +1221,7 @@ def fixture( params: Optional[Iterable[object]] = ..., autouse: bool = ..., ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] ] = ..., name: Optional[str] = None, ) -> FixtureFunctionMarker: @@ -1226,10 +1235,7 @@ def fixture( params: Optional[Iterable[object]] = None, autouse: bool = False, ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + Union[Sequence[Optional[object]], Callable[[Any], Optional[object]]] ] = None, name: Optional[str] = None, ) -> Union[FixtureFunctionMarker, FixtureFunction]: @@ -1271,7 +1277,7 @@ def fixture( the fixture. :param ids: - List of string ids each corresponding to the params so that they are + Sequence of ids each corresponding to the params so that they are part of the test id. If no ids are provided they will be generated automatically from the params. diff --git a/src/_pytest/main.py b/src/_pytest/main.py index afe613fd0..8f590754a 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -870,7 +870,10 @@ def resolve_collection_argument( If the path doesn't exist, raise UsageError. If the path is a directory and selection parts are present, raise UsageError. """ - strpath, *parts = str(arg).split("::") + base, squacket, rest = str(arg).partition("[") + strpath, *parts = base.split("::") + if parts: + parts[-1] = f"{parts[-1]}{squacket}{rest}" if as_pypath: strpath = search_pypath(strpath) fspath = invocation_path / strpath diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index ec41b3f99..b8cbf0d18 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -397,7 +397,7 @@ if TYPE_CHECKING: from _pytest.scope import _ScopeName class _SkipMarkDecorator(MarkDecorator): - @overload # type: ignore[override,misc] + @overload # type: ignore[override,misc,no-overload-impl] def __call__(self, arg: Markable) -> Markable: ... @@ -415,7 +415,7 @@ if TYPE_CHECKING: ... class _XfailMarkDecorator(MarkDecorator): - @overload # type: ignore[override,misc] + @overload # type: ignore[override,misc,no-overload-impl] def __call__(self, arg: Markable) -> Markable: ... diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 6e8454ad7..e49c1b003 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -656,20 +656,6 @@ class Item(Node): nextitem = None - def __init_subclass__(cls) -> None: - problems = ", ".join( - base.__name__ for base in cls.__bases__ if issubclass(base, Collector) - ) - if problems: - warnings.warn( - f"{cls.__name__} is an Item subclass and should not be a collector, " - f"however its bases {problems} are collectors.\n" - "Please split the Collectors and the Item into separate node types.\n" - "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n" - "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/", - PytestWarning, - ) - def __init__( self, name, @@ -697,6 +683,37 @@ class Item(Node): #: for this test. self.user_properties: List[Tuple[str, object]] = [] + self._check_item_and_collector_diamond_inheritance() + + def _check_item_and_collector_diamond_inheritance(self) -> None: + """ + Check if the current type inherits from both File and Collector + at the same time, emitting a warning accordingly (#8447). + """ + cls = type(self) + + # We inject an attribute in the type to avoid issuing this warning + # for the same class more than once, which is not helpful. + # It is a hack, but was deemed acceptable in order to avoid + # flooding the user in the common case. + attr_name = "_pytest_diamond_inheritance_warning_shown" + if getattr(cls, attr_name, False): + return + setattr(cls, attr_name, True) + + problems = ", ".join( + base.__name__ for base in cls.__bases__ if issubclass(base, Collector) + ) + if problems: + warnings.warn( + f"{cls.__name__} is an Item subclass and should not be a collector, " + f"however its bases {problems} are collectors.\n" + "Please split the Collectors and the Item into separate node types.\n" + "Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n" + "example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/", + PytestWarning, + ) + def runtest(self) -> None: """Run the test case for this item. diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index def5fa94b..c5a411b59 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -603,11 +603,20 @@ def insert_missing_modules(modules: Dict[str, ModuleType], module_name: str) -> module_parts = module_name.split(".") while module_name: if module_name not in modules: - module = ModuleType( - module_name, - doc="Empty module created by pytest's importmode=importlib.", - ) - modules[module_name] = module + try: + # If sys.meta_path is empty, calling import_module will issue + # a warning and raise ModuleNotFoundError. To avoid the + # warning, we check sys.meta_path explicitly and raise the error + # ourselves to fall back to creating a dummy module. + if not sys.meta_path: + raise ModuleNotFoundError + importlib.import_module(module_name) + except ModuleNotFoundError: + module = ModuleType( + module_name, + doc="Empty module created by pytest's importmode=importlib.", + ) + modules[module_name] = module module_parts.pop(-1) module_name = ".".join(module_parts) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 933d7d357..359e2aebd 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -477,7 +477,9 @@ def LineMatcher_fixture(request: FixtureRequest) -> Type["LineMatcher"]: @fixture -def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pytester": +def pytester( + request: FixtureRequest, tmp_path_factory: TempPathFactory, monkeypatch: MonkeyPatch +) -> "Pytester": """ Facilities to write tests/configuration files, execute pytest in isolation, and match against expected output, perfect for black-box testing of pytest plugins. @@ -488,7 +490,7 @@ def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pyt It is particularly useful for testing plugins. It is similar to the :fixture:`tmp_path` fixture but provides methods which aid in testing pytest itself. """ - return Pytester(request, tmp_path_factory, _ispytest=True) + return Pytester(request, tmp_path_factory, monkeypatch, _ispytest=True) @fixture @@ -683,6 +685,7 @@ class Pytester: self, request: FixtureRequest, tmp_path_factory: TempPathFactory, + monkeypatch: MonkeyPatch, *, _ispytest: bool = False, ) -> None: @@ -706,7 +709,7 @@ class Pytester: self._method = self._request.config.getoption("--runpytest") self._test_tmproot = tmp_path_factory.mktemp(f"tmp-{name}", numbered=True) - self._monkeypatch = mp = MonkeyPatch() + self._monkeypatch = mp = monkeypatch mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self._test_tmproot)) # Ensure no unexpected caching via tox. mp.delenv("TOX_ENV_DIR", raising=False) @@ -738,7 +741,6 @@ class Pytester: self._sys_modules_snapshot.restore() self._sys_path_snapshot.restore() self._cwd_snapshot.restore() - self._monkeypatch.undo() def __take_sys_modules_snapshot(self) -> SysModulesSnapshot: # Some zope modules used by twisted-related tests keep internal state @@ -830,7 +832,7 @@ class Pytester: return self._makefile(ext, args, kwargs) def makeconftest(self, source: str) -> Path: - """Write a contest.py file with 'source' as contents.""" + """Write a conftest.py file with 'source' as contents.""" return self.makepyfile(conftest=source) def makeini(self, source: str) -> Path: diff --git a/src/_pytest/python.py b/src/_pytest/python.py index f5b332e68..cd951939e 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -905,8 +905,6 @@ class InstanceDummy: only to ignore it; this dummy class keeps them working. This will be removed in pytest 8.""" - pass - def __getattr__(name: str) -> object: if name == "Instance": @@ -942,7 +940,7 @@ class IdMaker: # ParameterSet. idfn: Optional[Callable[[Any], Optional[object]]] # Optionally, explicit IDs for ParameterSets by index. - ids: Optional[Sequence[Union[None, str]]] + ids: Optional[Sequence[Optional[object]]] # Optionally, the pytest config. # Used for controlling ASCII escaping, and for calling the # :hook:`pytest_make_parametrize_id` hook. @@ -950,6 +948,9 @@ class IdMaker: # Optionally, the ID of the node being parametrized. # Used only for clearer error messages. nodeid: Optional[str] + # Optionally, the ID of the function being parametrized. + # Used only for clearer error messages. + func_name: Optional[str] def make_unique_parameterset_ids(self) -> List[str]: """Make a unique identifier for each ParameterSet, that may be used to @@ -984,9 +985,7 @@ class IdMaker: yield parameterset.id elif self.ids and idx < len(self.ids) and self.ids[idx] is not None: # ID provided in the IDs list - parametrize(..., ids=[...]). - id = self.ids[idx] - assert id is not None - yield _ascii_escaped_by_config(id, self.config) + yield self._idval_from_value_required(self.ids[idx], idx) else: # ID not provided - generate it. yield "-".join( @@ -1055,6 +1054,25 @@ class IdMaker: return name return None + def _idval_from_value_required(self, val: object, idx: int) -> str: + """Like _idval_from_value(), but fails if the type is not supported.""" + id = self._idval_from_value(val) + if id is not None: + return id + + # Fail. + if self.func_name is not None: + prefix = f"In {self.func_name}: " + elif self.nodeid is not None: + prefix = f"In {self.nodeid}: " + else: + prefix = "" + msg = ( + f"{prefix}ids contains unsupported value {saferepr(val)} (type: {type(val)!r}) at index {idx}. " + "Supported types are: str, bytes, int, float, complex, bool, enum, regex or anything with a __name__." + ) + fail(msg, pytrace=False) + @staticmethod def _idval_from_argname(argname: str, idx: int) -> str: """Make an ID for a parameter in a ParameterSet from the argument name @@ -1184,10 +1202,7 @@ class Metafunc: argvalues: Iterable[Union[ParameterSet, Sequence[object], object]], indirect: Union[bool, Sequence[str]] = False, ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + Union[Iterable[Optional[object]], Callable[[Any], Optional[object]]] ] = None, scope: "Optional[_ScopeName]" = None, *, @@ -1318,10 +1333,7 @@ class Metafunc: self, argnames: Sequence[str], ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + Union[Iterable[Optional[object]], Callable[[Any], Optional[object]]] ], parametersets: Sequence[ParameterSet], nodeid: str, @@ -1351,16 +1363,22 @@ class Metafunc: idfn = None ids_ = self._validate_ids(ids, parametersets, self.function.__name__) id_maker = IdMaker( - argnames, parametersets, idfn, ids_, self.config, nodeid=nodeid + argnames, + parametersets, + idfn, + ids_, + self.config, + nodeid=nodeid, + func_name=self.function.__name__, ) return id_maker.make_unique_parameterset_ids() def _validate_ids( self, - ids: Iterable[Union[None, str, float, int, bool]], + ids: Iterable[Optional[object]], parametersets: Sequence[ParameterSet], func_name: str, - ) -> List[Union[None, str]]: + ) -> List[Optional[object]]: try: num_ids = len(ids) # type: ignore[arg-type] except TypeError: @@ -1375,22 +1393,7 @@ class Metafunc: msg = "In {}: {} parameter sets specified, with different number of ids: {}" fail(msg.format(func_name, len(parametersets), num_ids), pytrace=False) - new_ids = [] - for idx, id_value in enumerate(itertools.islice(ids, num_ids)): - if id_value is None or isinstance(id_value, str): - new_ids.append(id_value) - elif isinstance(id_value, (float, int, bool)): - new_ids.append(str(id_value)) - else: - msg = ( # type: ignore[unreachable] - "In {}: ids must be list of string/float/int/bool, " - "found: {} (type: {!r}) at index {}" - ) - fail( - msg.format(func_name, saferepr(id_value), type(id_value), idx), - pytrace=False, - ) - return new_ids + return list(itertools.islice(ids, num_ids)) def _resolve_arg_value_types( self, diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index cb72fde1e..5fa219619 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -1,5 +1,6 @@ import math import pprint +from collections.abc import Collection from collections.abc import Sized from decimal import Decimal from numbers import Complex @@ -8,7 +9,6 @@ from typing import Any from typing import Callable from typing import cast from typing import Generic -from typing import Iterable from typing import List from typing import Mapping from typing import Optional @@ -131,7 +131,6 @@ class ApproxBase: # a numeric type. For this reason, the default is to do nothing. The # classes that deal with sequences should reimplement this method to # raise if there are any non-numeric elements in the sequence. - pass def _recursive_list_map(f, x): @@ -307,12 +306,12 @@ class ApproxMapping(ApproxBase): raise TypeError(msg.format(key, value, pprint.pformat(self.expected))) -class ApproxSequencelike(ApproxBase): +class ApproxSequenceLike(ApproxBase): """Perform approximate comparisons where the expected value is a sequence of numbers.""" def __repr__(self) -> str: seq_type = type(self.expected) - if seq_type not in (tuple, list, set): + if seq_type not in (tuple, list): seq_type = list return "approx({!r})".format( seq_type(self._approx_scalar(x) for x in self.expected) @@ -320,7 +319,6 @@ class ApproxSequencelike(ApproxBase): def _repr_compare(self, other_side: Sequence[float]) -> List[str]: import math - import numpy as np if len(self.expected) != len(other_side): return [ @@ -341,7 +339,7 @@ class ApproxSequencelike(ApproxBase): abs_diff = abs(approx_value.expected - other_value) max_abs_diff = max(max_abs_diff, abs_diff) if other_value == 0.0: - max_rel_diff = np.inf + max_rel_diff = math.inf else: max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value)) different_ids.append(i) @@ -516,7 +514,7 @@ class ApproxDecimal(ApproxScalar): def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: - """Assert that two numbers (or two sets of numbers) are equal to each other + """Assert that two numbers (or two ordered sequences of numbers) are equal to each other within some tolerance. Due to the :std:doc:`tutorial/floatingpoint`, numbers that we @@ -548,16 +546,11 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: >>> 0.1 + 0.2 == approx(0.3) True - The same syntax also works for sequences of numbers:: + The same syntax also works for ordered sequences of numbers:: >>> (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6)) True - Dictionary *values*:: - - >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6}) - True - ``numpy`` arrays:: >>> import numpy as np # doctest: +SKIP @@ -570,6 +563,20 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: >>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) # doctest: +SKIP True + Only ordered sequences are supported, because ``approx`` needs + to infer the relative position of the sequences without ambiguity. This means + ``sets`` and other unordered sequences are not supported. + + Finally, dictionary *values* can also be compared:: + + >>> {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6}) + True + + The comparison will be true if both mappings have the same keys and their + respective values match the expected tolerances. + + **Tolerances** + By default, ``approx`` considers numbers within a relative tolerance of ``1e-6`` (i.e. one part in a million) of its expected value to be equal. This treatment would lead to surprising results if the expected value was @@ -709,12 +716,19 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase: expected = _as_numpy_array(expected) cls = ApproxNumpy elif ( - isinstance(expected, Iterable) + hasattr(expected, "__getitem__") and isinstance(expected, Sized) # Type ignored because the error is wrong -- not unreachable. and not isinstance(expected, STRING_TYPES) # type: ignore[unreachable] ): - cls = ApproxSequencelike + cls = ApproxSequenceLike + elif ( + isinstance(expected, Collection) + # Type ignored because the error is wrong -- not unreachable. + and not isinstance(expected, STRING_TYPES) # type: ignore[unreachable] + ): + msg = f"pytest.approx() only supports ordered sequences, but got: {repr(expected)}" + raise TypeError(msg) else: cls = ApproxScalar diff --git a/src/_pytest/pythonpath.py b/src/_pytest/python_path.py similarity index 100% rename from src/_pytest/pythonpath.py rename to src/_pytest/python_path.py diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 175b571a8..49e1de282 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -1,6 +1,7 @@ """Record warnings during test function execution.""" import re import warnings +from pprint import pformat from types import TracebackType from typing import Any from typing import Callable @@ -110,7 +111,7 @@ def warns( r"""Assert that code raises a particular class of warning. Specifically, the parameter ``expected_warning`` can be a warning class or - sequence of warning classes, and the inside the ``with`` block must issue a warning of that class or + sequence of warning classes, and the code inside the ``with`` block must issue a warning of that class or classes. This helper produces a list of :class:`warnings.WarningMessage` objects, @@ -142,10 +143,11 @@ def warns( __tracebackhide__ = True if not args: if kwargs: - msg = "Unexpected keyword arguments passed to pytest.warns: " - msg += ", ".join(sorted(kwargs)) - msg += "\nUse context-manager form instead?" - raise TypeError(msg) + argnames = ", ".join(sorted(kwargs)) + raise TypeError( + f"Unexpected keyword arguments passed to pytest.warns: {argnames}" + "\nUse context-manager form instead?" + ) return WarningsChecker(expected_warning, match_expr=match, _ispytest=True) else: func = args[0] @@ -191,7 +193,7 @@ class WarningsRecorder(warnings.catch_warnings): if issubclass(w.category, cls): return self._list.pop(i) __tracebackhide__ = True - raise AssertionError("%r not found in warning list" % cls) + raise AssertionError(f"{cls!r} not found in warning list") def clear(self) -> None: """Clear the list of recorded warnings.""" @@ -202,7 +204,7 @@ class WarningsRecorder(warnings.catch_warnings): def __enter__(self) -> "WarningsRecorder": # type: ignore if self._entered: __tracebackhide__ = True - raise RuntimeError("Cannot enter %r twice" % self) + raise RuntimeError(f"Cannot enter {self!r} twice") _list = super().__enter__() # record=True means it's None. assert _list is not None @@ -218,7 +220,7 @@ class WarningsRecorder(warnings.catch_warnings): ) -> None: if not self._entered: __tracebackhide__ = True - raise RuntimeError("Cannot exit %r without entering first" % self) + raise RuntimeError(f"Cannot exit {self!r} without entering first") super().__exit__(exc_type, exc_val, exc_tb) @@ -268,16 +270,17 @@ class WarningsChecker(WarningsRecorder): __tracebackhide__ = True + def found_str(): + return pformat([record.message for record in self], indent=2) + # only check if we're not currently handling an exception if exc_type is None and exc_val is None and exc_tb is None: if self.expected_warning is not None: if not any(issubclass(r.category, self.expected_warning) for r in self): __tracebackhide__ = True fail( - "DID NOT WARN. No warnings of type {} were emitted. " - "The list of emitted warnings is: {}.".format( - self.expected_warning, [each.message for each in self] - ) + f"DID NOT WARN. No warnings of type {self.expected_warning} were emitted.\n" + f"The list of emitted warnings is: {found_str()}." ) elif self.match_expr is not None: for r in self: @@ -286,11 +289,8 @@ class WarningsChecker(WarningsRecorder): break else: fail( - "DID NOT WARN. No warnings of type {} matching" - " ('{}') were emitted. The list of emitted warnings" - " is: {}.".format( - self.expected_warning, - self.match_expr, - [each.message for each in self], - ) + f"""\ +DID NOT WARN. No warnings of type {self.expected_warning} matching the regex were emitted. + Regex: {self.match_expr} + Emitted warnings: {found_str()}""" ) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index e43dd2dc8..df6eecdb1 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -2,7 +2,6 @@ import bdb import os import sys -import warnings from typing import Callable from typing import cast from typing import Dict @@ -28,7 +27,6 @@ from _pytest._code.code import TerminalRepr from _pytest.compat import final from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest -from _pytest.deprecated import UNITTEST_SKIP_DURING_COLLECTION from _pytest.nodes import Collector from _pytest.nodes import Item from _pytest.nodes import Node @@ -379,11 +377,6 @@ def pytest_make_collect_report(collector: Collector) -> CollectReport: # Type ignored because unittest is loaded dynamically. skip_exceptions.append(unittest.SkipTest) # type: ignore if isinstance(call.excinfo.value, tuple(skip_exceptions)): - if unittest is not None and isinstance( - call.excinfo.value, unittest.SkipTest # type: ignore[attr-defined] - ): - warnings.warn(UNITTEST_SKIP_DURING_COLLECTION, stacklevel=2) - outcome = "skipped" r_ = collector._repr_failure_py(call.excinfo, "line") assert isinstance(r_, ExceptionChainRepr), repr(r_) diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 4bcc968d1..b4848c48a 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -663,7 +663,7 @@ class TerminalReporter: errors = len(self.stats.get("error", [])) skipped = len(self.stats.get("skipped", [])) deselected = len(self.stats.get("deselected", [])) - selected = self._numcollected - errors - skipped - deselected + selected = self._numcollected - deselected line = "collected " if final else "collecting " line += ( str(self._numcollected) + " item" + ("" if self._numcollected == 1 else "s") @@ -674,7 +674,7 @@ class TerminalReporter: line += " / %d deselected" % deselected if skipped: line += " / %d skipped" % skipped - if self._numcollected > selected > 0: + if self._numcollected > selected: line += " / %d selected" % selected if self.isatty: self.rewrite(line, bold=True, erase=True) diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index a05c3b4bc..851e4943b 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -185,6 +185,15 @@ class TestCaseFunction(Function): _excinfo: Optional[List[_pytest._code.ExceptionInfo[BaseException]]] = None _testcase: Optional["unittest.TestCase"] = None + def _getobj(self): + assert self.parent is not None + # Unlike a regular Function in a Class, where `item.obj` returns + # a *bound* method (attached to an instance), TestCaseFunction's + # `obj` returns an *unbound* method (not attached to an instance). + # This inconsistency is probably not desirable, but needs some + # consideration before changing. + return getattr(self.parent.obj, self.originalname) # type: ignore[attr-defined] + def setup(self) -> None: # A bound method to be called during teardown() if set (see 'runtest()'). self._explicit_tearDown: Optional[Callable[[], None]] = None diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index 154283632..4aaa94452 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -81,6 +81,23 @@ def warning_record_to_str(warning_message: warnings.WarningMessage) -> str: warning_message.lineno, warning_message.line, ) + if warning_message.source is not None: + try: + import tracemalloc + except ImportError: + pass + else: + tb = tracemalloc.get_object_traceback(warning_message.source) + if tb is not None: + formatted_tb = "\n".join(tb.format()) + # Use a leading new line to better separate the (large) output + # from the traceback to the previous warning text. + msg += f"\nObject allocated at:\n{formatted_tb}" + else: + # No need for a leading new line. + url = "https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings" + msg += "Enable tracemalloc to get traceback where the object was allocated.\n" + msg += f"See {url} for more info." return msg diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 8b8d4a4a6..71d3cc23a 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1238,8 +1238,6 @@ def test_pdb_can_be_rewritten(pytester: Pytester) -> None: " def check():", "> assert 1 == 2", "E assert 1 == 2", - "E +1", - "E -2", "", "pdb.py:2: AssertionError", "*= 1 failed in *", diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 61aa4406a..af72857f3 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -420,18 +420,20 @@ def test_match_raises_error(pytester: Pytester) -> None: excinfo.match(r'[123]+') """ ) - result = pytester.runpytest() + result = pytester.runpytest("--tb=short") assert result.ret != 0 - exc_msg = "Regex pattern '[[]123[]]+' does not match 'division by zero'." - result.stdout.fnmatch_lines([f"E * AssertionError: {exc_msg}"]) + match = [ + r"E .* AssertionError: Regex pattern did not match.", + r"E .* Regex: '\[123\]\+'", + r"E .* Input: 'division by zero'", + ] + result.stdout.re_match_lines(match) result.stdout.no_fnmatch_line("*__tracebackhide__ = True*") result = pytester.runpytest("--fulltrace") assert result.ret != 0 - result.stdout.fnmatch_lines( - ["*__tracebackhide__ = True*", f"E * AssertionError: {exc_msg}"] - ) + result.stdout.re_match_lines([r".*__tracebackhide__ = True.*", *match]) class TestFormattedExcinfo: diff --git a/testing/code/test_source.py b/testing/code/test_source.py index fd2c9fc97..52417f2f8 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -1,16 +1,13 @@ # flake8: noqa # disable flake check on this file because some constructs are strange # or redundant on purpose and can't be disable on a line-by-line basis -import ast import inspect import linecache import sys import textwrap from pathlib import Path -from types import CodeType from typing import Any from typing import Dict -from typing import Optional import pytest from _pytest._code import Code diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 4104d19db..db649841a 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -86,23 +86,6 @@ def test_private_is_deprecated() -> None: PrivateInit(10, _ispytest=True) -def test_raising_unittest_skiptest_during_collection_is_deprecated( - pytester: Pytester, -) -> None: - pytester.makepyfile( - """ - import unittest - raise unittest.SkipTest() - """ - ) - result = pytester.runpytest() - result.stdout.fnmatch_lines( - [ - "*PytestRemovedIn8Warning: Raising unittest.SkipTest*", - ] - ) - - @pytest.mark.parametrize("hooktype", ["hook", "ihook"]) def test_hookproxy_warnings_for_pathlib(tmp_path, hooktype, request): path = legacy_path(tmp_path) diff --git a/testing/io/test_saferepr.py b/testing/io/test_saferepr.py index 63d3af822..24746bc22 100644 --- a/testing/io/test_saferepr.py +++ b/testing/io/test_saferepr.py @@ -2,6 +2,7 @@ import pytest from _pytest._io.saferepr import _pformat_dispatch from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE from _pytest._io.saferepr import saferepr +from _pytest._io.saferepr import saferepr_unlimited def test_simple_repr(): @@ -179,3 +180,23 @@ def test_broken_getattribute(): assert saferepr(SomeClass()).startswith( "<[RuntimeError() raised in repr()] SomeClass object at 0x" ) + + +def test_saferepr_unlimited(): + dict5 = {f"v{i}": i for i in range(5)} + assert saferepr_unlimited(dict5) == "{'v0': 0, 'v1': 1, 'v2': 2, 'v3': 3, 'v4': 4}" + + dict_long = {f"v{i}": i for i in range(1_000)} + r = saferepr_unlimited(dict_long) + assert "..." not in r + assert "\n" not in r + + +def test_saferepr_unlimited_exc(): + class A: + def __repr__(self): + raise ValueError(42) + + assert saferepr_unlimited(A()).startswith( + "<[ValueError(42) raised in repr()] A object at 0x" + ) diff --git a/testing/plugins_integration/requirements.txt b/testing/plugins_integration/requirements.txt index 8c5d69ff1..357fa539f 100644 --- a/testing/plugins_integration/requirements.txt +++ b/testing/plugins_integration/requirements.txt @@ -1,6 +1,6 @@ anyio[curio,trio]==3.5.0 -django==4.0.1 -pytest-asyncio==0.17.2 +django==4.0.3 +pytest-asyncio==0.18.2 pytest-bdd==5.0.0 pytest-cov==3.0.0 pytest-django==4.5.2 @@ -11,5 +11,5 @@ pytest-rerunfailures==10.2 pytest-sugar==0.9.4 pytest-trio==0.7.0 pytest-twisted==1.13.4 -twisted==21.7.0 +twisted==22.2.0 pytest-xvfb==2.0.0 diff --git a/testing/python/approx.py b/testing/python/approx.py index eb9bcd874..7b4fbad15 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -92,9 +92,7 @@ SOME_INT = r"[0-9]+\s*" class TestApprox: - def test_error_messages(self, assert_approx_raises_regex): - np = pytest.importorskip("numpy") - + def test_error_messages_native_dtypes(self, assert_approx_raises_regex): assert_approx_raises_regex( 2.0, 1.0, @@ -135,6 +133,22 @@ class TestApprox: ], ) + # Specific test for comparison with 0.0 (relative diff will be 'inf') + assert_approx_raises_regex( + [0.0], + [1.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"\s*0\s*\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}", + ], + ) + + def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex): + np = pytest.importorskip("numpy") + a = np.linspace(0, 100, 20) b = np.linspace(0, 100, 20) a[10] += 0.5 @@ -175,18 +189,6 @@ class TestApprox: ) # Specific test for comparison with 0.0 (relative diff will be 'inf') - assert_approx_raises_regex( - [0.0], - [1.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"\s*0\s*\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}", - ], - ) - assert_approx_raises_regex( np.array([0.0]), np.array([1.0]), @@ -858,13 +860,21 @@ class TestApprox: assert approx(expected, rel=5e-7, abs=0) == actual assert approx(expected, rel=5e-8, abs=0) != actual - def test_generic_sized_iterable_object(self): - class MySizedIterable: - def __iter__(self): - return iter([1, 2, 3, 4]) + def test_generic_ordered_sequence(self): + class MySequence: + def __getitem__(self, i): + return [1, 2, 3, 4][i] def __len__(self): return 4 - expected = MySizedIterable() - assert [1, 2, 3, 4] == approx(expected) + expected = MySequence() + assert [1, 2, 3, 4] == approx(expected, abs=1e-4) + + expected_repr = "approx([1 ± 1.0e-06, 2 ± 2.0e-06, 3 ± 3.0e-06, 4 ± 4.0e-06])" + assert repr(approx(expected)) == expected_repr + + def test_allow_ordered_sequences_only(self) -> None: + """pytest.approx() should raise an error on unordered sequences (#9692).""" + with pytest.raises(TypeError, match="only supports ordered sequences"): + assert {1, 2, 3} == approx({1, 2, 3}) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index b6ad4a809..2fed22718 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -106,8 +106,8 @@ class TestMetafunc: with pytest.raises( fail.Exception, match=( - r"In func: ids must be list of string/float/int/bool, found:" - r" Exc\(from_gen\) \(type: \) at index 2" + r"In func: ids contains unsupported value Exc\(from_gen\) \(type: \) at index 2. " + r"Supported types are: .*" ), ): metafunc.parametrize("x", [1, 2, 3], ids=gen()) # type: ignore[arg-type] @@ -285,7 +285,7 @@ class TestMetafunc: deadline=400.0 ) # very close to std deadline and CI boxes are not reliable in CPU power def test_idval_hypothesis(self, value) -> None: - escaped = IdMaker([], [], None, None, None, None)._idval(value, "a", 6) + escaped = IdMaker([], [], None, None, None, None, None)._idval(value, "a", 6) assert isinstance(escaped, str) escaped.encode("ascii") @@ -308,7 +308,8 @@ class TestMetafunc: ] for val, expected in values: assert ( - IdMaker([], [], None, None, None, None)._idval(val, "a", 6) == expected + IdMaker([], [], None, None, None, None, None)._idval(val, "a", 6) + == expected ) def test_unicode_idval_with_config(self) -> None: @@ -337,7 +338,7 @@ class TestMetafunc: ("ação", MockConfig({option: False}), "a\\xe7\\xe3o"), ] for val, config, expected in values: - actual = IdMaker([], [], None, None, config, None)._idval(val, "a", 6) + actual = IdMaker([], [], None, None, config, None, None)._idval(val, "a", 6) assert actual == expected def test_bytes_idval(self) -> None: @@ -351,7 +352,8 @@ class TestMetafunc: ] for val, expected in values: assert ( - IdMaker([], [], None, None, None, None)._idval(val, "a", 6) == expected + IdMaker([], [], None, None, None, None, None)._idval(val, "a", 6) + == expected ) def test_class_or_function_idval(self) -> None: @@ -367,7 +369,8 @@ class TestMetafunc: values = [(TestClass, "TestClass"), (test_function, "test_function")] for val, expected in values: assert ( - IdMaker([], [], None, None, None, None)._idval(val, "a", 6) == expected + IdMaker([], [], None, None, None, None, None)._idval(val, "a", 6) + == expected ) def test_notset_idval(self) -> None: @@ -376,7 +379,9 @@ class TestMetafunc: Regression test for #7686. """ - assert IdMaker([], [], None, None, None, None)._idval(NOTSET, "a", 0) == "a0" + assert ( + IdMaker([], [], None, None, None, None, None)._idval(NOTSET, "a", 0) == "a0" + ) def test_idmaker_autoname(self) -> None: """#250""" @@ -387,6 +392,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["string-1.0", "st-ring-2.0"] @@ -397,17 +403,18 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["a0-1.0", "a1-b1"] # unicode mixing, issue250 result = IdMaker( - ("a", "b"), [pytest.param({}, b"\xc3\xb4")], None, None, None, None + ("a", "b"), [pytest.param({}, b"\xc3\xb4")], None, None, None, None, None ).make_unique_parameterset_ids() assert result == ["a0-\\xc3\\xb4"] def test_idmaker_with_bytes_regex(self) -> None: result = IdMaker( - ("a"), [pytest.param(re.compile(b"foo"), 1.0)], None, None, None, None + ("a"), [pytest.param(re.compile(b"foo"), 1.0)], None, None, None, None, None ).make_unique_parameterset_ids() assert result == ["foo"] @@ -433,6 +440,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == [ "1.0--1.1", @@ -465,6 +473,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["\\x00-1", "\\x05-2", "\\x00-3", "\\x05-4", "\\t-5", "\\t-6"] @@ -479,6 +488,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["hello \\x00", "hello \\x05"] @@ -486,7 +496,7 @@ class TestMetafunc: enum = pytest.importorskip("enum") e = enum.Enum("Foo", "one, two") result = IdMaker( - ("a", "b"), [pytest.param(e.one, e.two)], None, None, None, None + ("a", "b"), [pytest.param(e.one, e.two)], None, None, None, None, None ).make_unique_parameterset_ids() assert result == ["Foo.one-Foo.two"] @@ -509,6 +519,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["10.0-IndexError()", "20-KeyError()", "three-b2"] @@ -529,6 +540,7 @@ class TestMetafunc: None, None, None, + None, ).make_unique_parameterset_ids() assert result == ["a-a0", "a-a1", "a-a2"] @@ -560,7 +572,13 @@ class TestMetafunc: ] for config, expected in values: result = IdMaker( - ("a",), [pytest.param("string")], lambda _: "ação", None, config, None + ("a",), + [pytest.param("string")], + lambda _: "ação", + None, + config, + None, + None, ).make_unique_parameterset_ids() assert result == [expected] @@ -592,7 +610,7 @@ class TestMetafunc: ] for config, expected in values: result = IdMaker( - ("a",), [pytest.param("string")], None, ["ação"], config, None + ("a",), [pytest.param("string")], None, ["ação"], config, None, None ).make_unique_parameterset_ids() assert result == [expected] @@ -657,6 +675,7 @@ class TestMetafunc: ["a", None], None, None, + None, ).make_unique_parameterset_ids() assert result == ["a", "3-4"] @@ -668,6 +687,7 @@ class TestMetafunc: ["a", None], None, None, + None, ).make_unique_parameterset_ids() assert result == ["me", "you"] @@ -679,6 +699,7 @@ class TestMetafunc: ["a", "a", "b", "c", "b"], None, None, + None, ).make_unique_parameterset_ids() assert result == ["a0", "a1", "b0", "c", "b1"] @@ -1318,7 +1339,7 @@ class TestMetafuncFunctional: """ import pytest - @pytest.mark.parametrize("x, expected", [(1, 2), (3, 4), (5, 6)], ids=(None, 2, type)) + @pytest.mark.parametrize("x, expected", [(1, 2), (3, 4), (5, 6)], ids=(None, 2, OSError())) def test_ids_numbers(x,expected): assert x * 2 == expected """ @@ -1326,8 +1347,8 @@ class TestMetafuncFunctional: result = pytester.runpytest() result.stdout.fnmatch_lines( [ - "In test_ids_numbers: ids must be list of string/float/int/bool," - " found: (type: ) at index 2" + "In test_ids_numbers: ids contains unsupported value OSError() (type: ) at index 2. " + "Supported types are: str, bytes, int, float, complex, bool, enum, regex or anything with a __name__." ] ) diff --git a/testing/python/raises.py b/testing/python/raises.py index 2d62e9109..112dec06c 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -191,10 +191,12 @@ class TestRaises: int("asdf") msg = "with base 16" - expr = "Regex pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\".".format( - msg + expr = ( + "Regex pattern did not match.\n" + f" Regex: {msg!r}\n" + " Input: \"invalid literal for int() with base 10: 'asdf'\"" ) - with pytest.raises(AssertionError, match=re.escape(expr)): + with pytest.raises(AssertionError, match="(?m)" + re.escape(expr)): with pytest.raises(ValueError, match=msg): int("asdf", base=10) @@ -217,7 +219,7 @@ class TestRaises: with pytest.raises(AssertionError, match="'foo"): raise AssertionError("'bar") (msg,) = excinfo.value.args - assert msg == 'Regex pattern "\'foo" does not match "\'bar".' + assert msg == '''Regex pattern did not match.\n Regex: "'foo"\n Input: "'bar"''' def test_match_failure_exact_string_message(self): message = "Oh here is a message with (42) numbers in parameters" @@ -226,9 +228,10 @@ class TestRaises: raise AssertionError(message) (msg,) = excinfo.value.args assert msg == ( - "Regex pattern 'Oh here is a message with (42) numbers in " - "parameters' does not match 'Oh here is a message with (42) " - "numbers in parameters'. Did you mean to `re.escape()` the regex?" + "Regex pattern did not match.\n" + " Regex: 'Oh here is a message with (42) numbers in parameters'\n" + " Input: 'Oh here is a message with (42) numbers in parameters'\n" + " Did you mean to `re.escape()` the regex?" ) def test_raises_match_wrong_type(self): diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 317a2beb3..4825ede77 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -83,7 +83,7 @@ class TestImportHookInstallation: "E assert {'failed': 1,... 'skipped': 0} == {'failed': 0,... 'skipped': 0}", "E Omitting 1 identical items, use -vv to show", "E Differing items:", - "E Use -v to get the full diff", + "E Use -v to get more diff", ] ) # XXX: unstable output. @@ -376,7 +376,7 @@ class TestAssert_reprcompare: assert diff == [ "b'spam' == b'eggs'", "At index 0 diff: b's' != b'e'", - "Use -v to get the full diff", + "Use -v to get more diff", ] def test_bytes_diff_verbose(self) -> None: @@ -444,11 +444,19 @@ class TestAssert_reprcompare: """ expl = callequal(left, right, verbose=0) assert expl is not None - assert expl[-1] == "Use -v to get the full diff" + assert expl[-1] == "Use -v to get more diff" verbose_expl = callequal(left, right, verbose=1) assert verbose_expl is not None assert "\n".join(verbose_expl).endswith(textwrap.dedent(expected).strip()) + def test_iterable_quiet(self) -> None: + expl = callequal([1, 2], [10, 2], verbose=-1) + assert expl == [ + "[1, 2] == [10, 2]", + "At index 0 diff: 1 != 10", + "Use -v to get more diff", + ] + def test_iterable_full_diff_ci( self, monkeypatch: MonkeyPatch, pytester: Pytester ) -> None: @@ -466,7 +474,7 @@ class TestAssert_reprcompare: monkeypatch.delenv("CI", raising=False) result = pytester.runpytest() - result.stdout.fnmatch_lines(["E Use -v to get the full diff"]) + result.stdout.fnmatch_lines(["E Use -v to get more diff"]) def test_list_different_lengths(self) -> None: expl = callequal([0, 1], [0, 1, 2]) @@ -699,32 +707,6 @@ class TestAssert_reprcompare: assert expl is not None assert len(expl) > 1 - def test_repr_verbose(self) -> None: - class Nums: - def __init__(self, nums): - self.nums = nums - - def __repr__(self): - return str(self.nums) - - list_x = list(range(5000)) - list_y = list(range(5000)) - list_y[len(list_y) // 2] = 3 - nums_x = Nums(list_x) - nums_y = Nums(list_y) - - assert callequal(nums_x, nums_y) is None - - expl = callequal(nums_x, nums_y, verbose=1) - assert expl is not None - assert "+" + repr(nums_x) in expl - assert "-" + repr(nums_y) in expl - - expl = callequal(nums_x, nums_y, verbose=2) - assert expl is not None - assert "+" + repr(nums_x) in expl - assert "-" + repr(nums_y) in expl - def test_list_bad_repr(self) -> None: class A: def __repr__(self): @@ -851,8 +833,6 @@ class TestAssert_reprcompare_dataclass: "E ", "E Drill down into differing attribute a:", "E a: 10 != 20", - "E +10", - "E -20", "E ", "E Drill down into differing attribute b:", "E b: 'ten' != 'xxx'", @@ -1026,7 +1006,7 @@ class TestAssert_reprcompare_attrsclass: assert lines is None def test_attrs_with_custom_eq(self) -> None: - @attr.define + @attr.define(slots=False) class SimpleDataObject: field_a = attr.ib() @@ -1059,7 +1039,7 @@ class TestAssert_reprcompare_namedtuple: " b: 'b' != 'c'", " - c", " + b", - "Use -v to get the full diff", + "Use -v to get more diff", ] def test_comparing_two_different_namedtuple(self) -> None: @@ -1074,7 +1054,7 @@ class TestAssert_reprcompare_namedtuple: assert lines == [ "NT1(a=1, b='b') == NT2(a=2, b='b')", "At index 0 diff: 1 != 2", - "Use -v to get the full diff", + "Use -v to get more diff", ] @@ -1648,7 +1628,7 @@ def test_raise_unprintable_assertion_error(pytester: Pytester) -> None: ) -def test_raise_assertion_error_raisin_repr(pytester: Pytester) -> None: +def test_raise_assertion_error_raising_repr(pytester: Pytester) -> None: pytester.makepyfile( """ class RaisingRepr(object): @@ -1659,9 +1639,15 @@ def test_raise_assertion_error_raisin_repr(pytester: Pytester) -> None: """ ) result = pytester.runpytest() - result.stdout.fnmatch_lines( - ["E AssertionError: "] - ) + if sys.version_info >= (3, 11): + # python 3.11 has native support for un-str-able exceptions + result.stdout.fnmatch_lines( + ["E AssertionError: "] + ) + else: + result.stdout.fnmatch_lines( + ["E AssertionError: "] + ) def test_issue_1944(pytester: Pytester) -> None: @@ -1709,3 +1695,18 @@ def test_assertion_location_with_coverage(pytester: Pytester) -> None: "*= 1 failed in*", ] ) + + +def test_reprcompare_verbose_long() -> None: + a = {f"v{i}": i for i in range(11)} + b = a.copy() + b["v2"] += 10 + lines = callop("==", a, b, verbose=2) + assert lines is not None + assert lines[0] == ( + "{'v0': 0, 'v1': 1, 'v2': 2, 'v3': 3, 'v4': 4, 'v5': 5, " + "'v6': 6, 'v7': 7, 'v8': 8, 'v9': 9, 'v10': 10}" + " == " + "{'v0': 0, 'v1': 1, 'v2': 12, 'v3': 3, 'v4': 4, 'v5': 5, " + "'v6': 6, 'v7': 7, 'v8': 8, 'v9': 9, 'v10': 10}" + ) diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index ae18b4be3..41458b52b 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -13,10 +13,12 @@ from functools import partial from pathlib import Path from typing import cast from typing import Dict +from typing import Generator from typing import List from typing import Mapping from typing import Optional from typing import Set +from unittest import mock import _pytest._code import pytest @@ -202,16 +204,8 @@ class TestAssertionRewrite: def f4() -> None: assert sys == 42 # type: ignore[comparison-overlap] - verbose = request.config.getoption("verbose") msg = getmsg(f4, {"sys": sys}) - if verbose > 0: - assert msg == ( - "assert == 42\n" - " +\n" - " -42" - ) - else: - assert msg == "assert sys == 42" + assert msg == "assert sys == 42" def f5() -> None: assert cls == 42 # type: ignore[name-defined] # noqa: F821 @@ -222,20 +216,7 @@ class TestAssertionRewrite: msg = getmsg(f5, {"cls": X}) assert msg is not None lines = msg.splitlines() - if verbose > 1: - assert lines == [ - f"assert {X!r} == 42", - f" +{X!r}", - " -42", - ] - elif verbose > 0: - assert lines == [ - "assert .X'> == 42", - f" +{X!r}", - " -42", - ] - else: - assert lines == ["assert cls == 42"] + assert lines == ["assert cls == 42"] def test_assertrepr_compare_same_width(self, request) -> None: """Should use same width/truncation with same initial width.""" @@ -277,14 +258,11 @@ class TestAssertionRewrite: msg = getmsg(f, {"cls": Y}) assert msg is not None lines = msg.splitlines() - if request.config.getoption("verbose") > 0: - assert lines == ["assert 3 == 2", " +3", " -2"] - else: - assert lines == [ - "assert 3 == 2", - " + where 3 = Y.foo", - " + where Y = cls()", - ] + assert lines == [ + "assert 3 == 2", + " + where 3 = Y.foo", + " + where Y = cls()", + ] def test_assert_already_has_message(self) -> None: def f(): @@ -661,10 +639,7 @@ class TestAssertionRewrite: assert len(values) == 11 msg = getmsg(f) - if request.config.getoption("verbose") > 0: - assert msg == "assert 10 == 11\n +10\n -11" - else: - assert msg == "assert 10 == 11\n + where 10 = len([0, 1, 2, 3, 4, 5, ...])" + assert msg == "assert 10 == 11\n + where 10 = len([0, 1, 2, 3, 4, 5, ...])" def test_custom_reprcompare(self, monkeypatch) -> None: def my_reprcompare1(op, left, right) -> str: @@ -730,10 +705,7 @@ class TestAssertionRewrite: msg = getmsg(f) assert msg is not None lines = util._format_lines([msg]) - if request.config.getoption("verbose") > 0: - assert lines == ["assert 0 == 1\n +0\n -1"] - else: - assert lines == ["assert 0 == 1\n + where 1 = \\n{ \\n~ \\n}.a"] + assert lines == ["assert 0 == 1\n + where 1 = \\n{ \\n~ \\n}.a"] def test_custom_repr_non_ascii(self) -> None: def f() -> None: @@ -1057,7 +1029,7 @@ class TestAssertionRewriteHookDetails: e = OSError() e.errno = 10 raise e - yield + yield # type:ignore[unreachable] monkeypatch.setattr( _pytest.assertion.rewrite, "atomic_write", atomic_write_failed @@ -1376,7 +1348,7 @@ class TestEarlyRewriteBailout: @pytest.fixture def hook( self, pytestconfig, monkeypatch, pytester: Pytester - ) -> AssertionRewritingHook: + ) -> Generator[AssertionRewritingHook, None, None]: """Returns a patched AssertionRewritingHook instance so we can configure its initial paths and track if PathFinder.find_spec has been called. """ @@ -1397,11 +1369,11 @@ class TestEarlyRewriteBailout: hook = AssertionRewritingHook(pytestconfig) # use default patterns, otherwise we inherit pytest's testing config - hook.fnpats[:] = ["test_*.py", "*_test.py"] - monkeypatch.setattr(hook, "_find_spec", spy_find_spec) - hook.set_session(StubSession()) # type: ignore[arg-type] - pytester.syspathinsert() - return hook + with mock.patch.object(hook, "fnpats", ["test_*.py", "*_test.py"]): + monkeypatch.setattr(hook, "_find_spec", spy_find_spec) + hook.set_session(StubSession()) # type: ignore[arg-type] + pytester.syspathinsert() + yield hook def test_basic(self, pytester: Pytester, hook: AssertionRewritingHook) -> None: """ @@ -1451,9 +1423,9 @@ class TestEarlyRewriteBailout: } ) pytester.syspathinsert("tests") - hook.fnpats[:] = ["tests/**.py"] - assert hook.find_spec("file") is not None - assert self.find_spec_calls == ["file"] + with mock.patch.object(hook, "fnpats", ["tests/**.py"]): + assert hook.find_spec("file") is not None + assert self.find_spec_calls == ["file"] @pytest.mark.skipif( sys.platform.startswith("win32"), reason="cannot remove cwd on Windows" diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index cc6d547df..2baa3c8f1 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -773,7 +773,7 @@ class TestLastFailed: result = pytester.runpytest("--lf", "--lfnf", "none") result.stdout.fnmatch_lines( [ - "collected 2 items / 2 deselected", + "collected 2 items / 2 deselected / 0 selected", "run-last-failure: no previously failed tests, deselecting all items.", "deselected=2", "* 2 deselected in *", diff --git a/testing/test_collection.py b/testing/test_collection.py index e79ae384d..9099ec57f 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -651,7 +651,7 @@ class Test_getinitialnodes: for parent in col.listchain(): assert parent.config is config - def test_pkgfile(self, pytester: Pytester) -> None: + def test_pkgfile(self, pytester: Pytester, monkeypatch: MonkeyPatch) -> None: """Verify nesting when a module is within a package. The parent chain should match: Module -> Package -> Session. Session's parent should always be None. @@ -660,7 +660,8 @@ class Test_getinitialnodes: subdir = tmp_path.joinpath("subdir") x = ensure_file(subdir / "x.py") ensure_file(subdir / "__init__.py") - with subdir.cwd(): + with monkeypatch.context() as mp: + mp.chdir(subdir) config = pytester.parseconfigure(x) col = pytester.getnode(config, x) assert col is not None @@ -1188,8 +1189,7 @@ def test_collect_with_chdir_during_import(pytester: Pytester) -> None: """ % (str(subdir),) ) - with pytester.path.cwd(): - result = pytester.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed in*"]) assert result.ret == 0 @@ -1200,8 +1200,7 @@ def test_collect_with_chdir_during_import(pytester: Pytester) -> None: testpaths = . """ ) - with pytester.path.cwd(): - result = pytester.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["collected 1 item"]) @@ -1224,7 +1223,8 @@ def test_collect_pyargs_with_testpaths( ) ) monkeypatch.setenv("PYTHONPATH", str(pytester.path), prepend=os.pathsep) - with root.cwd(): + with monkeypatch.context() as mp: + mp.chdir(root) result = pytester.runpytest_subprocess() result.stdout.fnmatch_lines(["*1 passed in*"]) @@ -1507,6 +1507,35 @@ class TestImportModeImportlib: ] ) + def test_using_python_path(self, pytester: Pytester) -> None: + """ + Dummy modules created by insert_missing_modules should not get in + the way of modules that could be imported via python path (#9645). + """ + pytester.makeini( + """ + [pytest] + pythonpath = . + addopts = --import-mode importlib + """ + ) + pytester.makepyfile( + **{ + "tests/__init__.py": "", + "tests/conftest.py": "", + "tests/subpath/__init__.py": "", + "tests/subpath/helper.py": "", + "tests/subpath/test_something.py": """ + import tests.subpath.helper + + def test_something(): + assert True + """, + } + ) + result = pytester.runpytest() + result.stdout.fnmatch_lines("*1 passed in*") + def test_does_not_crash_on_error_from_decorated_function(pytester: Pytester) -> None: """Regression test for an issue around bad exception formatting due to diff --git a/testing/test_compat.py b/testing/test_compat.py index 88f0f33ef..8a80fd625 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -1,4 +1,5 @@ import enum +import sys from functools import partial from functools import wraps from typing import TYPE_CHECKING @@ -91,6 +92,7 @@ def test_get_real_func_partial() -> None: assert get_real_func(partial(foo)) is foo +@pytest.mark.skipif(sys.version_info >= (3, 11), reason="couroutine removed") def test_is_generator_asyncio(pytester: Pytester) -> None: pytester.makepyfile( """ diff --git a/testing/test_config.py b/testing/test_config.py index bf4b2741e..6784809e0 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -163,7 +163,17 @@ class TestParseIni: pytester.path.joinpath("pytest.ini").write_text("addopts = -x") result = pytester.runpytest() assert result.ret != 0 - result.stderr.fnmatch_lines(["ERROR: *pytest.ini:1: no section header defined"]) + result.stderr.fnmatch_lines("ERROR: *pytest.ini:1: no section header defined") + + def test_toml_parse_error(self, pytester: Pytester) -> None: + pytester.makepyprojecttoml( + """ + \\" + """ + ) + result = pytester.runpytest() + assert result.ret != 0 + result.stderr.fnmatch_lines("ERROR: *pyproject.toml: Invalid statement*") @pytest.mark.xfail(reason="probably not needed") def test_confcutdir(self, pytester: Pytester) -> None: @@ -1275,7 +1285,7 @@ def test_load_initial_conftest_last_ordering(_config_for_test): ("_pytest.config", "nonwrapper"), (m.__module__, "nonwrapper"), ("_pytest.legacypath", "nonwrapper"), - ("_pytest.pythonpath", "nonwrapper"), + ("_pytest.python_path", "nonwrapper"), ("_pytest.capture", "wrapper"), ("_pytest.warnings", "wrapper"), ] diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 4cbc2d14c..680482045 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -252,6 +252,34 @@ def test_conftest_confcutdir(pytester: Pytester) -> None: result.stdout.no_fnmatch_line("*warning: could not load initial*") +def test_installed_conftest_is_picked_up(pytester: Pytester, tmp_path: Path) -> None: + """When using `--pyargs` to run tests in an installed packages (located e.g. + in a site-packages in the PYTHONPATH), conftest files in there are picked + up. + + Regression test for #9767. + """ + # pytester dir - the source tree. + # tmp_path - the simulated site-packages dir (not in source tree). + + pytester.syspathinsert(tmp_path) + pytester.makepyprojecttoml("[tool.pytest.ini_options]") + tmp_path.joinpath("foo").mkdir() + tmp_path.joinpath("foo", "__init__.py").touch() + tmp_path.joinpath("foo", "conftest.py").write_text( + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def fix(): return None + """ + ) + ) + tmp_path.joinpath("foo", "test_it.py").write_text("def test_it(fix): pass") + result = pytester.runpytest("--pyargs", "foo") + assert result.ret == 0 + + def test_conftest_symlink(pytester: Pytester) -> None: """`conftest.py` discovery follows normal path resolution and does not resolve symlinks.""" # Structure: diff --git a/testing/test_doctest.py b/testing/test_doctest.py index c2c832720..1b4809240 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -1,4 +1,5 @@ import inspect +import sys import textwrap from pathlib import Path from typing import Callable @@ -200,6 +201,7 @@ class TestDoctests: "Traceback (most recent call last):", ' File "*/doctest.py", line *, in __run', " *", + *((" *^^^^*",) if sys.version_info >= (3, 11) else ()), ' File "", line 1, in ', "ZeroDivisionError: division by zero", "*/test_doctest_unexpected_exception.txt:2: UnexpectedException", @@ -801,8 +803,8 @@ class TestDoctests: """ p = pytester.makepyfile( setup=""" - from setuptools import setup, find_packages if __name__ == '__main__': + from setuptools import setup, find_packages setup(name='sample', version='0.0', description='description', diff --git a/testing/test_error_diffs.py b/testing/test_error_diffs.py index d880be0da..eb7812108 100644 --- a/testing/test_error_diffs.py +++ b/testing/test_error_diffs.py @@ -231,8 +231,6 @@ TESTCASES = [ E ['a'] E Drill down into differing attribute a: E a: 1 != 2 - E +1 - E -2 """, id="Compare data classes", ), diff --git a/testing/test_main.py b/testing/test_main.py index 6a13633f6..2df51bb7b 100644 --- a/testing/test_main.py +++ b/testing/test_main.py @@ -1,6 +1,7 @@ import argparse import os import re +import sys from pathlib import Path from typing import Optional @@ -44,16 +45,32 @@ def test_wrap_session_notify_exception(ret_exc, pytester: Pytester) -> None: assert result.ret == ExitCode.INTERNAL_ERROR assert result.stdout.lines[0] == "INTERNALERROR> Traceback (most recent call last):" + end_lines = ( + result.stdout.lines[-4:] + if sys.version_info >= (3, 11) + else result.stdout.lines[-3:] + ) + if exc == SystemExit: - assert result.stdout.lines[-3:] == [ + assert end_lines == [ f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart', 'INTERNALERROR> raise SystemExit("boom")', + *( + ("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",) + if sys.version_info >= (3, 11) + else () + ), "INTERNALERROR> SystemExit: boom", ] else: - assert result.stdout.lines[-3:] == [ + assert end_lines == [ f'INTERNALERROR> File "{c1}", line 4, in pytest_sessionstart', 'INTERNALERROR> raise ValueError("boom")', + *( + ("INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^",) + if sys.version_info >= (3, 11) + else () + ), "INTERNALERROR> ValueError: boom", ] if returncode is False: @@ -171,6 +188,12 @@ class TestResolveCollectionArgument: invocation_path, "pkg::foo::bar", as_pypath=True ) + def test_parametrized_name_with_colons(self, invocation_path: Path) -> None: + ret = resolve_collection_argument( + invocation_path, "src/pkg/test.py::test[a::b]" + ) + assert ret == (invocation_path / "src/pkg/test.py", ["test[a::b]"]) + def test_does_not_exist(self, invocation_path: Path) -> None: """Given a file/module that does not exist raises UsageError.""" with pytest.raises( diff --git a/testing/test_nodes.py b/testing/test_nodes.py index c8afe0252..df1439e1c 100644 --- a/testing/test_nodes.py +++ b/testing/test_nodes.py @@ -1,3 +1,5 @@ +import re +import warnings from pathlib import Path from typing import cast from typing import List @@ -58,30 +60,31 @@ def test_subclassing_both_item_and_collector_deprecated( request, tmp_path: Path ) -> None: """ - Verifies we warn on diamond inheritance - as well as correctly managing legacy inheritance ctors with missing args - as found in plugins + Verifies we warn on diamond inheritance as well as correctly managing legacy + inheritance constructors with missing args as found in plugins. """ - with pytest.warns( - PytestWarning, - match=( - "(?m)SoWrong is an Item subclass and should not be a collector, however its bases File are collectors.\n" - "Please split the Collectors and the Item into separate node types.\n.*" - ), - ): + # We do not expect any warnings messages to issued during class definition. + with warnings.catch_warnings(): + warnings.simplefilter("error") class SoWrong(nodes.Item, nodes.File): def __init__(self, fspath, parent): """Legacy ctor with legacy call # don't wana see""" super().__init__(fspath, parent) - with pytest.warns( - PytestWarning, match=".*SoWrong.* not using a cooperative constructor.*" - ): + with pytest.warns(PytestWarning) as rec: SoWrong.from_parent( request.session, fspath=legacy_path(tmp_path / "broken.txt") ) + messages = [str(x.message) for x in rec] + assert any( + re.search(".*SoWrong.* not using a cooperative constructor.*", x) + for x in messages + ) + assert any( + re.search("(?m)SoWrong .* should not be a collector", x) for x in messages + ) @pytest.mark.parametrize( diff --git a/testing/test_nose.py b/testing/test_nose.py index 1ded8854b..cab5a81a2 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -345,7 +345,7 @@ def test_SkipTest_during_collection(pytester: Pytester) -> None: """ ) result = pytester.runpytest(p) - result.assert_outcomes(skipped=1, warnings=1) + result.assert_outcomes(skipped=1, warnings=0) def test_SkipTest_in_test(pytester: Pytester) -> None: diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index fe5e08f21..c901dc6f4 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -562,15 +562,20 @@ class TestImportLibMode: result = module_name_from_path(Path("/home/foo/test_foo.py"), Path("/bar")) assert result == "home.foo.test_foo" - def test_insert_missing_modules(self) -> None: - modules = {"src.tests.foo": ModuleType("src.tests.foo")} - insert_missing_modules(modules, "src.tests.foo") - assert sorted(modules) == ["src", "src.tests", "src.tests.foo"] + def test_insert_missing_modules( + self, monkeypatch: MonkeyPatch, tmp_path: Path + ) -> None: + monkeypatch.chdir(tmp_path) + # Use 'xxx' and 'xxy' as parent names as they are unlikely to exist and + # don't end up being imported. + modules = {"xxx.tests.foo": ModuleType("xxx.tests.foo")} + insert_missing_modules(modules, "xxx.tests.foo") + assert sorted(modules) == ["xxx", "xxx.tests", "xxx.tests.foo"] mod = ModuleType("mod", doc="My Module") - modules = {"src": mod} - insert_missing_modules(modules, "src") - assert modules == {"src": mod} + modules = {"xxy": mod} + insert_missing_modules(modules, "xxy") + assert modules == {"xxy": mod} modules = {} insert_missing_modules(modules, "") diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 9f7cf42b7..62dad9858 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -618,14 +618,9 @@ def test_linematcher_string_api() -> None: def test_pytest_addopts_before_pytester(request, monkeypatch: MonkeyPatch) -> None: - orig = os.environ.get("PYTEST_ADDOPTS", None) monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused") - pytester: Pytester = request.getfixturevalue("pytester") + _: Pytester = request.getfixturevalue("pytester") assert "PYTEST_ADDOPTS" not in os.environ - pytester._finalize() - assert os.environ.get("PYTEST_ADDOPTS") == "--orig-unused" - monkeypatch.undo() - assert os.environ.get("PYTEST_ADDOPTS") == orig def test_run_stdin(pytester: Pytester) -> None: @@ -743,8 +738,8 @@ def test_run_result_repr() -> None: # known exit code r = pytester_mod.RunResult(1, outlines, errlines, duration=0.5) - assert ( - repr(r) == "" ) diff --git a/testing/test_pythonpath.py b/testing/test_python_path.py similarity index 98% rename from testing/test_pythonpath.py rename to testing/test_python_path.py index 97c439ce0..5ee0f55e3 100644 --- a/testing/test_pythonpath.py +++ b/testing/test_python_path.py @@ -81,7 +81,7 @@ def test_no_ini(pytester: Pytester, file_structure) -> None: def test_clean_up(pytester: Pytester) -> None: - """Test that the pythonpath plugin cleans up after itself.""" + """Test that the plugin cleans up after itself.""" # This is tough to test behaviorly because the cleanup really runs last. # So the test make several implementation assumptions: # - Cleanup is done in pytest_unconfigure(). diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index c5a8ae90f..7e0f836a6 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -1,4 +1,3 @@ -import re import warnings from typing import Optional @@ -263,7 +262,7 @@ class TestWarns: with pytest.warns(RuntimeWarning): warnings.warn("user", UserWarning) excinfo.match( - r"DID NOT WARN. No warnings of type \(.+RuntimeWarning.+,\) were emitted. " + r"DID NOT WARN. No warnings of type \(.+RuntimeWarning.+,\) were emitted.\n" r"The list of emitted warnings is: \[UserWarning\('user',?\)\]." ) @@ -271,15 +270,15 @@ class TestWarns: with pytest.warns(UserWarning): warnings.warn("runtime", RuntimeWarning) excinfo.match( - r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) were emitted. " - r"The list of emitted warnings is: \[RuntimeWarning\('runtime',?\)\]." + r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) were emitted.\n" + r"The list of emitted warnings is: \[RuntimeWarning\('runtime',?\)]." ) with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(UserWarning): pass excinfo.match( - r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) were emitted. " + r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) were emitted.\n" r"The list of emitted warnings is: \[\]." ) @@ -289,18 +288,14 @@ class TestWarns: warnings.warn("runtime", RuntimeWarning) warnings.warn("import", ImportWarning) - message_template = ( - "DID NOT WARN. No warnings of type {0} were emitted. " - "The list of emitted warnings is: {1}." - ) - excinfo.match( - re.escape( - message_template.format( - warning_classes, [each.message for each in warninfo] - ) - ) + messages = [each.message for each in warninfo] + expected_str = ( + f"DID NOT WARN. No warnings of type {warning_classes} were emitted.\n" + f"The list of emitted warnings is: {messages}." ) + assert str(excinfo.value) == expected_str + def test_record(self) -> None: with pytest.warns(UserWarning) as record: warnings.warn("user", UserWarning) diff --git a/testing/test_terminal.py b/testing/test_terminal.py index e5f412662..f0e58e5b4 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -783,6 +783,33 @@ class TestTerminalFunctional: result.stdout.no_fnmatch_line("*= 1 deselected =*") assert result.ret == 0 + def test_selected_count_with_error(self, pytester: Pytester) -> None: + pytester.makepyfile( + test_selected_count_3=""" + def test_one(): + pass + def test_two(): + pass + def test_three(): + pass + """, + test_selected_count_error=""" + 5/0 + def test_foo(): + pass + def test_bar(): + pass + """, + ) + result = pytester.runpytest("-k", "test_t") + result.stdout.fnmatch_lines( + [ + "collected 3 items / 1 error / 1 deselected / 2 selected", + "* ERROR collecting test_selected_count_error.py *", + ] + ) + assert result.ret == ExitCode.INTERRUPTED + def test_no_skip_summary_if_failure(self, pytester: Pytester) -> None: pytester.makepyfile( """ diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 12bcb9361..fb3128145 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1472,3 +1472,56 @@ def test_do_cleanups_on_teardown_failure(pytester: Pytester) -> None: passed, skipped, failed = reprec.countoutcomes() assert failed == 2 assert passed == 1 + + +def test_traceback_pruning(pytester: Pytester) -> None: + """Regression test for #9610 - doesn't crash during traceback pruning.""" + pytester.makepyfile( + """ + import unittest + + class MyTestCase(unittest.TestCase): + def __init__(self, test_method): + unittest.TestCase.__init__(self, test_method) + + class TestIt(MyTestCase): + @classmethod + def tearDownClass(cls) -> None: + assert False + + def test_it(self): + pass + """ + ) + reprec = pytester.inline_run() + passed, skipped, failed = reprec.countoutcomes() + assert passed == 1 + assert failed == 1 + assert reprec.ret == 1 + + +def test_raising_unittest_skiptest_during_collection( + pytester: Pytester, +) -> None: + pytester.makepyfile( + """ + import unittest + + class TestIt(unittest.TestCase): + def test_it(self): pass + def test_it2(self): pass + + raise unittest.SkipTest() + + class TestIt2(unittest.TestCase): + def test_it(self): pass + def test_it2(self): pass + """ + ) + reprec = pytester.inline_run() + passed, skipped, failed = reprec.countoutcomes() + assert passed == 0 + # Unittest reports one fake test for a skipped module. + assert skipped == 1 + assert failed == 0 + assert reprec.ret == ExitCode.NO_TESTS_COLLECTED diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 734e1ebb5..7b716bb45 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -1,4 +1,5 @@ import os +import sys import warnings from typing import List from typing import Optional @@ -774,3 +775,57 @@ class TestStackLevel: "*Unknown pytest.mark.unknown*", ] ) + + +def test_resource_warning(pytester: Pytester, monkeypatch: pytest.MonkeyPatch) -> None: + # Some platforms (notably PyPy) don't have tracemalloc. + # We choose to explicitly not skip this in case tracemalloc is not + # available, using `importorskip("tracemalloc")` for example, + # because we want to ensure the same code path does not break in those platforms. + try: + import tracemalloc # noqa + + has_tracemalloc = True + except ImportError: + has_tracemalloc = False + + # Explicitly disable PYTHONTRACEMALLOC in case pytest's test suite is running + # with it enabled. + monkeypatch.delenv("PYTHONTRACEMALLOC", raising=False) + + pytester.makepyfile( + """ + def open_file(p): + f = p.open("r") + assert p.read_text() == "hello" + + def test_resource_warning(tmp_path): + p = tmp_path.joinpath("foo.txt") + p.write_text("hello") + open_file(p) + """ + ) + result = pytester.run(sys.executable, "-Xdev", "-m", "pytest") + expected_extra = ( + [ + "*ResourceWarning* unclosed file*", + "*Enable tracemalloc to get traceback where the object was allocated*", + "*See https* for more info.", + ] + if has_tracemalloc + else [] + ) + result.stdout.fnmatch_lines([*expected_extra, "*1 passed*"]) + + monkeypatch.setenv("PYTHONTRACEMALLOC", "20") + + result = pytester.run(sys.executable, "-Xdev", "-m", "pytest") + expected_extra = ( + [ + "*ResourceWarning* unclosed file*", + "*Object allocated at*", + ] + if has_tracemalloc + else [] + ) + result.stdout.fnmatch_lines([*expected_extra, "*1 passed*"]) diff --git a/tox.ini b/tox.ini index a1f4cab00..93c390ffc 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,7 @@ envlist = py38 py39 py310 + py311 pypy3 py37-{pexpect,xdist,unittestextras,numpy,pluggymain} doctesting