diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 20a72270f..640a0f1c2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -31,7 +31,7 @@ jobs: persist-credentials: false - name: Build and Check Package - uses: hynek/build-and-inspect-python-package@v2.5.0 + uses: hynek/build-and-inspect-python-package@v2.6.0 with: attest-build-provenance-github: 'true' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09d37aaa2..45e9c918a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Build and Check Package - uses: hynek/build-and-inspect-python-package@v2.5.0 + uses: hynek/build-and-inspect-python-package@v2.6.0 build: needs: [package] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f20f61761..fb583b111 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.4" + rev: "v0.4.7" hooks: - id: ruff args: ["--fix"] @@ -43,6 +43,11 @@ repos: - id: pyproject-fmt # https://pyproject-fmt.readthedocs.io/en/latest/#calculating-max-supported-python-version additional_dependencies: ["tox>=4.9"] +- repo: https://github.com/asottile/pyupgrade + rev: v3.15.2 + hooks: + - id: pyupgrade + stages: [manual] - repo: local hooks: - id: pylint diff --git a/AUTHORS b/AUTHORS index cc53ce10d..0560caf72 100644 --- a/AUTHORS +++ b/AUTHORS @@ -192,6 +192,7 @@ Jake VanderPlas Jakob van Santen Jakub Mitoraj James Bourbeau +James Frost Jan Balster Janne Vanhala Jason R. Coombs @@ -278,6 +279,7 @@ Michael Droettboom Michael Goerz Michael Krebs Michael Seifert +Michael Vogt Michal Wajszczuk Michał Górny Michał Zięba @@ -289,6 +291,7 @@ Mike Lundy Milan Lesnek Miro Hrončok mrbean-bremen +Nathan Goldbaum Nathaniel Compton Nathaniel Waisbrot Ned Batchelder diff --git a/changelog/12290.doc.rst b/changelog/12290.doc.rst deleted file mode 100644 index 07fe3babc..000000000 --- a/changelog/12290.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Updated Sphinx theme to use Furo instead of Flask, enabling Dark mode theme. diff --git a/changelog/12424.bugfix.rst b/changelog/12424.bugfix.rst new file mode 100644 index 000000000..7ad112685 --- /dev/null +++ b/changelog/12424.bugfix.rst @@ -0,0 +1 @@ +Fix crash with `assert testcase is not None` assertion failure when re-running unittest tests using plugins like pytest-rerunfailures. Regressed in 8.2.2. diff --git a/changelog/2871.improvement.rst b/changelog/2871.improvement.rst new file mode 100644 index 000000000..1ba399550 --- /dev/null +++ b/changelog/2871.improvement.rst @@ -0,0 +1 @@ +Do not truncate arguments to functions in output when running with `-vvv`. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 8a33f7fb5..c65eb5f36 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-8.2.2 release-8.2.1 release-8.2.0 release-8.1.2 diff --git a/doc/en/announce/release-8.2.2.rst b/doc/en/announce/release-8.2.2.rst new file mode 100644 index 000000000..3b1d93bd0 --- /dev/null +++ b/doc/en/announce/release-8.2.2.rst @@ -0,0 +1,19 @@ +pytest-8.2.2 +======================================= + +pytest 8.2.2 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at https://docs.pytest.org/en/stable/changelog.html. + +Thanks to all of the contributors to this release: + +* Bruno Oliveira +* Ran Benita + + +Happy testing, +The pytest Development Team diff --git a/doc/en/builtin.rst b/doc/en/builtin.rst index 458253fab..8dfffb082 100644 --- a/doc/en/builtin.rst +++ b/doc/en/builtin.rst @@ -22,7 +22,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a cachedir: .pytest_cache rootdir: /home/sweet/project collected 0 items - cache -- .../_pytest/cacheprovider.py:549 + cache -- .../_pytest/cacheprovider.py:560 Return a cache object that can persist state between testing sessions. cache.get(key, default) @@ -115,7 +115,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a For more details: :ref:`doctest_namespace`. - pytestconfig [session scope] -- .../_pytest/fixtures.py:1335 + pytestconfig [session scope] -- .../_pytest/fixtures.py:1338 Session-scoped fixture that returns the session's :class:`pytest.Config` object. diff --git a/doc/en/changelog.rst b/doc/en/changelog.rst index ca7f5b999..3ab2307ee 100644 --- a/doc/en/changelog.rst +++ b/doc/en/changelog.rst @@ -28,6 +28,35 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 8.2.2 (2024-06-04) +========================= + +Bug Fixes +--------- + +- `#12355 `_: Fix possible catastrophic performance slowdown on a certain parametrization pattern involving many higher-scoped parameters. + + +- `#12367 `_: Fix a regression in pytest 8.2.0 where unittest class instances (a fresh one is created for each test) were not released promptly on test teardown but only on session teardown. + + +- `#12381 `_: Fix possible "Directory not empty" crashes arising from concurent cache dir (``.pytest_cache``) creation. Regressed in pytest 8.2.0. + + + +Improved Documentation +---------------------- + +- `#12290 `_: Updated Sphinx theme to use Furo instead of Flask, enabling Dark mode theme. + + +- `#12356 `_: Added a subsection to the documentation for debugging flaky tests to mention + lack of thread safety in pytest as a possible source of flakyness. + + +- `#12363 `_: The documentation webpages now links to a canonical version to reduce outdated documentation in search engine results. + + pytest 8.2.1 (2024-05-19) ========================= diff --git a/doc/en/conf.py b/doc/en/conf.py index e64931ae5..738d07dc2 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -312,6 +312,9 @@ html_show_sourcelink = False # Output file base name for HTML help builder. htmlhelp_basename = "pytestdoc" +# The base URL which points to the root of the HTML documentation. It is used +# to indicate the location of document using the canonical link relation (#12363). +html_baseurl = "https://docs.pytest.org/en/stable/" # -- Options for LaTeX output -------------------------------------------------- diff --git a/doc/en/contact.rst b/doc/en/contact.rst index beed10d7f..68efef522 100644 --- a/doc/en/contact.rst +++ b/doc/en/contact.rst @@ -26,19 +26,12 @@ Contact channels `_, or `via Matrix `_). -- private mail to Holger.Krekel at gmail com if you want to communicate sensitive issues - - -- `merlinux.eu`_ offers pytest and tox-related professional teaching and - consulting. .. _`pytest issue tracker`: https://github.com/pytest-dev/pytest/issues .. _`old issue tracker`: https://bitbucket.org/hpk42/py-trunk/issues/ .. _`pytest discussions`: https://github.com/pytest-dev/pytest/discussions -.. _`merlinux.eu`: https://merlinux.eu/ - .. _`get an account`: .. _tetamap: https://tetamap.wordpress.com/ diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index 03f6852e5..d540bf083 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -162,7 +162,7 @@ objects, they are still using the default pytest representation: rootdir: /home/sweet/project collected 8 items - + @@ -239,7 +239,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia rootdir: /home/sweet/project collected 4 items - + @@ -318,7 +318,7 @@ Let's first see how it looks like at collection time: rootdir: /home/sweet/project collected 2 items - + diff --git a/doc/en/example/pythoncollection.rst b/doc/en/example/pythoncollection.rst index aa9d05d72..39b799ed9 100644 --- a/doc/en/example/pythoncollection.rst +++ b/doc/en/example/pythoncollection.rst @@ -152,7 +152,7 @@ The test collection would look like this: configfile: pytest.ini collected 2 items - + @@ -215,7 +215,7 @@ You can always peek at the collection tree without running tests like this: configfile: pytest.ini collected 3 items - + diff --git a/doc/en/explanation/flaky.rst b/doc/en/explanation/flaky.rst index 41cbe8479..cb6c39834 100644 --- a/doc/en/explanation/flaky.rst +++ b/doc/en/explanation/flaky.rst @@ -18,7 +18,7 @@ System state Broadly speaking, a flaky test indicates that the test relies on some system state that is not being appropriately controlled - the test environment is not sufficiently isolated. Higher level tests are more likely to be flaky as they rely on more state. -Flaky tests sometimes appear when a test suite is run in parallel (such as use of pytest-xdist). This can indicate a test is reliant on test ordering. +Flaky tests sometimes appear when a test suite is run in parallel (such as use of `pytest-xdist`_). This can indicate a test is reliant on test ordering. - Perhaps a different test is failing to clean up after itself and leaving behind data which causes the flaky test to fail. - The flaky test is reliant on data from a previous test that doesn't clean up after itself, and in parallel runs that previous test is not always present @@ -30,9 +30,22 @@ Overly strict assertion Overly strict assertions can cause problems with floating point comparison as well as timing issues. :func:`pytest.approx` is useful here. +Thread safety +~~~~~~~~~~~~~ -Pytest features -^^^^^^^^^^^^^^^ +pytest is single-threaded, executing its tests always in the same thread, sequentially, never spawning any threads itself. + +Even in case of plugins which run tests in parallel, for example `pytest-xdist`_, usually work by spawning multiple *processes* and running tests in batches, without using multiple threads. + +It is of course possible (and common) for tests and fixtures to spawn threads themselves as part of their testing workflow (for example, a fixture that starts a server thread in the background, or a test which executes production code that spawns threads), but some care must be taken: + +* Make sure to eventually wait on any spawned threads -- for example at the end of a test, or during the teardown of a fixture. +* Avoid using primitives provided by pytest (:func:`pytest.warns`, :func:`pytest.raises`, etc) from multiple threads, as they are not thread-safe. + +If your test suite uses threads and your are seeing flaky test results, do not discount the possibility that the test is implicitly using global state in pytest itself. + +Related features +^^^^^^^^^^^^^^^^ Xfail strict ~~~~~~~~~~~~ @@ -123,3 +136,6 @@ Resources * `Flaky Tests at Google and How We Mitigate Them `_ by John Micco, 2016 * `Where do Google's flaky tests come from? `_ by Jeff Listfield, 2017 + + +.. _pytest-xdist: https://github.com/pytest-dev/pytest-xdist diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index 94e0d80e6..85bee729b 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 8.2.1 + pytest 8.2.2 .. _`simpletest`: diff --git a/doc/en/how-to/fixtures.rst b/doc/en/how-to/fixtures.rst index 6cc20c8c3..35c3238de 100644 --- a/doc/en/how-to/fixtures.rst +++ b/doc/en/how-to/fixtures.rst @@ -1418,7 +1418,7 @@ Running the above tests results in the following test IDs being used: rootdir: /home/sweet/project collected 12 items - + diff --git a/doc/en/index.rst b/doc/en/index.rst index 2aebb0d6b..58527ea73 100644 --- a/doc/en/index.rst +++ b/doc/en/index.rst @@ -4,11 +4,10 @@ .. sidebar:: **Next Open Trainings and Events** - - `Professional Testing with Python `_, via `Python Academy `_ (3 day in-depth training): - * **June 11th to 13th 2024**, Remote - * **March 4th to 6th 2025**, Leipzig, Germany / Remote - - `pytest development sprint `_, **June 17th -- 22nd 2024** - - pytest tips and tricks for a better testsuite, `Europython 2024 `_, **July 8th -- 14th 2024** (3h), Prague + - `pytest development sprint `_, **June 17th -- 22nd 2024**, Klaus (AT) / Remote + - `pytest tips and tricks for a better testsuite `_, at `Europython 2024 `_, **July 8th -- 14th 2024** (3h), Prague (CZ) + - `pytest: Professionelles Testen (nicht nur) für Python `_, at `CH Open Workshoptage `_, **September 2nd 2024**, HSLU Rotkreuz (CH) + - `Professional Testing with Python `_, via `Python Academy `_ (3 day in-depth training), **March 4th -- 6th 2025**, Leipzig (DE) / Remote Also see :doc:`previous talks and blogposts ` diff --git a/doc/en/reference/plugin_list.rst b/doc/en/reference/plugin_list.rst index 43c4748ea..0f1162779 100644 --- a/doc/en/reference/plugin_list.rst +++ b/doc/en/reference/plugin_list.rst @@ -27,7 +27,7 @@ please refer to `the update script =7; extra == "pytest" - :pypi:`nuts` Network Unit Testing System Aug 11, 2023 N/A pytest (>=7.3.0,<8.0.0) + :pypi:`nuts` Network Unit Testing System May 28, 2024 N/A pytest<8,>=7 :pypi:`pytest-abq` Pytest integration for the ABQ universal test runner. Apr 07, 2023 N/A N/A :pypi:`pytest-abstracts` A contextmanager pytest fixture for handling multiple mock abstracts May 25, 2022 N/A N/A :pypi:`pytest-accept` A pytest-plugin for updating doctest outputs Feb 10, 2024 N/A pytest (>=6) @@ -109,7 +109,7 @@ This list contains 1461 plugins. :pypi:`pytest-ast-transformer` May 04, 2019 3 - Alpha pytest :pypi:`pytest_async` pytest-async - Run your coroutine in event loop without decorator Feb 26, 2020 N/A N/A :pypi:`pytest-async-generators` Pytest fixtures for async generators Jul 05, 2023 N/A N/A - :pypi:`pytest-asyncio` Pytest support for asyncio Mar 19, 2024 4 - Beta pytest <9,>=7.0.0 + :pypi:`pytest-asyncio` Pytest support for asyncio May 19, 2024 4 - Beta pytest<9,>=7.0.0 :pypi:`pytest-asyncio-cooperative` Run all your asynchronous tests cooperatively. Feb 25, 2024 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) @@ -124,10 +124,11 @@ This list contains 1461 plugins. :pypi:`pytest-automock` Pytest plugin for automatical mocks creation May 16, 2023 N/A pytest ; extra == 'dev' :pypi:`pytest-auto-parametrize` pytest plugin: avoid repeating arguments in parametrize Oct 02, 2016 3 - Alpha N/A :pypi:`pytest-autotest` This fixture provides a configured "driver" for Android Automated Testing, using uiautomator2. Aug 25, 2021 N/A pytest + :pypi:`pytest-aux` templates/examples and aux for pytest May 31, 2024 N/A N/A :pypi:`pytest-aviator` Aviator's Flakybot pytest plugin that automatically reruns flaky tests. Nov 04, 2022 4 - Beta pytest :pypi:`pytest-avoidance` Makes pytest skip tests that don not need rerunning May 23, 2019 4 - Beta pytest (>=3.5.0) :pypi:`pytest-aws` pytest plugin for testing AWS resource configurations Oct 04, 2017 4 - Beta N/A - :pypi:`pytest-aws-apigateway` pytest plugin for AWS ApiGateway May 18, 2024 4 - Beta pytest + :pypi:`pytest-aws-apigateway` pytest plugin for AWS ApiGateway May 24, 2024 4 - Beta pytest :pypi:`pytest-aws-config` Protect your AWS credentials in unit tests May 28, 2021 N/A N/A :pypi:`pytest-aws-fixtures` A series of fixtures to use in integration tests involving actual AWS services. Feb 02, 2024 N/A pytest (>=8.0.0,<9.0.0) :pypi:`pytest-axe` pytest plugin for axe-selenium-python Nov 12, 2018 N/A pytest (>=3.0.0) @@ -142,13 +143,13 @@ This list contains 1461 plugins. :pypi:`pytest-bdd` BDD for pytest Mar 17, 2024 6 - Mature pytest (>=6.2.0) :pypi:`pytest-bdd-html` pytest plugin to display BDD info in HTML test report Nov 22, 2022 3 - Alpha pytest (!=6.0.0,>=5.0) :pypi:`pytest-bdd-ng` BDD for pytest Dec 31, 2023 4 - Beta pytest >=5.0 - :pypi:`pytest-bdd-report` A pytest-bdd plugin for generating useful and informative BDD test reports Feb 19, 2024 N/A pytest >=7.1.3 + :pypi:`pytest-bdd-report` A pytest-bdd plugin for generating useful and informative BDD test reports May 20, 2024 N/A pytest >=7.1.3 :pypi:`pytest-bdd-splinter` Common steps for pytest bdd and splinter integration Aug 12, 2019 5 - Production/Stable pytest (>=4.0.0) :pypi:`pytest-bdd-web` A simple plugin to use with pytest Jan 02, 2020 4 - Beta pytest (>=3.5.0) :pypi:`pytest-bdd-wrappers` Feb 11, 2020 2 - Pre-Alpha N/A :pypi:`pytest-beakerlib` A pytest plugin that reports test results to the BeakerLib framework Mar 17, 2017 5 - Production/Stable pytest :pypi:`pytest-beartype` Pytest plugin to run your tests with beartype checking enabled. Jan 25, 2024 N/A pytest - :pypi:`pytest-bec-e2e` BEC pytest plugin for end-to-end tests May 17, 2024 3 - Alpha pytest + :pypi:`pytest-bec-e2e` BEC pytest plugin for end-to-end tests May 31, 2024 3 - Alpha pytest :pypi:`pytest-beds` Fixtures for testing Google Appengine (GAE) apps Jun 07, 2016 4 - Beta N/A :pypi:`pytest-beeprint` use icdiff for better error messages in pytest assertions Jul 04, 2023 4 - Beta N/A :pypi:`pytest-bench` Benchmark utility that plugs into pytest. Jul 21, 2014 3 - Alpha N/A @@ -171,6 +172,7 @@ This list contains 1461 plugins. :pypi:`pytest-board` Local continuous test runner with pytest and watchdog. Jan 20, 2019 N/A N/A :pypi:`pytest-boost-xml` Plugin for pytest to generate boost xml reports Nov 30, 2022 4 - Beta N/A :pypi:`pytest-bootstrap` Mar 04, 2022 N/A N/A + :pypi:`pytest-boto-mock` Thin-wrapper around the mock package for easier use with pytest May 27, 2024 5 - Production/Stable pytest>=8.2.0 :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-bq` BigQuery fixtures and fixture factories for Pytest. May 08, 2024 5 - Production/Stable pytest>=6.2 :pypi:`pytest-bravado` Pytest-bravado automatically generates from OpenAPI specification client fixtures. Feb 15, 2022 N/A N/A @@ -233,7 +235,7 @@ This list contains 1461 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 Nov 07, 2022 N/A pytest (>=3.6) - :pypi:`pytest-cleanslate` Collects and executes pytest tests separately May 15, 2024 N/A pytest + :pypi:`pytest-cleanslate` Collects and executes pytest tests separately May 30, 2024 N/A pytest :pypi:`pytest_cleanup` Automated, comprehensive and well-organised pytest test cases. Jan 28, 2020 N/A N/A :pypi:`pytest-cleanuptotal` A cleanup plugin for pytest Mar 19, 2024 5 - Production/Stable N/A :pypi:`pytest-clerk` A set of pytest fixtures to help with integration testing with Clerk. Apr 19, 2024 N/A pytest<9.0.0,>=8.0.0 @@ -243,7 +245,7 @@ This list contains 1461 plugins. :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) :pypi:`pytest-cloudist` Distribute tests to cloud machines without fuss Sep 02, 2022 4 - Beta pytest (>=7.1.2,<8.0.0) - :pypi:`pytest-cmake` Provide CMake module for Pytest May 12, 2024 N/A pytest<9,>=4 + :pypi:`pytest-cmake` Provide CMake module for Pytest May 31, 2024 N/A pytest<9,>=4 :pypi:`pytest-cmake-presets` Execute CMake Presets via pytest Dec 26, 2022 N/A pytest (>=7.2.0,<8.0.0) :pypi:`pytest-cobra` PyTest plugin for testing Smart Contracts for Ethereum blockchain. Jun 29, 2019 3 - Alpha pytest (<4.0.0,>=3.7.1) :pypi:`pytest_codeblocks` Test code blocks in your READMEs Sep 17, 2023 5 - Production/Stable pytest >= 7.0.0 @@ -258,6 +260,7 @@ This list contains 1461 plugins. :pypi:`pytest-collect-formatter` Formatter for pytest collect output Mar 29, 2021 5 - Production/Stable N/A :pypi:`pytest-collect-formatter2` Formatter for pytest collect output May 31, 2021 5 - Production/Stable N/A :pypi:`pytest-collect-interface-info-plugin` Get executed interface information in pytest interface automation framework Sep 25, 2023 4 - Beta N/A + :pypi:`pytest-collect-jmeter-report-tests` A simple plugin to use with pytest May 20, 2024 4 - Beta pytest>=7.2.1 :pypi:`pytest-collector` Python package for collecting pytest. Aug 02, 2022 N/A pytest (>=7.0,<8.0) :pypi:`pytest-collect-pytest-interinfo` A simple plugin to use with pytest Sep 26, 2023 4 - Beta N/A :pypi:`pytest-colordots` Colorizes the progress indicators Oct 06, 2017 5 - Production/Stable N/A @@ -301,15 +304,16 @@ This list contains 1461 plugins. :pypi:`pytest-custom-concurrency` Custom grouping concurrence for pytest Feb 08, 2021 N/A N/A :pypi:`pytest-custom-exit-code` Exit pytest test session with custom exit code in different scenarios Aug 07, 2019 4 - Beta pytest (>=4.0.2) :pypi:`pytest-custom-nodeid` Custom grouping for pytest-xdist, rename test cases name and test cases nodeid, support allure report Mar 07, 2021 N/A N/A + :pypi:`pytest-custom-outputs` A plugin that allows users to create and use custom outputs instead of the standard Pass and Fail May 30, 2024 4 - Beta pytest>=6.2.0 :pypi:`pytest-custom-report` Configure the symbols displayed for test outcomes Jan 30, 2019 N/A pytest :pypi:`pytest-custom-scheduling` Custom grouping for pytest-xdist, rename test cases name and test cases nodeid, support allure report Mar 01, 2021 N/A N/A :pypi:`pytest-cython` A plugin for testing Cython extension modules Apr 05, 2024 5 - Production/Stable pytest>=8 :pypi:`pytest-cython-collect` Jun 17, 2022 N/A pytest :pypi:`pytest-darker` A pytest plugin for checking of modified code using Darker Feb 25, 2024 N/A pytest <7,>=6.0.1 :pypi:`pytest-dash` pytest fixtures to run dash applications. Mar 18, 2019 N/A N/A - :pypi:`pytest-dashboard` Apr 22, 2024 N/A pytest<8.0.0,>=7.4.3 + :pypi:`pytest-dashboard` May 30, 2024 N/A pytest<8.0.0,>=7.4.3 :pypi:`pytest-data` Useful functions for managing data for pytest fixtures Nov 01, 2016 5 - Production/Stable N/A - :pypi:`pytest-databases` Reusable database fixtures for any and all databases. Apr 21, 2024 4 - Beta pytest + :pypi:`pytest-databases` Reusable database fixtures for any and all databases. May 25, 2024 4 - Beta pytest :pypi:`pytest-databricks` Pytest plugin for remote Databricks notebooks testing Jul 29, 2020 N/A pytest :pypi:`pytest-datadir` pytest plugin for test data directories and files Oct 03, 2023 5 - Production/Stable pytest >=5.0 :pypi:`pytest-datadir-mgr` Manager for test data: downloads, artifact caching, and a tmpdir context. Apr 06, 2023 5 - Production/Stable pytest (>=7.1) @@ -361,14 +365,15 @@ This list contains 1461 plugins. :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. May 11, 2024 4 - Beta pytest!=6.0.0,<9,>=3.3.2 :pypi:`pytest-discover` Pytest plugin to record discovered tests in a file Mar 26, 2024 N/A pytest - :pypi:`pytest-ditto` Snapshot testing pytest plugin with minimal ceremony and flexible persistence formats. May 07, 2024 4 - Beta pytest>=3.5.0 + :pypi:`pytest-ditto` Snapshot testing pytest plugin with minimal ceremony and flexible persistence formats. May 29, 2024 4 - Beta pytest>=3.5.0 + :pypi:`pytest-ditto-pandas` pytest-ditto plugin for pandas snapshots. May 29, 2024 4 - Beta pytest>=3.5.0 :pypi:`pytest-django` A Django plugin for pytest. Jan 30, 2024 5 - Production/Stable pytest >=7.0.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. May 19, 2023 4 - Beta pytest :pypi:`pytest-django-cache-xdist` A djangocachexdist plugin for pytest May 12, 2020 4 - Beta N/A :pypi:`pytest-django-casperjs` Integrate CasperJS with your django tests as a pytest fixture. Mar 15, 2015 2 - Pre-Alpha N/A :pypi:`pytest-django-class` A pytest plugin for running django in class-scoped fixtures Aug 08, 2023 4 - Beta N/A - :pypi:`pytest-django-docker-pg` Jan 30, 2024 5 - Production/Stable pytest <8.0.0,>=7.0.0 + :pypi:`pytest-django-docker-pg` May 21, 2024 5 - Production/Stable pytest<9.0.0,>=7.0.0 :pypi:`pytest-django-dotenv` Pytest plugin used to setup environment variables with django-dotenv Nov 26, 2019 4 - Beta pytest (>=2.6.0) :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-filefield` Replaces FileField.storage with something you can patch globally. May 09, 2022 5 - Production/Stable pytest >= 5.2 @@ -443,14 +448,14 @@ This list contains 1461 plugins. :pypi:`pytest-eliot` An eliot plugin for pytest. Aug 31, 2022 1 - Planning pytest (>=5.4.0) :pypi:`pytest-elk-reporter` A simple plugin to use with pytest Apr 04, 2024 4 - Beta pytest>=3.5.0 :pypi:`pytest-email` Send execution result email Jul 08, 2020 N/A pytest - :pypi:`pytest-embedded` A pytest plugin that designed for embedded testing. Apr 30, 2024 5 - Production/Stable pytest>=7.0 - :pypi:`pytest-embedded-arduino` Make pytest-embedded plugin work with Arduino. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-idf` Make pytest-embedded plugin work with ESP-IDF. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-jtag` Make pytest-embedded plugin work with JTAG. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-qemu` Make pytest-embedded plugin work with QEMU. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-serial` Make pytest-embedded plugin work with Serial. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-serial-esp` Make pytest-embedded plugin work with Espressif target boards. Apr 30, 2024 5 - Production/Stable N/A - :pypi:`pytest-embedded-wokwi` Make pytest-embedded plugin work with the Wokwi CLI. Apr 30, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded` A pytest plugin that designed for embedded testing. May 31, 2024 5 - Production/Stable pytest>=7.0 + :pypi:`pytest-embedded-arduino` Make pytest-embedded plugin work with Arduino. May 23, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-idf` Make pytest-embedded plugin work with ESP-IDF. May 23, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-jtag` Make pytest-embedded plugin work with JTAG. May 23, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-qemu` Make pytest-embedded plugin work with QEMU. May 23, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-serial` Make pytest-embedded plugin work with Serial. May 31, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-serial-esp` Make pytest-embedded plugin work with Espressif target boards. May 31, 2024 5 - Production/Stable N/A + :pypi:`pytest-embedded-wokwi` Make pytest-embedded plugin work with the Wokwi CLI. May 23, 2024 5 - Production/Stable N/A :pypi:`pytest-embrace` 💝 Dataclasses-as-tests. Describe the runtime once and multiply coverage with no boilerplate. Mar 25, 2023 N/A pytest (>=7.0,<8.0) :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 Apr 09, 2023 4 - Beta pytest (==7.0.1) @@ -479,6 +484,7 @@ This list contains 1461 plugins. :pypi:`pytest_exact_fixtures` Parse queries in Lucene and Elasticsearch syntaxes Feb 04, 2019 N/A N/A :pypi:`pytest-examples` Pytest plugin for testing examples in docstrings and markdown files. Jul 11, 2023 4 - Beta pytest>=7 :pypi:`pytest-exasol-itde` Feb 15, 2024 N/A pytest (>=7,<9) + :pypi:`pytest-exasol-saas` May 27, 2024 N/A pytest<9,>=7 :pypi:`pytest-excel` pytest plugin for generating excel reports Sep 14, 2023 5 - Production/Stable N/A :pypi:`pytest-exceptional` Better exceptions Mar 16, 2017 4 - Beta N/A :pypi:`pytest-exception-script` Walk your code through exception script to check it's resiliency to failures. Aug 04, 2020 3 - Alpha pytest @@ -519,7 +525,7 @@ This list contains 1461 plugins. :pypi:`pytest-fastest` Use SCM and coverage to run only needed tests Oct 04, 2023 4 - Beta pytest (>=4.4) :pypi:`pytest-fast-first` Pytest plugin that runs fast tests first Jan 19, 2023 3 - Alpha pytest :pypi:`pytest-faulthandler` py.test plugin that activates the fault handler module for tests (dummy package) Jul 04, 2019 6 - Mature pytest (>=5.0) - :pypi:`pytest-fauna` A collection of helpful test fixtures for Fauna DB. Apr 22, 2024 N/A N/A + :pypi:`pytest-fauna` A collection of helpful test fixtures for Fauna DB. May 30, 2024 N/A N/A :pypi:`pytest-fauxfactory` Integration of fauxfactory into pytest. Dec 06, 2017 5 - Production/Stable pytest (>=3.2) :pypi:`pytest-figleaf` py.test figleaf coverage plugin Jan 18, 2010 5 - Production/Stable N/A :pypi:`pytest-file` Pytest File Mar 18, 2024 1 - Planning N/A @@ -615,7 +621,6 @@ This list contains 1461 plugins. :pypi:`pytest-hardware-test-report` A simple plugin to use with pytest Apr 01, 2024 4 - Beta pytest<9.0.0,>=8.0.0 :pypi:`pytest-harmony` Chain tests and data with pytest Jan 17, 2023 N/A pytest (>=7.2.1,<8.0.0) :pypi:`pytest-harvest` Store data created during your pytest tests execution, and retrieve it at the end of the session, e.g. for applicative benchmarking purposes. Mar 16, 2024 5 - Production/Stable N/A - :pypi:`pytest-helm-chart` A plugin to provide different types and configs of Kubernetes clusters that can be used for testing. Jun 15, 2020 4 - Beta pytest (>=5.4.2,<6.0.0) :pypi:`pytest-helm-charts` A plugin to provide different types and configs of Kubernetes clusters that can be used for testing. Feb 07, 2024 4 - Beta pytest (>=8.0.0,<9.0.0) :pypi:`pytest-helm-templates` Pytest fixtures for unit testing the output of helm templates May 08, 2024 N/A pytest~=7.4.0; extra == "dev" :pypi:`pytest-helper` Functions to help in using the pytest testing framework May 31, 2019 5 - Production/Stable N/A @@ -629,7 +634,7 @@ This list contains 1461 plugins. :pypi:`pytest-history` Pytest plugin to keep a history of your pytest runs Jan 14, 2024 N/A pytest (>=7.4.3,<8.0.0) :pypi:`pytest-home` Home directory fixtures Oct 09, 2023 5 - Production/Stable 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 May 18, 2024 3 - Alpha pytest==8.1.1 + :pypi:`pytest-homeassistant-custom-component` Experimental package to automatically extract test plugins for Home Assistant custom components May 31, 2024 3 - Alpha pytest==8.2.0 :pypi:`pytest-honey` A simple plugin to use with pytest Jan 07, 2022 4 - Beta pytest (>=3.5.0) :pypi:`pytest-honors` Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A :pypi:`pytest-hot-reloading` Apr 18, 2024 N/A N/A @@ -645,7 +650,7 @@ This list contains 1461 plugins. :pypi:`pytest-html-object-storage` Pytest report plugin for send HTML report on object-storage Jan 17, 2024 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 Feb 13, 2022 N/A N/A - :pypi:`pytest-html-report-merger` Oct 23, 2023 N/A N/A + :pypi:`pytest-html-report-merger` May 22, 2024 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 May 08, 2023 5 - Production/Stable pytest ; extra == 'test' @@ -680,7 +685,7 @@ This list contains 1461 plugins. :pypi:`pytest-initry` Plugin for sending automation test data from Pytest to the initry Apr 30, 2024 N/A pytest<9.0.0,>=8.1.1 :pypi:`pytest-inline` A pytest plugin for writing inline tests. Oct 19, 2023 4 - Beta pytest >=7.0.0 :pypi:`pytest-inmanta` A py.test plugin providing fixtures to simplify inmanta modules testing. Dec 13, 2023 5 - Production/Stable pytest - :pypi:`pytest-inmanta-extensions` Inmanta tests package Apr 02, 2024 5 - Production/Stable N/A + :pypi:`pytest-inmanta-extensions` Inmanta tests package May 24, 2024 5 - Production/Stable N/A :pypi:`pytest-inmanta-lsm` Common fixtures for inmanta LSM related modules May 10, 2024 5 - Production/Stable N/A :pypi:`pytest-inmanta-yang` Common fixtures used in inmanta yang related modules Feb 22, 2024 4 - Beta pytest :pypi:`pytest-Inomaly` A simple image diff plugin for pytest Feb 13, 2018 4 - Beta N/A @@ -716,11 +721,13 @@ This list contains 1461 plugins. :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-json-ctrf` Pytest plugin to generate json report in CTRF (Common Test Report Format) May 21, 2024 N/A pytest>6.0.0 :pypi:`pytest-json-fixtures` JSON output for the --fixtures flag Mar 14, 2023 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 Mar 15, 2022 4 - Beta pytest (>=3.8.0) :pypi:`pytest-json-report-wip` A pytest plugin to report test results as JSON files Oct 28, 2023 4 - Beta pytest >=3.8.0 :pypi:`pytest-jsonschema` A pytest plugin to perform JSONSchema validations Mar 27, 2024 4 - Beta pytest>=6.2.0 + :pypi:`pytest-jtl-collector` A simple plugin to use with pytest May 20, 2024 4 - Beta pytest>=7.2.1 :pypi:`pytest-jtr` pytest plugin supporting json test report output Apr 15, 2024 N/A pytest<8.0.0,>=7.1.2 :pypi:`pytest-jupyter` A pytest plugin for testing Jupyter libraries and extensions. Apr 04, 2024 4 - Beta pytest>=7.0 :pypi:`pytest-jupyterhub` A reusable JupyterHub pytest plugin Apr 25, 2023 5 - Production/Stable pytest @@ -740,7 +747,7 @@ This list contains 1461 plugins. :pypi:`pytest-kubernetes` Sep 14, 2023 N/A pytest (>=7.2.1,<8.0.0) :pypi:`pytest-kuunda` pytest plugin to help with test data setup for PySpark tests Feb 25, 2024 4 - Beta pytest >=6.2.0 :pypi:`pytest-kwparametrize` Alternate syntax for @pytest.mark.parametrize with test cases as dictionaries and default value fallbacks Jan 22, 2021 N/A pytest (>=6) - :pypi:`pytest-lambda` Define pytest fixtures with lambda functions. Aug 20, 2022 3 - Alpha pytest (>=3.6,<8) + :pypi:`pytest-lambda` Define pytest fixtures with lambda functions. May 27, 2024 5 - Production/Stable pytest<9,>=3.6 :pypi:`pytest-lamp` Jan 06, 2017 3 - Alpha N/A :pypi:`pytest-langchain` Pytest-style test runner for langchain agents Feb 26, 2023 N/A pytest :pypi:`pytest-lark` Create fancy and clear HTML test reports. Nov 05, 2023 N/A N/A @@ -766,7 +773,7 @@ This list contains 1461 plugins. :pypi:`pytest-litter` Pytest plugin which verifies that tests do not modify file trees. Nov 23, 2023 4 - Beta pytest >=6.1 :pypi:`pytest-live` Live results for pytest Mar 08, 2020 N/A pytest :pypi:`pytest-local-badge` Generate local badges (shields) reporting your test suite status. Jan 15, 2023 N/A pytest (>=6.1.0) - :pypi:`pytest-localftpserver` A PyTest plugin which provides an FTP fixture for your tests May 17, 2024 5 - Production/Stable pytest + :pypi:`pytest-localftpserver` A PyTest plugin which provides an FTP fixture for your tests May 19, 2024 5 - Production/Stable pytest :pypi:`pytest-localserver` pytest plugin to test server connections locally. Oct 12, 2023 4 - Beta N/A :pypi:`pytest-localstack` Pytest plugin for AWS integration tests Jun 07, 2023 4 - Beta pytest (>=6.0.0,<7.0.0) :pypi:`pytest-lock` pytest-lock is a pytest plugin that allows you to "lock" the results of unit tests, storing them in a local cache. This is particularly useful for tests that are resource-intensive or don't need to be run every time. When the tests are run subsequently, pytest-lock will compare the current results with the locked results and issue a warning if there are any discrepancies. Feb 03, 2024 N/A pytest (>=7.4.3,<8.0.0) @@ -779,11 +786,11 @@ This list contains 1461 plugins. :pypi:`pytest-logger` Plugin configuring handlers for loggers from Python logging module. Mar 10, 2024 5 - Production/Stable 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-logging-end-to-end-test-tool` Sep 23, 2022 N/A pytest (>=7.1.2,<8.0.0) - :pypi:`pytest-logikal` Common testing environment Mar 30, 2024 5 - Production/Stable pytest==8.1.1 + :pypi:`pytest-logikal` Common testing environment May 23, 2024 5 - Production/Stable pytest==8.2.1 :pypi:`pytest-log-report` Package for creating a pytest test run reprot Dec 26, 2019 N/A N/A :pypi:`pytest-loguru` Pytest Loguru Mar 20, 2024 5 - Production/Stable pytest; extra == "test" :pypi:`pytest-loop` pytest plugin for looping tests Mar 30, 2024 5 - Production/Stable pytest - :pypi:`pytest-lsp` A pytest plugin for end-to-end testing of language servers Feb 07, 2024 3 - Alpha pytest + :pypi:`pytest-lsp` A pytest plugin for end-to-end testing of language servers May 22, 2024 3 - Alpha pytest :pypi:`pytest-manual-marker` pytest marker for marking manual tests Aug 04, 2022 3 - Alpha pytest>=7 :pypi:`pytest-markdoctest` A pytest plugin to doctest your markdown files Jul 22, 2022 4 - Beta pytest (>=6) :pypi:`pytest-markdown` Test your markdown docs with pytest Jan 15, 2021 4 - Beta pytest (>=6.0.1,<7.0.0) @@ -814,13 +821,13 @@ This list contains 1461 plugins. :pypi:`pytest-messenger` Pytest to Slack reporting plugin Nov 24, 2022 5 - Production/Stable N/A :pypi:`pytest-metadata` pytest plugin for test session metadata Feb 12, 2024 5 - Production/Stable pytest>=7.0.0 :pypi:`pytest-metrics` Custom metrics report for pytest Apr 04, 2020 N/A pytest - :pypi:`pytest-mh` Pytest multihost plugin Mar 14, 2024 N/A pytest + :pypi:`pytest-mh` Pytest multihost plugin May 28, 2024 N/A pytest :pypi:`pytest-mimesis` Mimesis integration with the pytest test runner Mar 21, 2020 5 - Production/Stable pytest (>=4.2) :pypi:`pytest-minecraft` A pytest plugin for running tests against Minecraft releases Apr 06, 2022 N/A pytest (>=6.0.1) :pypi:`pytest-mini` A plugin to test mp Feb 06, 2023 N/A pytest (>=7.2.0,<8.0.0) - :pypi:`pytest-minio-mock` A pytest plugin for mocking Minio S3 interactions Apr 27, 2024 N/A pytest>=5.0.0 + :pypi:`pytest-minio-mock` A pytest plugin for mocking Minio S3 interactions May 26, 2024 N/A pytest>=5.0.0 :pypi:`pytest-missing-fixtures` Pytest plugin that creates missing fixtures Oct 14, 2020 4 - Beta pytest (>=3.5.0) - :pypi:`pytest-mitmproxy` pytest plugin for mitmproxy tests Mar 07, 2024 N/A pytest >=7.0 + :pypi:`pytest-mitmproxy` pytest plugin for mitmproxy tests May 28, 2024 N/A pytest>=7.0 :pypi:`pytest-ml` Test your machine learning! May 04, 2019 4 - Beta N/A :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 Mar 21, 2024 5 - Production/Stable pytest>=6.2.5 @@ -836,7 +843,6 @@ This list contains 1461 plugins. :pypi:`pytest-modalt` Massively distributed pytest runs using modal.com Feb 27, 2024 4 - Beta pytest >=6.2.0 :pypi:`pytest-modified-env` Pytest plugin to fail a test if it leaves modified \`os.environ\` afterwards. Jan 29, 2022 4 - Beta N/A :pypi:`pytest-modifyjunit` Utility for adding additional properties to junit xml for IDM QE Jan 10, 2019 N/A N/A - :pypi:`pytest-modifyscope` pytest plugin to modify fixture scope Apr 12, 2020 N/A pytest :pypi:`pytest-molecule` PyTest Molecule Plugin :: discover and run molecule tests Mar 29, 2022 5 - Production/Stable pytest (>=7.0.0) :pypi:`pytest-molecule-JC` PyTest Molecule Plugin :: discover and run molecule tests Jul 18, 2023 5 - Production/Stable pytest (>=7.0.0) :pypi:`pytest-mongo` MongoDB process and client fixtures plugin for Pytest. Mar 13, 2024 5 - Production/Stable pytest >=6.2 @@ -864,7 +870,7 @@ This list contains 1461 plugins. :pypi:`pytest-mypy-plugins-shim` Substitute for "pytest-mypy-plugins" for Python implementations which aren't supported by mypy. Apr 12, 2021 N/A pytest>=6.0.0 :pypi:`pytest-mypy-runner` Run the mypy static type checker as a pytest test case Apr 23, 2024 N/A pytest>=8.0 :pypi:`pytest-mypy-testing` Pytest plugin to check mypy output. Mar 04, 2024 N/A pytest>=7,<9 - :pypi:`pytest-mysql` MySQL process and client fixtures for pytest Oct 30, 2023 5 - Production/Stable pytest >=6.2 + :pypi:`pytest-mysql` MySQL process and client fixtures for pytest May 23, 2024 5 - Production/Stable pytest>=6.2 :pypi:`pytest-ndb` pytest notebook debugger Apr 28, 2024 N/A pytest :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) @@ -877,7 +883,7 @@ This list contains 1461 plugins. :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 May 17, 2024 N/A pytest<9.0.0,>=8.2.0 + :pypi:`pytest-nhsd-apim` Pytest plugin accessing NHSDigital's APIM proxies May 20, 2024 N/A pytest<9.0.0,>=8.2.0 :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 Apr 11, 2024 N/A N/A @@ -904,7 +910,7 @@ This list contains 1461 plugins. :pypi:`pytest-offline` Mar 09, 2023 1 - Planning pytest (>=7.0.0,<8.0.0) :pypi:`pytest-ogsm-plugin` 针对特定项目定制化插件,优化了pytest报告展示方式,并添加了项目所需特定参数 May 16, 2023 N/A 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 Mar 09, 2024 5 - Production/Stable pytest (<7.1) ; python_full_version <= "3.6.0" + :pypi:`pytest-only` Use @pytest.mark.only to run a single test May 27, 2024 5 - Production/Stable pytest<9,>=3.6.0 :pypi:`pytest-oof` A Pytest plugin providing structured, programmatic access to a test run's results Dec 11, 2023 4 - Beta 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) @@ -929,7 +935,6 @@ This list contains 1461 plugins. :pypi:`pytest-parallelize-tests` pytest plugin that parallelizes test execution across multiple hosts Jan 27, 2023 4 - Beta N/A :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-parameterize-from-files` A pytest plugin that parameterizes tests from data files. Feb 15, 2024 4 - Beta pytest>=7.2.0 :pypi:`pytest-parametrization` Simpler PyTest parametrization May 22, 2022 5 - Production/Stable N/A :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 decorator for parametrizing tests with default iterables. Nov 03, 2023 5 - Production/Stable pytest @@ -949,12 +954,12 @@ This list contains 1461 plugins. :pypi:`pytest-pep8` pytest plugin to check PEP8 requirements Apr 27, 2014 N/A N/A :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-percents` Mar 16, 2024 N/A N/A - :pypi:`pytest-perf` Run performance tests against the mainline code. Jan 28, 2024 5 - Production/Stable pytest >=6 ; extra == 'testing' + :pypi:`pytest-perf` Run performance tests against the mainline code. May 20, 2024 5 - Production/Stable pytest!=8.1.*,>=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-performancetotal` A performance plugin for pytest Mar 19, 2024 4 - Beta N/A - :pypi:`pytest-persistence` Pytest tool for persistent objects Jul 04, 2023 N/A N/A + :pypi:`pytest-persistence` Pytest tool for persistent objects May 23, 2024 N/A N/A :pypi:`pytest-pexpect` Pytest pexpect plugin. Mar 27, 2024 4 - Beta pytest>=6.2.0 - :pypi:`pytest-pg` A tiny plugin for pytest which runs PostgreSQL in Docker Apr 03, 2024 5 - Production/Stable pytest>=6.0.0 + :pypi:`pytest-pg` A tiny plugin for pytest which runs PostgreSQL in Docker May 21, 2024 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. Apr 15, 2022 4 - Beta pytest (>=5.4.3) :pypi:`pytest-picked` Run the tests related to the changed files Jul 27, 2023 N/A pytest (>=3.7.0) @@ -971,7 +976,7 @@ This list contains 1461 plugins. :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 May 06, 2024 N/A N/A - :pypi:`pytest_playwright_async` ASYNC Pytest plugin for Playwright May 04, 2024 N/A N/A + :pypi:`pytest_playwright_async` ASYNC Pytest plugin for Playwright May 24, 2024 N/A N/A :pypi:`pytest-playwright-asyncio` Aug 29, 2023 N/A N/A :pypi:`pytest-playwright-enhanced` A pytest plugin for playwright python Mar 24, 2024 N/A pytest<9.0.0,>=8.0.0 :pypi:`pytest-playwrights` A pytest wrapper with fixtures for Playwright to automate web browsers Dec 02, 2021 N/A N/A @@ -982,7 +987,7 @@ This list contains 1461 plugins. :pypi:`pytest-plugin-helpers` A plugin to help developing and testing other plugins Nov 23, 2019 4 - Beta pytest (>=3.5.0) :pypi:`pytest-plus` PyTest Plus Plugin :: extends pytest functionality Mar 26, 2024 5 - Production/Stable pytest>=7.4.2 :pypi:`pytest-pmisc` Mar 21, 2019 5 - Production/Stable N/A - :pypi:`pytest-pogo` Pytest plugin for pogo-migrate Mar 11, 2024 1 - Planning pytest (>=7,<9) + :pypi:`pytest-pogo` Pytest plugin for pogo-migrate May 22, 2024 1 - Planning pytest<9,>=7 :pypi:`pytest-pointers` Pytest plugin to define functions you test with special marks for better navigation and reports Dec 26, 2022 N/A N/A :pypi:`pytest-pokie` Pokie plugin for pytest Oct 19, 2023 5 - Production/Stable N/A :pypi:`pytest-polarion-cfme` pytest plugin for collecting test cases and recording test results Nov 13, 2017 3 - Alpha N/A @@ -1017,6 +1022,7 @@ This list contains 1461 plugins. :pypi:`pytest-psqlgraph` pytest plugin for testing applications that use psqlgraph Oct 19, 2021 4 - Beta pytest (>=6.0) :pypi:`pytest-pt` pytest plugin to use \*.pt files as tests May 15, 2024 4 - Beta pytest :pypi:`pytest-ptera` Use ptera probes in tests Mar 01, 2022 N/A pytest (>=6.2.4,<7.0.0) + :pypi:`pytest-publish` Jun 01, 2024 N/A pytest<9.0.0,>=8.0.0 :pypi:`pytest-pudb` Pytest PuDB debugger integration Oct 25, 2018 3 - Alpha pytest (>=2.0) :pypi:`pytest-pumpkin-spice` A pytest plugin that makes your test reporting pumpkin-spiced Sep 18, 2022 4 - Beta N/A :pypi:`pytest-purkinje` py.test plugin for purkinje test runner Oct 28, 2017 2 - Pre-Alpha N/A @@ -1046,7 +1052,8 @@ This list contains 1461 plugins. :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-pyvenv` A package for create venv in tests Feb 27, 2024 N/A pytest ; extra == 'test' :pypi:`pytest-pyvista` Pytest-pyvista package Sep 29, 2023 4 - Beta pytest>=3.5.0 - :pypi:`pytest-qaseio` Pytest plugin for Qase.io integration Sep 12, 2023 4 - Beta pytest (>=7.2.2,<8.0.0) + :pypi:`pytest-qanova` A pytest plugin to collect test information May 26, 2024 3 - Alpha pytest + :pypi:`pytest-qaseio` Pytest plugin for Qase.io integration May 30, 2024 4 - Beta pytest<9.0.0,>=7.2.2 :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. Feb 14, 2023 4 - Beta pytest (>=6.2.0) :pypi:`pytest-qgis` A pytest plugin for testing QGIS python plugins Nov 29, 2023 5 - Production/Stable pytest >=6.0 @@ -1119,7 +1126,7 @@ This list contains 1461 plugins. :pypi:`pytest-rerunclassfailures` pytest rerun class failures plugin Apr 24, 2024 5 - Production/Stable pytest>=7.2 :pypi:`pytest-rerunfailures` pytest plugin to re-run tests to eliminate flaky failures Mar 13, 2024 5 - Production/Stable pytest >=7.2 :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-reserial` Pytest fixture for recording and replaying serial port traffic. Feb 08, 2024 4 - Beta pytest + :pypi:`pytest-reserial` Pytest fixture for recording and replaying serial port traffic. May 23, 2024 4 - Beta pytest :pypi:`pytest-resilient-circuits` Resilient Circuits fixtures for PyTest May 17, 2024 N/A pytest~=4.6; python_version == "2.7" :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) @@ -1144,7 +1151,7 @@ This list contains 1461 plugins. :pypi:`pytest-rmsis` Sycronise pytest results to Jira RMsis Aug 10, 2022 N/A pytest (>=5.3.5) :pypi:`pytest-rng` Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest :pypi:`pytest-roast` pytest plugin for ROAST configuration override and fixtures Nov 09, 2022 5 - Production/Stable pytest - :pypi:`pytest_robotframework` a pytest plugin that can run both python and robotframework tests while generating robot reports for them May 18, 2024 N/A pytest<9,>=7 + :pypi:`pytest_robotframework` a pytest plugin that can run both python and robotframework tests while generating robot reports for them May 29, 2024 N/A pytest<9,>=7 :pypi:`pytest-rocketchat` Pytest to Rocket.Chat reporting plugin Apr 18, 2021 5 - Production/Stable N/A :pypi:`pytest-rotest` Pytest integration with rotest Sep 08, 2019 N/A pytest (>=3.5.0) :pypi:`pytest-rpc` Extend py.test for RPC OpenStack testing. Feb 22, 2019 4 - Beta pytest (~=3.6) @@ -1171,6 +1178,7 @@ This list contains 1461 plugins. :pypi:`pytest_sauce` pytest_sauce provides sane and helpful methods worked out in clearcode to run py.test tests with selenium/saucelabs Jul 14, 2014 3 - Alpha N/A :pypi:`pytest-sbase` A complete web automation framework for end-to-end testing. May 16, 2024 5 - Production/Stable N/A :pypi:`pytest-scenario` pytest plugin for test scenarios Feb 06, 2017 3 - Alpha N/A + :pypi:`pytest-scenario-files` A pytest plugin that generates unit test scenarios from data files. May 19, 2024 5 - Production/Stable pytest>=7.2.0 :pypi:`pytest-schedule` The job of test scheduling for humans. Jan 07, 2023 5 - Production/Stable N/A :pypi:`pytest-schema` 👍 Validate return values against a schema-like object in testing Feb 16, 2024 5 - Production/Stable pytest >=3.5.0 :pypi:`pytest-screenshot-on-failure` Saves a screenshot when a test case from a pytest execution fails Jul 21, 2023 4 - Beta N/A @@ -1255,12 +1263,12 @@ This list contains 1461 plugins. :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 May 16, 2024 N/A pytest<8,>5.4.0 + :pypi:`pytest-splunk-addon` A Dynamic test tool for Splunk Apps and Add-ons May 27, 2024 N/A pytest<8,>5.4.0 :pypi:`pytest-splunk-addon-ui-smartx` Library to support testing Splunk Add-on UX May 10, 2024 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-sqlalchemy-mock` pytest sqlalchemy plugin for mock Mar 15, 2023 3 - Alpha pytest (>=2.0) + :pypi:`pytest-sqlalchemy-mock` pytest sqlalchemy plugin for mock May 21, 2024 3 - Alpha pytest>=7.0.0 :pypi:`pytest-sqlalchemy-session` A pytest plugin for preserving test isolation that use SQLAlchemy. May 19, 2023 4 - Beta pytest (>=7.0) :pypi:`pytest-sql-bigquery` Yet another SQL-testing framework for BigQuery provided by pytest plugin Dec 19, 2019 N/A pytest :pypi:`pytest-sqlfluff` A pytest plugin to use sqlfluff to enable format checking of sql files. Dec 21, 2022 4 - Beta pytest (>=3.5.0) @@ -1278,7 +1286,7 @@ This list contains 1461 plugins. :pypi:`pytest-stoq` A plugin to pytest stoq Feb 09, 2021 4 - Beta N/A :pypi:`pytest-store` Pytest plugin to store values from test runs Nov 16, 2023 3 - Alpha pytest (>=7.0.0) :pypi:`pytest-stress` A Pytest plugin that allows you to loop tests for a user defined amount of time. Dec 07, 2019 4 - Beta pytest (>=3.6.0) - :pypi:`pytest-structlog` Structured logging assertions Mar 13, 2024 N/A pytest + :pypi:`pytest-structlog` Structured logging assertions May 30, 2024 N/A pytest :pypi:`pytest-structmpd` provide structured temporary directory Oct 17, 2018 N/A N/A :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) @@ -1312,7 +1320,7 @@ This list contains 1461 plugins. :pypi:`pytest-telegram-notifier` Telegram notification plugin for Pytest Jun 27, 2023 5 - Production/Stable N/A :pypi:`pytest-tempdir` Predictable and repeatable tempdir support. Oct 11, 2019 4 - Beta pytest (>=2.8.1) :pypi:`pytest-terra-fixt` Terraform and Terragrunt fixtures for pytest Sep 15, 2022 N/A pytest (==6.2.5) - :pypi:`pytest-terraform` A pytest plugin for using terraform fixtures Jun 20, 2023 N/A pytest (>=6.0) + :pypi:`pytest-terraform` A pytest plugin for using terraform fixtures May 21, 2024 N/A pytest>=6.0 :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) @@ -1320,7 +1328,7 @@ This list contains 1461 plugins. :pypi:`pytest-testdox` A testdox format reporter for pytest Jul 22, 2023 5 - Production/Stable pytest (>=4.6.0) :pypi:`pytest-test-grouping` A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Feb 01, 2023 5 - Production/Stable pytest (>=2.5) :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 Feb 15, 2024 5 - Production/Stable pytest >=6 + :pypi:`pytest-testinfra` Test infrastructures May 26, 2024 5 - Production/Stable pytest>=6 :pypi:`pytest-testinfra-jpic` Test infrastructures Sep 21, 2023 5 - Production/Stable N/A :pypi:`pytest-testinfra-winrm-transport` Test infrastructures Sep 21, 2023 5 - Production/Stable N/A :pypi:`pytest-testlink-adaptor` pytest reporting plugin for testlink Dec 20, 2018 4 - Beta pytest (>=2.6) @@ -1349,6 +1357,7 @@ This list contains 1461 plugins. :pypi:`pytest-tesults` Tesults plugin for pytest Feb 15, 2024 5 - Production/Stable pytest >=3.5.0 :pypi:`pytest-textual-snapshot` Snapshot testing for Textual apps Aug 23, 2023 4 - Beta pytest (>=7.0.0) :pypi:`pytest-tezos` pytest-ligo Jan 16, 2020 4 - Beta N/A + :pypi:`pytest-tf` Test your OpenTofu and Terraform config using a PyTest plugin May 29, 2024 N/A pytest<9.0.0,>=8.2.1 :pypi:`pytest-th2-bdd` pytest_th2_bdd May 13, 2022 N/A N/A :pypi:`pytest-thawgun` Pytest plugin for time travel May 26, 2020 3 - Alpha N/A :pypi:`pytest-thread` Jul 07, 2023 N/A N/A @@ -1450,7 +1459,7 @@ This list contains 1461 plugins. :pypi:`pytest-webdriver` Selenium webdriver fixture for py.test May 28, 2019 5 - Production/Stable pytest :pypi:`pytest-webtest-extras` Pytest plugin to enhance pytest-html and allure reports of webtest projects by adding screenshots, comments and webpage sources. Nov 13, 2023 N/A pytest >= 7.0.0 :pypi:`pytest-wetest` Welian API Automation test framework pytest plugin Nov 10, 2018 4 - Beta N/A - :pypi:`pytest-when` Utility which makes mocking more readable and controllable Mar 22, 2024 N/A pytest>=7.3.1 + :pypi:`pytest-when` Utility which makes mocking more readable and controllable May 28, 2024 N/A pytest>=7.3.1 :pypi:`pytest-whirlwind` Testing Tornado. Jun 12, 2020 N/A N/A :pypi:`pytest-wholenodeid` pytest addon for displaying the whole node id for failures Aug 26, 2015 4 - Beta pytest (>=2.0) :pypi:`pytest-win32consoletitle` Pytest progress in console title (Win32 only) Aug 08, 2021 N/A N/A @@ -1469,11 +1478,12 @@ This list contains 1461 plugins. :pypi:`pytest-xlog` Extended logging for test and decorators May 31, 2020 4 - Beta N/A :pypi:`pytest-xlsx` pytest plugin for generating test cases by xlsx(excel) Apr 23, 2024 N/A pytest~=7.0 :pypi:`pytest-xpara` An extended parametrizing plugin of pytest. Oct 30, 2017 3 - Alpha pytest - :pypi:`pytest-xprocess` A pytest plugin for managing processes across test runs. Mar 31, 2024 4 - Beta pytest>=2.8 + :pypi:`pytest-xprocess` A pytest plugin for managing processes across test runs. May 19, 2024 4 - Beta pytest>=2.8 :pypi:`pytest-xray` May 30, 2019 3 - Alpha N/A :pypi:`pytest-xrayjira` Mar 17, 2020 3 - Alpha pytest (==4.3.1) :pypi:`pytest-xray-server` May 03, 2022 3 - Alpha pytest (>=5.3.1) :pypi:`pytest-xskynet` A package to prevent Dependency Confusion attacks against Yandex. Feb 20, 2024 N/A N/A + :pypi:`pytest-xstress` Jun 01, 2024 N/A pytest<9.0.0,>=8.0.0 :pypi:`pytest-xvfb` A pytest plugin to run Xvfb (or Xephyr/Xvnc) for tests. May 29, 2023 4 - Beta pytest (>=2.8.1) :pypi:`pytest-xvirt` A pytest plugin to virtualize test. For example to transparently running them on a remote box. Oct 01, 2023 4 - Beta pytest >=7.1.0 :pypi:`pytest-yaml` This plugin is used to load yaml output to your test using pytest framework. Oct 05, 2018 N/A pytest @@ -1515,9 +1525,9 @@ This list contains 1461 plugins. Test whether your code is logging correctly 🪵 :pypi:`nuts` - *last release*: Aug 11, 2023, + *last release*: May 28, 2024, *status*: N/A, - *requires*: pytest (>=7.3.0,<8.0.0) + *requires*: pytest<8,>=7 Network Unit Testing System @@ -2026,9 +2036,9 @@ This list contains 1461 plugins. Pytest fixtures for async generators :pypi:`pytest-asyncio` - *last release*: Mar 19, 2024, + *last release*: May 19, 2024, *status*: 4 - Beta, - *requires*: pytest <9,>=7.0.0 + *requires*: pytest<9,>=7.0.0 Pytest support for asyncio @@ -2130,6 +2140,13 @@ This list contains 1461 plugins. This fixture provides a configured "driver" for Android Automated Testing, using uiautomator2. + :pypi:`pytest-aux` + *last release*: May 31, 2024, + *status*: N/A, + *requires*: N/A + + templates/examples and aux for pytest + :pypi:`pytest-aviator` *last release*: Nov 04, 2022, *status*: 4 - Beta, @@ -2152,7 +2169,7 @@ This list contains 1461 plugins. pytest plugin for testing AWS resource configurations :pypi:`pytest-aws-apigateway` - *last release*: May 18, 2024, + *last release*: May 24, 2024, *status*: 4 - Beta, *requires*: pytest @@ -2257,7 +2274,7 @@ This list contains 1461 plugins. BDD for pytest :pypi:`pytest-bdd-report` - *last release*: Feb 19, 2024, + *last release*: May 20, 2024, *status*: N/A, *requires*: pytest >=7.1.3 @@ -2299,7 +2316,7 @@ This list contains 1461 plugins. Pytest plugin to run your tests with beartype checking enabled. :pypi:`pytest-bec-e2e` - *last release*: May 17, 2024, + *last release*: May 31, 2024, *status*: 3 - Alpha, *requires*: pytest @@ -2459,6 +2476,13 @@ This list contains 1461 plugins. + :pypi:`pytest-boto-mock` + *last release*: May 27, 2024, + *status*: 5 - Production/Stable, + *requires*: pytest>=8.2.0 + + Thin-wrapper around the mock package for easier use with pytest + :pypi:`pytest-bpdb` *last release*: Jan 19, 2015, *status*: 2 - Pre-Alpha, @@ -2894,7 +2918,7 @@ This list contains 1461 plugins. Easy quality control for CLDF datasets using pytest :pypi:`pytest-cleanslate` - *last release*: May 15, 2024, + *last release*: May 30, 2024, *status*: N/A, *requires*: pytest @@ -2964,7 +2988,7 @@ This list contains 1461 plugins. Distribute tests to cloud machines without fuss :pypi:`pytest-cmake` - *last release*: May 12, 2024, + *last release*: May 31, 2024, *status*: N/A, *requires*: pytest<9,>=4 @@ -3068,6 +3092,13 @@ This list contains 1461 plugins. Get executed interface information in pytest interface automation framework + :pypi:`pytest-collect-jmeter-report-tests` + *last release*: May 20, 2024, + *status*: 4 - Beta, + *requires*: pytest>=7.2.1 + + A simple plugin to use with pytest + :pypi:`pytest-collector` *last release*: Aug 02, 2022, *status*: N/A, @@ -3369,6 +3400,13 @@ This list contains 1461 plugins. Custom grouping for pytest-xdist, rename test cases name and test cases nodeid, support allure report + :pypi:`pytest-custom-outputs` + *last release*: May 30, 2024, + *status*: 4 - Beta, + *requires*: pytest>=6.2.0 + + A plugin that allows users to create and use custom outputs instead of the standard Pass and Fail + :pypi:`pytest-custom-report` *last release*: Jan 30, 2019, *status*: N/A, @@ -3412,7 +3450,7 @@ This list contains 1461 plugins. pytest fixtures to run dash applications. :pypi:`pytest-dashboard` - *last release*: Apr 22, 2024, + *last release*: May 30, 2024, *status*: N/A, *requires*: pytest<8.0.0,>=7.4.3 @@ -3426,7 +3464,7 @@ This list contains 1461 plugins. Useful functions for managing data for pytest fixtures :pypi:`pytest-databases` - *last release*: Apr 21, 2024, + *last release*: May 25, 2024, *status*: 4 - Beta, *requires*: pytest @@ -3790,12 +3828,19 @@ This list contains 1461 plugins. Pytest plugin to record discovered tests in a file :pypi:`pytest-ditto` - *last release*: May 07, 2024, + *last release*: May 29, 2024, *status*: 4 - Beta, *requires*: pytest>=3.5.0 Snapshot testing pytest plugin with minimal ceremony and flexible persistence formats. + :pypi:`pytest-ditto-pandas` + *last release*: May 29, 2024, + *status*: 4 - Beta, + *requires*: pytest>=3.5.0 + + pytest-ditto plugin for pandas snapshots. + :pypi:`pytest-django` *last release*: Jan 30, 2024, *status*: 5 - Production/Stable, @@ -3839,9 +3884,9 @@ This list contains 1461 plugins. A pytest plugin for running django in class-scoped fixtures :pypi:`pytest-django-docker-pg` - *last release*: Jan 30, 2024, + *last release*: May 21, 2024, *status*: 5 - Production/Stable, - *requires*: pytest <8.0.0,>=7.0.0 + *requires*: pytest<9.0.0,>=7.0.0 @@ -4364,56 +4409,56 @@ This list contains 1461 plugins. Send execution result email :pypi:`pytest-embedded` - *last release*: Apr 30, 2024, + *last release*: May 31, 2024, *status*: 5 - Production/Stable, *requires*: pytest>=7.0 A pytest plugin that designed for embedded testing. :pypi:`pytest-embedded-arduino` - *last release*: Apr 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with Arduino. :pypi:`pytest-embedded-idf` - *last release*: Apr 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with ESP-IDF. :pypi:`pytest-embedded-jtag` - *last release*: Apr 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with JTAG. :pypi:`pytest-embedded-qemu` - *last release*: Apr 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with QEMU. :pypi:`pytest-embedded-serial` - *last release*: Apr 30, 2024, + *last release*: May 31, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with Serial. :pypi:`pytest-embedded-serial-esp` - *last release*: Apr 30, 2024, + *last release*: May 31, 2024, *status*: 5 - Production/Stable, *requires*: N/A Make pytest-embedded plugin work with Espressif target boards. :pypi:`pytest-embedded-wokwi` - *last release*: Apr 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, *requires*: N/A @@ -4615,6 +4660,13 @@ This list contains 1461 plugins. + :pypi:`pytest-exasol-saas` + *last release*: May 27, 2024, + *status*: N/A, + *requires*: pytest<9,>=7 + + + :pypi:`pytest-excel` *last release*: Sep 14, 2023, *status*: 5 - Production/Stable, @@ -4896,7 +4948,7 @@ This list contains 1461 plugins. py.test plugin that activates the fault handler module for tests (dummy package) :pypi:`pytest-fauna` - *last release*: Apr 22, 2024, + *last release*: May 30, 2024, *status*: N/A, *requires*: N/A @@ -5567,13 +5619,6 @@ This list contains 1461 plugins. Store data created during your pytest tests execution, and retrieve it at the end of the session, e.g. for applicative benchmarking purposes. - :pypi:`pytest-helm-chart` - *last release*: Jun 15, 2020, - *status*: 4 - Beta, - *requires*: pytest (>=5.4.2,<6.0.0) - - A plugin to provide different types and configs of Kubernetes clusters that can be used for testing. - :pypi:`pytest-helm-charts` *last release*: Feb 07, 2024, *status*: 4 - Beta, @@ -5666,9 +5711,9 @@ This list contains 1461 plugins. A pytest plugin for use with homeassistant custom components. :pypi:`pytest-homeassistant-custom-component` - *last release*: May 18, 2024, + *last release*: May 31, 2024, *status*: 3 - Alpha, - *requires*: pytest==8.1.1 + *requires*: pytest==8.2.0 Experimental package to automatically extract test plugins for Home Assistant custom components @@ -5778,7 +5823,7 @@ This list contains 1461 plugins. Generates a static html report based on pytest framework :pypi:`pytest-html-report-merger` - *last release*: Oct 23, 2023, + *last release*: May 22, 2024, *status*: N/A, *requires*: N/A @@ -6023,7 +6068,7 @@ This list contains 1461 plugins. A py.test plugin providing fixtures to simplify inmanta modules testing. :pypi:`pytest-inmanta-extensions` - *last release*: Apr 02, 2024, + *last release*: May 24, 2024, *status*: 5 - Production/Stable, *requires*: N/A @@ -6274,6 +6319,13 @@ This list contains 1461 plugins. Generate JSON test reports + :pypi:`pytest-json-ctrf` + *last release*: May 21, 2024, + *status*: N/A, + *requires*: pytest>6.0.0 + + Pytest plugin to generate json report in CTRF (Common Test Report Format) + :pypi:`pytest-json-fixtures` *last release*: Mar 14, 2023, *status*: 4 - Beta, @@ -6309,6 +6361,13 @@ This list contains 1461 plugins. A pytest plugin to perform JSONSchema validations + :pypi:`pytest-jtl-collector` + *last release*: May 20, 2024, + *status*: 4 - Beta, + *requires*: pytest>=7.2.1 + + A simple plugin to use with pytest + :pypi:`pytest-jtr` *last release*: Apr 15, 2024, *status*: N/A, @@ -6443,9 +6502,9 @@ This list contains 1461 plugins. Alternate syntax for @pytest.mark.parametrize with test cases as dictionaries and default value fallbacks :pypi:`pytest-lambda` - *last release*: Aug 20, 2022, - *status*: 3 - Alpha, - *requires*: pytest (>=3.6,<8) + *last release*: May 27, 2024, + *status*: 5 - Production/Stable, + *requires*: pytest<9,>=3.6 Define pytest fixtures with lambda functions. @@ -6625,7 +6684,7 @@ This list contains 1461 plugins. Generate local badges (shields) reporting your test suite status. :pypi:`pytest-localftpserver` - *last release*: May 17, 2024, + *last release*: May 19, 2024, *status*: 5 - Production/Stable, *requires*: pytest @@ -6716,9 +6775,9 @@ This list contains 1461 plugins. :pypi:`pytest-logikal` - *last release*: Mar 30, 2024, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, - *requires*: pytest==8.1.1 + *requires*: pytest==8.2.1 Common testing environment @@ -6744,7 +6803,7 @@ This list contains 1461 plugins. pytest plugin for looping tests :pypi:`pytest-lsp` - *last release*: Feb 07, 2024, + *last release*: May 22, 2024, *status*: 3 - Alpha, *requires*: pytest @@ -6961,7 +7020,7 @@ This list contains 1461 plugins. Custom metrics report for pytest :pypi:`pytest-mh` - *last release*: Mar 14, 2024, + *last release*: May 28, 2024, *status*: N/A, *requires*: pytest @@ -6989,7 +7048,7 @@ This list contains 1461 plugins. A plugin to test mp :pypi:`pytest-minio-mock` - *last release*: Apr 27, 2024, + *last release*: May 26, 2024, *status*: N/A, *requires*: pytest>=5.0.0 @@ -7003,9 +7062,9 @@ This list contains 1461 plugins. Pytest plugin that creates missing fixtures :pypi:`pytest-mitmproxy` - *last release*: Mar 07, 2024, + *last release*: May 28, 2024, *status*: N/A, - *requires*: pytest >=7.0 + *requires*: pytest>=7.0 pytest plugin for mitmproxy tests @@ -7114,13 +7173,6 @@ This list contains 1461 plugins. Utility for adding additional properties to junit xml for IDM QE - :pypi:`pytest-modifyscope` - *last release*: Apr 12, 2020, - *status*: N/A, - *requires*: pytest - - pytest plugin to modify fixture scope - :pypi:`pytest-molecule` *last release*: Mar 29, 2022, *status*: 5 - Production/Stable, @@ -7311,9 +7363,9 @@ This list contains 1461 plugins. Pytest plugin to check mypy output. :pypi:`pytest-mysql` - *last release*: Oct 30, 2023, + *last release*: May 23, 2024, *status*: 5 - Production/Stable, - *requires*: pytest >=6.2 + *requires*: pytest>=6.2 MySQL process and client fixtures for pytest @@ -7402,7 +7454,7 @@ This list contains 1461 plugins. pytest ngs fixtures :pypi:`pytest-nhsd-apim` - *last release*: May 17, 2024, + *last release*: May 20, 2024, *status*: N/A, *requires*: pytest<9.0.0,>=8.2.0 @@ -7591,9 +7643,9 @@ This list contains 1461 plugins. The ultimate pytest output plugin :pypi:`pytest-only` - *last release*: Mar 09, 2024, + *last release*: May 27, 2024, *status*: 5 - Production/Stable, - *requires*: pytest (<7.1) ; python_full_version <= "3.6.0" + *requires*: pytest<9,>=3.6.0 Use @pytest.mark.only to run a single test @@ -7765,13 +7817,6 @@ This list contains 1461 plugins. Configure pytest fixtures using a combination of"parametrize" and markers - :pypi:`pytest-parameterize-from-files` - *last release*: Feb 15, 2024, - *status*: 4 - Beta, - *requires*: pytest>=7.2.0 - - A pytest plugin that parameterizes tests from data files. - :pypi:`pytest-parametrization` *last release*: May 22, 2022, *status*: 5 - Production/Stable, @@ -7906,9 +7951,9 @@ This list contains 1461 plugins. :pypi:`pytest-perf` - *last release*: Jan 28, 2024, + *last release*: May 20, 2024, *status*: 5 - Production/Stable, - *requires*: pytest >=6 ; extra == 'testing' + *requires*: pytest!=8.1.*,>=6; extra == "testing" Run performance tests against the mainline code. @@ -7927,7 +7972,7 @@ This list contains 1461 plugins. A performance plugin for pytest :pypi:`pytest-persistence` - *last release*: Jul 04, 2023, + *last release*: May 23, 2024, *status*: N/A, *requires*: N/A @@ -7941,7 +7986,7 @@ This list contains 1461 plugins. Pytest pexpect plugin. :pypi:`pytest-pg` - *last release*: Apr 03, 2024, + *last release*: May 21, 2024, *status*: 5 - Production/Stable, *requires*: pytest>=6.0.0 @@ -8060,7 +8105,7 @@ This list contains 1461 plugins. A pytest wrapper with fixtures for Playwright to automate web browsers :pypi:`pytest_playwright_async` - *last release*: May 04, 2024, + *last release*: May 24, 2024, *status*: N/A, *requires*: N/A @@ -8137,9 +8182,9 @@ This list contains 1461 plugins. :pypi:`pytest-pogo` - *last release*: Mar 11, 2024, + *last release*: May 22, 2024, *status*: 1 - Planning, - *requires*: pytest (>=7,<9) + *requires*: pytest<9,>=7 Pytest plugin for pogo-migrate @@ -8381,6 +8426,13 @@ This list contains 1461 plugins. Use ptera probes in tests + :pypi:`pytest-publish` + *last release*: Jun 01, 2024, + *status*: N/A, + *requires*: pytest<9.0.0,>=8.0.0 + + + :pypi:`pytest-pudb` *last release*: Oct 25, 2018, *status*: 3 - Alpha, @@ -8584,10 +8636,17 @@ This list contains 1461 plugins. Pytest-pyvista package + :pypi:`pytest-qanova` + *last release*: May 26, 2024, + *status*: 3 - Alpha, + *requires*: pytest + + A pytest plugin to collect test information + :pypi:`pytest-qaseio` - *last release*: Sep 12, 2023, + *last release*: May 30, 2024, *status*: 4 - Beta, - *requires*: pytest (>=7.2.2,<8.0.0) + *requires*: pytest<9.0.0,>=7.2.2 Pytest plugin for Qase.io integration @@ -9096,7 +9155,7 @@ This list contains 1461 plugins. pytest plugin to re-run tests to eliminate flaky failures :pypi:`pytest-reserial` - *last release*: Feb 08, 2024, + *last release*: May 23, 2024, *status*: 4 - Beta, *requires*: pytest @@ -9271,7 +9330,7 @@ This list contains 1461 plugins. pytest plugin for ROAST configuration override and fixtures :pypi:`pytest_robotframework` - *last release*: May 18, 2024, + *last release*: May 29, 2024, *status*: N/A, *requires*: pytest<9,>=7 @@ -9459,6 +9518,13 @@ This list contains 1461 plugins. pytest plugin for test scenarios + :pypi:`pytest-scenario-files` + *last release*: May 19, 2024, + *status*: 5 - Production/Stable, + *requires*: pytest>=7.2.0 + + A pytest plugin that generates unit test scenarios from data files. + :pypi:`pytest-schedule` *last release*: Jan 07, 2023, *status*: 5 - Production/Stable, @@ -10048,7 +10114,7 @@ This list contains 1461 plugins. :pypi:`pytest-splunk-addon` - *last release*: May 16, 2024, + *last release*: May 27, 2024, *status*: N/A, *requires*: pytest<8,>5.4.0 @@ -10083,9 +10149,9 @@ This list contains 1461 plugins. pytest plugin with sqlalchemy related fixtures :pypi:`pytest-sqlalchemy-mock` - *last release*: Mar 15, 2023, + *last release*: May 21, 2024, *status*: 3 - Alpha, - *requires*: pytest (>=2.0) + *requires*: pytest>=7.0.0 pytest sqlalchemy plugin for mock @@ -10209,7 +10275,7 @@ This list contains 1461 plugins. A Pytest plugin that allows you to loop tests for a user defined amount of time. :pypi:`pytest-structlog` - *last release*: Mar 13, 2024, + *last release*: May 30, 2024, *status*: N/A, *requires*: pytest @@ -10447,9 +10513,9 @@ This list contains 1461 plugins. Terraform and Terragrunt fixtures for pytest :pypi:`pytest-terraform` - *last release*: Jun 20, 2023, + *last release*: May 21, 2024, *status*: N/A, - *requires*: pytest (>=6.0) + *requires*: pytest>=6.0 A pytest plugin for using terraform fixtures @@ -10503,9 +10569,9 @@ This list contains 1461 plugins. A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. :pypi:`pytest-testinfra` - *last release*: Feb 15, 2024, + *last release*: May 26, 2024, *status*: 5 - Production/Stable, - *requires*: pytest >=6 + *requires*: pytest>=6 Test infrastructures @@ -10705,6 +10771,13 @@ This list contains 1461 plugins. pytest-ligo + :pypi:`pytest-tf` + *last release*: May 29, 2024, + *status*: N/A, + *requires*: pytest<9.0.0,>=8.2.1 + + Test your OpenTofu and Terraform config using a PyTest plugin + :pypi:`pytest-th2-bdd` *last release*: May 13, 2022, *status*: N/A, @@ -11413,7 +11486,7 @@ This list contains 1461 plugins. Welian API Automation test framework pytest plugin :pypi:`pytest-when` - *last release*: Mar 22, 2024, + *last release*: May 28, 2024, *status*: N/A, *requires*: pytest>=7.3.1 @@ -11546,7 +11619,7 @@ This list contains 1461 plugins. An extended parametrizing plugin of pytest. :pypi:`pytest-xprocess` - *last release*: Mar 31, 2024, + *last release*: May 19, 2024, *status*: 4 - Beta, *requires*: pytest>=2.8 @@ -11580,6 +11653,13 @@ This list contains 1461 plugins. A package to prevent Dependency Confusion attacks against Yandex. + :pypi:`pytest-xstress` + *last release*: Jun 01, 2024, + *status*: N/A, + *requires*: pytest<9.0.0,>=8.0.0 + + + :pypi:`pytest-xvfb` *last release*: May 29, 2023, *status*: 4 - Beta, diff --git a/extra/get_issues.py b/extra/get_issues.py index a0c2f19ad..64e859e0c 100644 --- a/extra/get_issues.py +++ b/extra/get_issues.py @@ -1,5 +1,6 @@ import json from pathlib import Path +import sys import requests @@ -17,7 +18,7 @@ def get_issues(): if r.status_code == 403: # API request limit exceeded print(data["message"]) - exit(1) + sys.exit(1) issues.extend(data) # Look for next page diff --git a/pyproject.toml b/pyproject.toml index e3c64b3e9..0627c94c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -181,28 +181,25 @@ disable = [ "bad-mcs-method-argument", "broad-exception-caught", "broad-exception-raised", - "cell-var-from-loop", + "cell-var-from-loop", # B023 from ruff / flake8-bugbear "comparison-of-constants", "comparison-with-callable", "comparison-with-itself", "condition-evals-to-constant", "consider-using-dict-items", - "consider-using-enumerate", "consider-using-from-import", "consider-using-f-string", "consider-using-in", - "consider-using-sys-exit", "consider-using-ternary", "consider-using-with", "cyclic-import", - "disallowed-name", + "disallowed-name", # foo / bar are used often in tests "duplicate-code", "eval-used", "exec-used", "expression-not-assigned", "fixme", "global-statement", - "implicit-str-concat", "import-error", "import-outside-toplevel", "inconsistent-return-statements", @@ -213,10 +210,9 @@ disable = [ "keyword-arg-before-vararg", "line-too-long", "method-hidden", - "misplaced-bare-raise", "missing-docstring", "missing-timeout", - "multiple-statements", + "multiple-statements", # multiple-statements-on-one-line-colon (E701) from ruff "no-else-break", "no-else-continue", "no-else-raise", @@ -229,6 +225,7 @@ disable = [ "pointless-exception-statement", "pointless-statement", "pointless-string-statement", + "possibly-used-before-assignment", "protected-access", "raise-missing-from", "redefined-argument-from-local", @@ -276,7 +273,6 @@ disable = [ "useless-else-on-loop", "useless-import-alias", "useless-return", - "use-maxsplit-arg", "using-constant-test", "wrong-import-order", ] diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index cfa226bb7..b6e06340d 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -55,7 +55,7 @@ from _pytest.pathlib import bestrelpath if sys.version_info < (3, 11): from exceptiongroup import BaseExceptionGroup -_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] +TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"] class Code: @@ -199,8 +199,8 @@ class TracebackEntry: rawentry: TracebackType, repr_style: Optional['Literal["short", "long"]'] = None, ) -> None: - self._rawentry: "Final" = rawentry - self._repr_style: "Final" = repr_style + self._rawentry: Final = rawentry + self._repr_style: Final = repr_style def with_repr_style( self, repr_style: Optional['Literal["short", "long"]'] @@ -628,13 +628,14 @@ class ExceptionInfo(Generic[E]): def getrepr( self, showlocals: bool = False, - style: _TracebackStyle = "long", + style: TracebackStyle = "long", abspath: bool = False, tbfilter: Union[ bool, Callable[["ExceptionInfo[BaseException]"], Traceback] ] = True, funcargs: bool = False, truncate_locals: bool = True, + truncate_args: bool = True, chain: bool = True, ) -> Union["ReprExceptionInfo", "ExceptionChainRepr"]: """Return str()able representation of this exception info. @@ -665,6 +666,9 @@ class ExceptionInfo(Generic[E]): :param bool truncate_locals: With ``showlocals==True``, make sure locals can be safely represented as strings. + :param bool truncate_args: + With ``showargs==True``, make sure args can be safely represented as strings. + :param bool chain: If chained exceptions in Python 3 should be shown. @@ -691,6 +695,7 @@ class ExceptionInfo(Generic[E]): tbfilter=tbfilter, funcargs=funcargs, truncate_locals=truncate_locals, + truncate_args=truncate_args, chain=chain, ) return fmt.repr_excinfo(self) @@ -804,11 +809,12 @@ class FormattedExcinfo: fail_marker: ClassVar = "E" showlocals: bool = False - style: _TracebackStyle = "long" + style: TracebackStyle = "long" abspath: bool = True tbfilter: Union[bool, Callable[[ExceptionInfo[BaseException]], Traceback]] = True funcargs: bool = False truncate_locals: bool = True + truncate_args: bool = True chain: bool = True astcache: Dict[Union[str, Path], ast.AST] = dataclasses.field( default_factory=dict, init=False, repr=False @@ -839,7 +845,11 @@ class FormattedExcinfo: if self.funcargs: args = [] for argname, argvalue in entry.frame.getargs(var=True): - args.append((argname, saferepr(argvalue))) + if self.truncate_args: + str_repr = saferepr(argvalue) + else: + str_repr = saferepr(argvalue, maxsize=None) + args.append((argname, str_repr)) return ReprFuncArgs(args) return None @@ -1164,7 +1174,7 @@ class ReprExceptionInfo(ExceptionRepr): class ReprTraceback(TerminalRepr): reprentries: Sequence[Union["ReprEntry", "ReprEntryNative"]] extraline: Optional[str] - style: _TracebackStyle + style: TracebackStyle entrysep: ClassVar = "_ " @@ -1198,7 +1208,7 @@ class ReprTracebackNative(ReprTraceback): class ReprEntryNative(TerminalRepr): lines: Sequence[str] - style: ClassVar[_TracebackStyle] = "native" + style: ClassVar[TracebackStyle] = "native" def toterminal(self, tw: TerminalWriter) -> None: tw.write("".join(self.lines)) @@ -1210,7 +1220,7 @@ class ReprEntry(TerminalRepr): reprfuncargs: Optional["ReprFuncArgs"] reprlocals: Optional["ReprLocals"] reprfileloc: Optional["ReprFileLocation"] - style: _TracebackStyle + style: TracebackStyle def _write_entry_lines(self, tw: TerminalWriter) -> None: """Write the source code portions of a list of traceback entries with syntax highlighting. diff --git a/src/_pytest/_py/path.py b/src/_pytest/_py/path.py index bcb05ac34..c7ab1182f 100644 --- a/src/_pytest/_py/path.py +++ b/src/_pytest/_py/path.py @@ -161,15 +161,13 @@ class Visitor: ) if not self.breadthfirst: for subdir in dirs: - for p in self.gen(subdir): - yield p + yield from self.gen(subdir) for p in self.optsort(entries): if self.fil is None or self.fil(p): yield p if self.breadthfirst: for subdir in dirs: - for p in self.gen(subdir): - yield p + yield from self.gen(subdir) class FNMatcher: diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 5aa8f4835..7e00135a4 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -4,6 +4,7 @@ # This plugin was not named "cache" to avoid conflicts with the external # pytest-cache version. import dataclasses +import errno import json import os from pathlib import Path @@ -227,14 +228,24 @@ class Cache: with open(path.joinpath("CACHEDIR.TAG"), "xb") as f: f.write(CACHEDIR_TAG_CONTENT) - path.rename(self._cachedir) - # Create a directory in place of the one we just moved so that `TemporaryDirectory`'s - # cleanup doesn't complain. - # - # TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10. See - # https://github.com/python/cpython/issues/74168. Note that passing delete=False would - # do the wrong thing in case of errors and isn't supported until python 3.12. - path.mkdir() + try: + path.rename(self._cachedir) + except OSError as e: + # If 2 concurrent pytests both race to the rename, the loser + # gets "Directory not empty" from the rename. In this case, + # everything is handled so just continue (while letting the + # temporary directory be cleaned up). + if e.errno != errno.ENOTEMPTY: + raise + else: + # Create a directory in place of the one we just moved so that + # `TemporaryDirectory`'s cleanup doesn't complain. + # + # TODO: pass ignore_cleanup_errors=True when we no longer support python < 3.10. + # See https://github.com/python/cpython/issues/74168. Note that passing + # delete=False would do the wrong thing in case of errors and isn't supported + # until python 3.12. + path.mkdir() class LFPluginCollWrapper: diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index c698ea9a7..287fac463 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -54,7 +54,10 @@ from _pytest import __version__ import _pytest._code from _pytest._code import ExceptionInfo from _pytest._code import filter_traceback +from _pytest._code.code import TracebackStyle from _pytest._io import TerminalWriter +from _pytest.config.argparsing import Argument +from _pytest.config.argparsing import Parser import _pytest.deprecated import _pytest.hookspec from _pytest.outcomes import fail @@ -71,9 +74,7 @@ from _pytest.warning_types import warn_explicit_for if TYPE_CHECKING: - from .argparsing import Argument - from .argparsing import Parser - from _pytest._code.code import _TracebackStyle + from _pytest.cacheprovider import Cache from _pytest.terminal import TerminalReporter @@ -1030,6 +1031,9 @@ class Config: #: 'testpaths' configuration value. TESTPATHS = enum.auto() + # Set by cacheprovider plugin. + cache: Optional["Cache"] + def __init__( self, pluginmanager: PytestPluginManager, @@ -1091,11 +1095,6 @@ class Config: self.args_source = Config.ArgsSource.ARGS self.args: List[str] = [] - if TYPE_CHECKING: - from _pytest.cacheprovider import Cache - - self.cache: Optional[Cache] = None - @property def rootpath(self) -> Path: """The path to the :ref:`rootdir `. @@ -1175,7 +1174,7 @@ class Config: option: Optional[argparse.Namespace] = None, ) -> None: if option and getattr(option, "fulltrace", False): - style: _TracebackStyle = "long" + style: TracebackStyle = "long" else: style = "native" excrepr = excinfo.getrepr( @@ -1913,7 +1912,7 @@ def parse_warning_filter( parts.append("") action_, message, category_, module, lineno_ = (s.strip() for s in parts) try: - action: "warnings._ActionKind" = warnings._getaction(action_) # type: ignore[attr-defined] + action: warnings._ActionKind = warnings._getaction(action_) # type: ignore[attr-defined] except warnings._OptionError as e: raise UsageError(error_template.format(error=str(e))) from None try: diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 1338ef9f2..eacb2836d 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -13,12 +13,12 @@ from typing import List from typing import Optional from typing import Tuple from typing import Type -from typing import TYPE_CHECKING from typing import Union import unittest from _pytest import outcomes from _pytest._code import ExceptionInfo +from _pytest.capture import CaptureManager from _pytest.config import Config from _pytest.config import ConftestImportFailure from _pytest.config import hookimpl @@ -27,11 +27,7 @@ from _pytest.config.argparsing import Parser from _pytest.config.exceptions import UsageError from _pytest.nodes import Node from _pytest.reports import BaseReport - - -if TYPE_CHECKING: - from _pytest.capture import CaptureManager - from _pytest.runner import CallInfo +from _pytest.runner import CallInfo def _validate_usepdb_cls(value: str) -> Tuple[str, str]: @@ -310,7 +306,7 @@ class PdbTrace: return (yield) -def wrap_pytest_function_for_tracing(pyfuncitem): +def wrap_pytest_function_for_tracing(pyfuncitem) -> None: """Change the Python function object of the given Function item by a wrapper which actually enters pdb before calling the python function itself, effectively leaving the user in the pdb prompt in the first @@ -322,14 +318,14 @@ def wrap_pytest_function_for_tracing(pyfuncitem): # python < 3.7.4) runcall's first param is `func`, which means we'd get # an exception if one of the kwargs to testfunction was called `func`. @functools.wraps(testfunction) - def wrapper(*args, **kwargs): + def wrapper(*args, **kwargs) -> None: func = functools.partial(testfunction, *args, **kwargs) _pdb.runcall(func) pyfuncitem.obj = wrapper -def maybe_wrap_pytest_function_for_tracing(pyfuncitem): +def maybe_wrap_pytest_function_for_tracing(pyfuncitem) -> None: """Wrap the given pytestfunct item for tracing support if --trace was given in the command line.""" if pyfuncitem.config.getvalue("trace"): diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index 35a136762..23ad7a7a9 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -298,7 +298,7 @@ class DoctestItem(Item): def runtest(self) -> None: _check_all_skipped(self.dtest) self._disable_output_capturing_for_darwin() - failures: List["doctest.DocTestFailure"] = [] + failures: List[doctest.DocTestFailure] = [] # Type ignored because we change the type of `out` from what # doctest expects. self.runner.run(self.dtest, out=failures) # type: ignore[arg-type] @@ -505,43 +505,46 @@ class DoctestModule(Module): import doctest class MockAwareDocTestFinder(doctest.DocTestFinder): - """A hackish doctest finder that overrides stdlib internals to fix a stdlib bug. + if sys.version_info < (3, 11): - https://github.com/pytest-dev/pytest/issues/3456 - https://bugs.python.org/issue25532 - """ + def _find_lineno(self, obj, source_lines): + """On older Pythons, doctest code does not take into account + `@property`. https://github.com/python/cpython/issues/61648 - def _find_lineno(self, obj, source_lines): - """Doctest code does not take into account `@property`, this - is a hackish way to fix it. https://bugs.python.org/issue17446 + Moreover, wrapped Doctests need to be unwrapped so the correct + line number is returned. #8796 + """ + if isinstance(obj, property): + obj = getattr(obj, "fget", obj) - Wrapped Doctests will need to be unwrapped so the correct - line number is returned. This will be reported upstream. #8796 - """ - if isinstance(obj, property): - obj = getattr(obj, "fget", obj) + if hasattr(obj, "__wrapped__"): + # Get the main obj in case of it being wrapped + obj = inspect.unwrap(obj) - if hasattr(obj, "__wrapped__"): - # Get the main obj in case of it being wrapped - obj = inspect.unwrap(obj) - - # Type ignored because this is a private function. - return super()._find_lineno( # type:ignore[misc] - obj, - source_lines, - ) - - def _find( - self, tests, obj, name, module, source_lines, globs, seen - ) -> None: - if _is_mocked(obj): - return - with _patch_unwrap_mock_aware(): # Type ignored because this is a private function. - super()._find( # type:ignore[misc] - tests, obj, name, module, source_lines, globs, seen + return super()._find_lineno( # type:ignore[misc] + obj, + source_lines, ) + if sys.version_info < (3, 10): + + def _find( + self, tests, obj, name, module, source_lines, globs, seen + ) -> None: + """Override _find to work around issue in stdlib. + + https://github.com/pytest-dev/pytest/issues/3456 + https://github.com/python/cpython/issues/69718 + """ + if _is_mocked(obj): + return # pragma: no cover + with _patch_unwrap_mock_aware(): + # Type ignored because this is a private function. + super()._find( # type:ignore[misc] + tests, obj, name, module, source_lines, globs, seen + ) + if sys.version_info < (3, 13): def _from_module(self, module, object): @@ -556,9 +559,6 @@ class DoctestModule(Module): # Type ignored because this is a private function. return super()._from_module(module, object) # type: ignore[misc] - else: # pragma: no cover - pass - try: module = self.obj except Collector.CollectError: diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index a01b6bfa4..00b86e7fc 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -21,9 +21,11 @@ from typing import Generic from typing import Iterable from typing import Iterator from typing import List +from typing import Mapping from typing import MutableMapping from typing import NoReturn from typing import Optional +from typing import OrderedDict from typing import overload from typing import Sequence from typing import Set @@ -58,6 +60,7 @@ from _pytest.config.argparsing import Parser from _pytest.deprecated import check_ispytest from _pytest.deprecated import MARKED_FIXTURE from _pytest.deprecated import YIELD_FIXTURE +from _pytest.main import Session from _pytest.mark import Mark from _pytest.mark import ParameterSet from _pytest.mark.structures import MarkDecorator @@ -76,9 +79,6 @@ if sys.version_info < (3, 11): if TYPE_CHECKING: - from typing import Deque - - from _pytest.main import Session from _pytest.python import CallSpec2 from _pytest.python import Function from _pytest.python import Metafunc @@ -161,6 +161,12 @@ def getfixturemarker(obj: object) -> Optional["FixtureFunctionMarker"]: ) +# Algorithm for sorting on a per-parametrized resource setup basis. +# It is called for Session scope first and performs sorting +# down to the lower scopes such as to minimize number of "high scope" +# setups and teardowns. + + @dataclasses.dataclass(frozen=True) class FixtureArgKey: argname: str @@ -169,97 +175,95 @@ class FixtureArgKey: item_cls: Optional[type] -def get_parametrized_fixture_keys( +_V = TypeVar("_V") +OrderedSet = Dict[_V, None] + + +def get_parametrized_fixture_argkeys( item: nodes.Item, scope: Scope ) -> Iterator[FixtureArgKey]: """Return list of keys for all parametrized arguments which match the specified scope.""" assert scope is not Scope.Function + try: callspec: CallSpec2 = item.callspec # type: ignore[attr-defined] except AttributeError: return + + item_cls = None + if scope is Scope.Session: + scoped_item_path = None + elif scope is Scope.Package: + # Package key = module's directory. + scoped_item_path = item.path.parent + elif scope is Scope.Module: + scoped_item_path = item.path + elif scope is Scope.Class: + scoped_item_path = item.path + item_cls = item.cls # type: ignore[attr-defined] + else: + assert_never(scope) + for argname in callspec.indices: if callspec._arg2scope[argname] != scope: continue - - item_cls = None - if scope is Scope.Session: - scoped_item_path = None - elif scope is Scope.Package: - # Package key = module's directory. - scoped_item_path = item.path.parent - elif scope is Scope.Module: - scoped_item_path = item.path - elif scope is Scope.Class: - scoped_item_path = item.path - item_cls = item.cls # type: ignore[attr-defined] - else: - assert_never(scope) - param_index = callspec.indices[argname] yield FixtureArgKey(argname, param_index, scoped_item_path, item_cls) -# Algorithm for sorting on a per-parametrized resource setup basis. -# It is called for Session scope first and performs sorting -# down to the lower scopes such as to minimize number of "high scope" -# setups and teardowns. - - def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]: - argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]] = {} - items_by_argkey: Dict[Scope, Dict[FixtureArgKey, Deque[nodes.Item]]] = {} + argkeys_by_item: Dict[Scope, Dict[nodes.Item, OrderedSet[FixtureArgKey]]] = {} + items_by_argkey: Dict[ + Scope, Dict[FixtureArgKey, OrderedDict[nodes.Item, None]] + ] = {} for scope in HIGH_SCOPES: - scoped_argkeys_cache = argkeys_cache[scope] = {} - scoped_items_by_argkey = items_by_argkey[scope] = defaultdict(deque) + scoped_argkeys_by_item = argkeys_by_item[scope] = {} + scoped_items_by_argkey = items_by_argkey[scope] = defaultdict(OrderedDict) for item in items: - keys = dict.fromkeys(get_parametrized_fixture_keys(item, scope), None) - if keys: - scoped_argkeys_cache[item] = keys - for key in keys: - scoped_items_by_argkey[key].append(item) - items_dict = dict.fromkeys(items, None) + argkeys = dict.fromkeys(get_parametrized_fixture_argkeys(item, scope)) + if argkeys: + scoped_argkeys_by_item[item] = argkeys + for argkey in argkeys: + scoped_items_by_argkey[argkey][item] = None + + items_set = dict.fromkeys(items) return list( - reorder_items_atscope(items_dict, argkeys_cache, items_by_argkey, Scope.Session) + reorder_items_atscope( + items_set, argkeys_by_item, items_by_argkey, Scope.Session + ) ) -def fix_cache_order( - item: nodes.Item, - argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]], - items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]], -) -> None: - for scope in HIGH_SCOPES: - for key in argkeys_cache[scope].get(item, []): - items_by_argkey[scope][key].appendleft(item) - - def reorder_items_atscope( - items: Dict[nodes.Item, None], - argkeys_cache: Dict[Scope, Dict[nodes.Item, Dict[FixtureArgKey, None]]], - items_by_argkey: Dict[Scope, Dict[FixtureArgKey, "Deque[nodes.Item]"]], + items: OrderedSet[nodes.Item], + argkeys_by_item: Mapping[Scope, Mapping[nodes.Item, OrderedSet[FixtureArgKey]]], + items_by_argkey: Mapping[ + Scope, Mapping[FixtureArgKey, OrderedDict[nodes.Item, None]] + ], scope: Scope, -) -> Dict[nodes.Item, None]: +) -> OrderedSet[nodes.Item]: if scope is Scope.Function or len(items) < 3: return items - ignore: Set[Optional[FixtureArgKey]] = set() - items_deque = deque(items) - items_done: Dict[nodes.Item, None] = {} + scoped_items_by_argkey = items_by_argkey[scope] - scoped_argkeys_cache = argkeys_cache[scope] + scoped_argkeys_by_item = argkeys_by_item[scope] + + ignore: Set[FixtureArgKey] = set() + items_deque = deque(items) + items_done: OrderedSet[nodes.Item] = {} while items_deque: - no_argkey_group: Dict[nodes.Item, None] = {} + no_argkey_items: OrderedSet[nodes.Item] = {} slicing_argkey = None while items_deque: item = items_deque.popleft() - if item in items_done or item in no_argkey_group: + if item in items_done or item in no_argkey_items: continue argkeys = dict.fromkeys( - (k for k in scoped_argkeys_cache.get(item, []) if k not in ignore), None + k for k in scoped_argkeys_by_item.get(item, ()) if k not in ignore ) if not argkeys: - no_argkey_group[item] = None + no_argkey_items[item] = None else: slicing_argkey, _ = argkeys.popitem() # We don't have to remove relevant items from later in the @@ -268,16 +272,23 @@ def reorder_items_atscope( i for i in scoped_items_by_argkey[slicing_argkey] if i in items ] for i in reversed(matching_items): - fix_cache_order(i, argkeys_cache, items_by_argkey) items_deque.appendleft(i) + # Fix items_by_argkey order. + for other_scope in HIGH_SCOPES: + other_scoped_items_by_argkey = items_by_argkey[other_scope] + for argkey in argkeys_by_item[other_scope].get(i, ()): + other_scoped_items_by_argkey[argkey][i] = None + other_scoped_items_by_argkey[argkey].move_to_end( + i, last=False + ) break - if no_argkey_group: - no_argkey_group = reorder_items_atscope( - no_argkey_group, argkeys_cache, items_by_argkey, scope.next_lower() + if no_argkey_items: + reordered_no_argkey_items = reorder_items_atscope( + no_argkey_items, argkeys_by_item, items_by_argkey, scope.next_lower() ) - for item in no_argkey_group: - items_done[item] = None - ignore.add(slicing_argkey) + items_done.update(reordered_no_argkey_items) + if slicing_argkey is not None: + ignore.add(slicing_argkey) return items_done @@ -1627,7 +1638,7 @@ class FixtureManager: func: "_FixtureFunc[object]", nodeid: Optional[str], scope: Union[ - Scope, _ScopeName, Callable[[str, Config], _ScopeName], None + Scope, _ScopeName, Callable[[str, Config], _ScopeName] ] = "function", params: Optional[Sequence[object]] = None, ids: Optional[ @@ -1823,7 +1834,10 @@ def _show_fixtures_per_test(config: Config, session: "Session") -> None: fixture_doc = inspect.getdoc(fixture_def.func) if fixture_doc: write_docstring( - tw, fixture_doc.split("\n\n")[0] if verbose <= 0 else fixture_doc + tw, + fixture_doc.split("\n\n", maxsplit=1)[0] + if verbose <= 0 + else fixture_doc, ) else: tw.line(" no docstring available", red=True) @@ -1905,7 +1919,9 @@ def _showfixtures_main(config: Config, session: "Session") -> None: tw.write("\n") doc = inspect.getdoc(fixturedef.func) if doc: - write_docstring(tw, doc.split("\n\n")[0] if verbose <= 0 else doc) + write_docstring( + tw, doc.split("\n\n", maxsplit=1)[0] if verbose <= 0 else doc + ) else: tw.line(" no docstring available", red=True) tw.line() diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index 8a38ff4fb..c7f9d036c 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -311,7 +311,12 @@ def pytest_collection_finish(session: "Session") -> None: def pytest_ignore_collect( collection_path: Path, path: "LEGACY_PATH", config: "Config" ) -> Optional[bool]: - """Return True to prevent considering this path for collection. + """Return ``True`` to ignore this path for collection. + + Return ``None`` to let other plugins ignore the path for collection. + + Returning ``False`` will forcefully *not* ignore this path for collection, + without giving a chance for other plugins to ignore this path. This hook is consulted for all files and directories prior to calling more specific hooks. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index af5e443ce..c9139d369 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -401,7 +401,7 @@ class LogCaptureHandler(logging_StreamHandler): # The default behavior of logging is to print "Logging error" # to stderr with the call stack and some extra details. # pytest wants to make such mistakes visible during testing. - raise + raise # pylint: disable=misplaced-bare-raise @final diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 716d5cf78..d200a6877 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -38,7 +38,6 @@ from _pytest.config import PytestPluginManager from _pytest.config import UsageError from _pytest.config.argparsing import Parser from _pytest.config.compat import PathAwareHookProxy -from _pytest.fixtures import FixtureManager from _pytest.outcomes import exit from _pytest.pathlib import absolutepath from _pytest.pathlib import bestrelpath @@ -55,6 +54,8 @@ from _pytest.warning_types import PytestWarning if TYPE_CHECKING: from typing import Self + from _pytest.fixtures import FixtureManager + def pytest_addoption(parser: Parser) -> None: parser.addini( @@ -551,7 +552,7 @@ class Session(nodes.Collector): # Set on the session by runner.pytest_sessionstart. _setupstate: SetupState # Set on the session by fixtures.pytest_sessionstart. - _fixturemanager: FixtureManager + _fixturemanager: "FixtureManager" exitstatus: Union[int, ExitCode] def __init__(self, config: Config) -> None: diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 3567142a6..456808063 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -31,6 +31,7 @@ from _pytest.config import Config from _pytest.deprecated import check_ispytest from _pytest.deprecated import MARKED_FIXTURE from _pytest.outcomes import fail +from _pytest.scope import _ScopeName from _pytest.warning_types import PytestUnknownMarkWarning @@ -430,7 +431,6 @@ def store_mark(obj, mark: Mark, *, stacklevel: int = 2) -> None: # Typing for builtin pytest marks. This is cheating; it gives builtin marks # special privilege, and breaks modularity. But practicality beats purity... if TYPE_CHECKING: - from _pytest.scope import _ScopeName class _SkipMarkDecorator(MarkDecorator): @overload # type: ignore[override,no-overload-impl] diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 974d756a2..aad54f8b3 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -30,6 +30,7 @@ from _pytest._code import getfslineno from _pytest._code.code import ExceptionInfo from _pytest._code.code import TerminalRepr from _pytest._code.code import Traceback +from _pytest._code.code import TracebackStyle from _pytest.compat import LEGACY_PATH from _pytest.config import Config from _pytest.config import ConftestImportFailure @@ -49,7 +50,6 @@ if TYPE_CHECKING: from typing import Self # Imported here due to circular import. - from _pytest._code.code import _TracebackStyle from _pytest.main import Session @@ -416,7 +416,7 @@ class Node(abc.ABC, metaclass=NodeMeta): def _repr_failure_py( self, excinfo: ExceptionInfo[BaseException], - style: "Optional[_TracebackStyle]" = None, + style: "Optional[TracebackStyle]" = None, ) -> TerminalRepr: from _pytest.fixtures import FixtureLookupError @@ -448,6 +448,8 @@ class Node(abc.ABC, metaclass=NodeMeta): else: truncate_locals = True + truncate_args = False if self.config.getoption("verbose", 0) > 2 else True + # excinfo.getrepr() formats paths relative to the CWD if `abspath` is False. # It is possible for a fixture/test to change the CWD while this code runs, which # would then result in the user seeing confusing paths in the failure message. @@ -466,12 +468,13 @@ class Node(abc.ABC, metaclass=NodeMeta): style=style, tbfilter=tbfilter, truncate_locals=truncate_locals, + truncate_args=truncate_args, ) def repr_failure( self, excinfo: ExceptionInfo[BaseException], - style: "Optional[_TracebackStyle]" = None, + style: "Optional[TracebackStyle]" = None, ) -> Union[str, TerminalRepr]: """Return a representation of a collection or test failure. diff --git a/src/_pytest/stepwise.py b/src/_pytest/stepwise.py index 92d3a297e..1e3a09d96 100644 --- a/src/_pytest/stepwise.py +++ b/src/_pytest/stepwise.py @@ -1,18 +1,14 @@ from typing import List from typing import Optional -from typing import TYPE_CHECKING from _pytest import nodes +from _pytest.cacheprovider import Cache from _pytest.config import Config from _pytest.config.argparsing import Parser from _pytest.main import Session from _pytest.reports import TestReport -import pytest -if TYPE_CHECKING: - from _pytest.cacheprovider import Cache - STEPWISE_CACHE_DIR = "cache/stepwise" @@ -37,7 +33,6 @@ def pytest_addoption(parser: Parser) -> None: ) -@pytest.hookimpl def pytest_configure(config: Config) -> None: if config.option.stepwise_skip: # allow --stepwise-skip to work on its own merits. diff --git a/src/_pytest/threadexception.py b/src/_pytest/threadexception.py index 09faf661b..603a1777c 100644 --- a/src/_pytest/threadexception.py +++ b/src/_pytest/threadexception.py @@ -34,8 +34,8 @@ class catch_threading_exception: """ def __init__(self) -> None: - self.args: Optional["threading.ExceptHookArgs"] = None - self._old_hook: Optional[Callable[["threading.ExceptHookArgs"], Any]] = None + self.args: Optional[threading.ExceptHookArgs] = None + self._old_hook: Optional[Callable[[threading.ExceptHookArgs], Any]] = None def _hook(self, args: "threading.ExceptHookArgs") -> None: self.args = args diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 919b497c2..0f201d0f3 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -41,10 +41,11 @@ if TYPE_CHECKING: import twisted.trial.unittest - _SysExcInfoType = Union[ - Tuple[Type[BaseException], BaseException, types.TracebackType], - Tuple[None, None, None], - ] + +_SysExcInfoType = Union[ + Tuple[Type[BaseException], BaseException, types.TracebackType], + Tuple[None, None, None], +] def pytest_pycollect_makeitem( @@ -218,16 +219,17 @@ class TestCaseFunction(Function): super().setup() def teardown(self) -> None: - super().teardown() if self._explicit_tearDown is not None: self._explicit_tearDown() self._explicit_tearDown = None self._obj = None + del self._instance + super().teardown() def startTest(self, testcase: "unittest.TestCase") -> None: pass - def _addexcinfo(self, rawexcinfo: "_SysExcInfoType") -> None: + def _addexcinfo(self, rawexcinfo: _SysExcInfoType) -> None: # Unwrap potential exception info (see twisted trial support below). rawexcinfo = getattr(rawexcinfo, "_rawexcinfo", rawexcinfo) try: @@ -263,7 +265,7 @@ class TestCaseFunction(Function): self.__dict__.setdefault("_excinfo", []).append(excinfo) def addError( - self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + self, testcase: "unittest.TestCase", rawexcinfo: _SysExcInfoType ) -> None: try: if isinstance(rawexcinfo[1], exit.Exception): @@ -273,7 +275,7 @@ class TestCaseFunction(Function): self._addexcinfo(rawexcinfo) def addFailure( - self, testcase: "unittest.TestCase", rawexcinfo: "_SysExcInfoType" + self, testcase: "unittest.TestCase", rawexcinfo: _SysExcInfoType ) -> None: self._addexcinfo(rawexcinfo) @@ -286,7 +288,7 @@ class TestCaseFunction(Function): def addExpectedFailure( self, testcase: "unittest.TestCase", - rawexcinfo: "_SysExcInfoType", + rawexcinfo: _SysExcInfoType, reason: str = "", ) -> None: try: diff --git a/src/_pytest/unraisableexception.py b/src/_pytest/unraisableexception.py index f649267ab..50b121e88 100644 --- a/src/_pytest/unraisableexception.py +++ b/src/_pytest/unraisableexception.py @@ -34,8 +34,8 @@ class catch_unraisable_exception: """ def __init__(self) -> None: - self.unraisable: Optional["sys.UnraisableHookArgs"] = None - self._old_hook: Optional[Callable[["sys.UnraisableHookArgs"], Any]] = None + self.unraisable: Optional[sys.UnraisableHookArgs] = None + self._old_hook: Optional[Callable[[sys.UnraisableHookArgs], Any]] = None def _hook(self, unraisable: "sys.UnraisableHookArgs") -> None: # Storing unraisable.object can resurrect an object which is being diff --git a/testing/_py/test_local.py b/testing/_py/test_local.py index ea5794b25..0215aba96 100644 --- a/testing/_py/test_local.py +++ b/testing/_py/test_local.py @@ -207,7 +207,7 @@ class CommonFSTests: @pytest.mark.parametrize( "fil", - ["*dir", "*dir", pytest.mark.skip("sys.version_info <" " (3,6)")(b"*dir")], + ["*dir", "*dir", pytest.mark.skip("sys.version_info < (3,6)")(b"*dir")], ) def test_visit_filterfunc_is_string(self, path1, fil): lst = [] diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index b54745129..fc60ae9ac 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -11,6 +11,7 @@ import re import sys import textwrap from typing import Any +from typing import cast from typing import TYPE_CHECKING import _pytest._code @@ -27,7 +28,7 @@ import pytest if TYPE_CHECKING: - from _pytest._code.code import _TracebackStyle + from _pytest._code.code import TracebackStyle if sys.version_info < (3, 11): from exceptiongroup import ExceptionGroup @@ -712,6 +713,29 @@ raise ValueError() assert full_reprlocals.lines assert full_reprlocals.lines[0] == "l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + def test_repr_args_not_truncated(self, importasmod) -> None: + mod = importasmod( + """ + def func1(m): + raise ValueError("hello\\nworld") + """ + ) + excinfo = pytest.raises(ValueError, mod.func1, "m" * 500) + excinfo.traceback = excinfo.traceback.filter(excinfo) + entry = excinfo.traceback[-1] + p = FormattedExcinfo(funcargs=True, truncate_args=True) + reprfuncargs = p.repr_args(entry) + assert reprfuncargs is not None + arg1 = cast(str, reprfuncargs.args[0][1]) + assert len(arg1) < 500 + assert "..." in arg1 + # again without truncate + p = FormattedExcinfo(funcargs=True, truncate_args=False) + reprfuncargs = p.repr_args(entry) + assert reprfuncargs is not None + assert reprfuncargs.args[0] == ("m", repr("m" * 500)) + assert "..." not in cast(str, reprfuncargs.args[0][1]) + def test_repr_tracebackentry_lines(self, importasmod) -> None: mod = importasmod( """ @@ -901,7 +925,7 @@ raise ValueError() ) excinfo = pytest.raises(ValueError, mod.entry) - styles: tuple[_TracebackStyle, ...] = ("long", "short") + styles: tuple[TracebackStyle, ...] = ("long", "short") for style in styles: p = FormattedExcinfo(style=style) reprtb = p.repr_traceback(excinfo) @@ -1028,7 +1052,7 @@ raise ValueError() ) excinfo = pytest.raises(ValueError, mod.entry) - styles: tuple[_TracebackStyle, ...] = ("short", "long", "no") + styles: tuple[TracebackStyle, ...] = ("short", "long", "no") for style in styles: for showlocals in (True, False): repr = excinfo.getrepr(style=style, showlocals=showlocals) diff --git a/testing/plugins_integration/pytest_rerunfailures_integration.py b/testing/plugins_integration/pytest_rerunfailures_integration.py new file mode 100644 index 000000000..9a13a3279 --- /dev/null +++ b/testing/plugins_integration/pytest_rerunfailures_integration.py @@ -0,0 +1,11 @@ +import unittest + + +class MyTestCase(unittest.TestCase): + first_time = True + + def test_fail_the_first_time(self) -> None: + """Regression test for issue #12424.""" + if self.first_time: + type(self).first_time = False + self.fail() diff --git a/testing/plugins_integration/requirements.txt b/testing/plugins_integration/requirements.txt index 458cc2f97..f44a02915 100644 --- a/testing/plugins_integration/requirements.txt +++ b/testing/plugins_integration/requirements.txt @@ -1,4 +1,4 @@ -anyio[curio,trio]==4.3.0 +anyio[curio,trio]==4.4.0 django==5.0.6 pytest-asyncio==0.23.7 pytest-bdd==7.1.2 @@ -9,7 +9,7 @@ pytest-html==4.1.1 pytest-mock==3.14.0 pytest-rerunfailures==14.0 pytest-sugar==1.0.0 -pytest-trio==0.7.0 +pytest-trio==0.8.0 pytest-twisted==1.14.1 twisted==24.3.0 pytest-xvfb==3.0.0 diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index d54bcc4d4..d3cff38f9 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -2219,6 +2219,25 @@ class TestAutouseManagement: reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=2) + def test_reordering_catastrophic_performance(self, pytester: Pytester) -> None: + """Check that a certain high-scope parametrization pattern doesn't cause + a catasrophic slowdown. + + Regression test for #12355. + """ + pytester.makepyfile(""" + import pytest + + params = tuple("abcdefghijklmnopqrstuvwxyz") + @pytest.mark.parametrize(params, [range(len(params))] * 3, scope="module") + def test_parametrize(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z): + pass + """) + + result = pytester.runpytest() + + result.assert_outcomes(passed=3) + class TestFixtureMarker: def test_parametrize(self, pytester: Pytester) -> None: diff --git a/testing/test_assertion.py b/testing/test_assertion.py index a8960436b..726235999 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2045,3 +2045,36 @@ def test_fine_grained_assertion_verbosity(pytester: Pytester): f"E AssertionError: assert 'hello world' in '{long_text}'", ] ) + + +def test_full_output_vvv(pytester: Pytester) -> None: + pytester.makepyfile( + r""" + def crash_helper(m): + assert 1 == 2 + def test_vvv(): + crash_helper(500 * "a") + """ + ) + result = pytester.runpytest("") + # without -vvv, the passed args are truncated + expected_non_vvv_arg_line = "m = 'aaaaaaaaaaaaaaa*..aaaaaaaaaaaa*" + result.stdout.fnmatch_lines( + [ + expected_non_vvv_arg_line, + "test_full_output_vvv.py:2: AssertionError", + ], + ) + # double check that the untruncated part is not in the output + expected_vvv_arg_line = "m = '{}'".format(500 * "a") + result.stdout.no_fnmatch_line(expected_vvv_arg_line) + + # but with "-vvv" the args are not truncated + result = pytester.runpytest("-vvv") + result.stdout.fnmatch_lines( + [ + expected_vvv_arg_line, + "test_full_output_vvv.py:2: AssertionError", + ] + ) + result.stdout.no_fnmatch_line(expected_non_vvv_arg_line) diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 8728ae84f..08158f619 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -1163,7 +1163,7 @@ class TestNewFirst: ) p1.write_text( - "def test_1(): assert 1\n" "def test_2(): assert 1\n", encoding="utf-8" + "def test_1(): assert 1\ndef test_2(): assert 1\n", encoding="utf-8" ) os.utime(p1, ns=(p1.stat().st_atime_ns, int(1e9))) diff --git a/testing/test_reports.py b/testing/test_reports.py index c6baeebc9..7987b4017 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -100,14 +100,13 @@ class TestReportSerialization: rep_entries = rep.longrepr.reprtraceback.reprentries a_entries = a.longrepr.reprtraceback.reprentries - for i in range(len(a_entries)): - rep_entry = rep_entries[i] + assert len(rep_entries) == len(a_entries) # python < 3.10 zip(strict=True) + for a_entry, rep_entry in zip(a_entries, rep_entries): assert isinstance(rep_entry, ReprEntry) assert rep_entry.reprfileloc is not None assert rep_entry.reprfuncargs is not None assert rep_entry.reprlocals is not None - a_entry = a_entries[i] assert isinstance(a_entry, ReprEntry) assert a_entry.reprfileloc is not None assert a_entry.reprfuncargs is not None @@ -146,9 +145,10 @@ class TestReportSerialization: rep_entries = rep.longrepr.reprtraceback.reprentries a_entries = a.longrepr.reprtraceback.reprentries - for i in range(len(a_entries)): - assert isinstance(rep_entries[i], ReprEntryNative) - assert rep_entries[i].lines == a_entries[i].lines + assert len(rep_entries) == len(a_entries) # python < 3.10 zip(strict=True) + for rep_entry, a_entry in zip(rep_entries, a_entries): + assert isinstance(rep_entry, ReprEntryNative) + assert rep_entry.lines == a_entry.lines def test_itemreport_outcomes(self, pytester: Pytester) -> None: # This test came originally from test_remote.py in xdist (ca03269). diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 003a74d38..9561cad5e 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1,5 +1,4 @@ # mypy: allow-untyped-defs -import gc import sys from typing import List @@ -192,30 +191,35 @@ def test_teardown(pytester: Pytester) -> None: def test_teardown_issue1649(pytester: Pytester) -> None: """ Are TestCase objects cleaned up? Often unittest TestCase objects set - attributes that are large and expensive during setUp. + attributes that are large and expensive during test run or setUp. The TestCase will not be cleaned up if the test fails, because it would then exist in the stackframe. + + Regression test for #1649 (see also #12367). """ - testpath = pytester.makepyfile( + pytester.makepyfile( """ import unittest - class TestCaseObjectsShouldBeCleanedUp(unittest.TestCase): - def setUp(self): - self.an_expensive_object = 1 - def test_demo(self): - pass + import gc - """ + class TestCaseObjectsShouldBeCleanedUp(unittest.TestCase): + def test_expensive(self): + self.an_expensive_obj = object() + + def test_is_it_still_alive(self): + gc.collect() + for obj in gc.get_objects(): + if type(obj).__name__ == "TestCaseObjectsShouldBeCleanedUp": + assert not hasattr(obj, "an_expensive_obj") + break + else: + assert False, "Could not find TestCaseObjectsShouldBeCleanedUp instance" + """ ) - pytester.inline_run("-s", testpath) - gc.collect() - - # Either already destroyed, or didn't run setUp. - for obj in gc.get_objects(): - if type(obj).__name__ == "TestCaseObjectsShouldBeCleanedUp": - assert not hasattr(obj, "an_expensive_obj") + result = pytester.runpytest() + assert result.ret == ExitCode.OK def test_unittest_skip_issue148(pytester: Pytester) -> None: @@ -380,7 +384,7 @@ def test_testcase_adderrorandfailure_defers(pytester: Pytester, type: str) -> No @pytest.mark.parametrize("type", ["Error", "Failure"]) def test_testcase_custom_exception_info(pytester: Pytester, type: str) -> None: pytester.makepyfile( - """ + f""" from typing import Generic, TypeVar from unittest import TestCase import pytest, _pytest._code @@ -409,7 +413,7 @@ def test_testcase_custom_exception_info(pytester: Pytester, type: str) -> None: def test_hello(self): pass - """.format(**locals()) + """ ) result = pytester.runpytest() result.stdout.fnmatch_lines( diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 770454e83..73c8c1b32 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -280,10 +280,8 @@ def test_warning_recorded_hook(pytester: Pytester) -> None: ("call warning", "runtest", "test_warning_recorded_hook.py::test_func"), ("teardown warning", "runtest", "test_warning_recorded_hook.py::test_func"), ] - for index in range(len(expected)): - collected_result = collected[index] - expected_result = expected[index] - + assert len(collected) == len(expected) # python < 3.10 zip(strict=True) + for collected_result, expected_result in zip(collected, expected): assert collected_result[0] == expected_result[0], str(collected) assert collected_result[1] == expected_result[1], str(collected) assert collected_result[2] == expected_result[2], str(collected) diff --git a/tox.ini b/tox.ini index 0a3f0acf5..35b335a01 100644 --- a/tox.ini +++ b/tox.ini @@ -141,7 +141,7 @@ commands = pytest --cov=. simple_integration.py pytest --ds=django_settings simple_integration.py pytest --html=simple.html simple_integration.py - pytest --reruns 5 simple_integration.py + pytest --reruns 5 simple_integration.py pytest_rerunfailures_integration.py pytest pytest_anyio_integration.py pytest pytest_asyncio_integration.py pytest pytest_mock_integration.py