├── .gitignore ├── .pre-commit-config.yaml ├── .travis.yml ├── HOWTOUPDATE.md ├── LICENSE ├── OVERVIEW.md ├── Procfile ├── README.md ├── dev-requirements.txt ├── drop_db.py ├── heroku_update.bash ├── index.json ├── pypi_rpc_client ├── __init__.py └── proxy.py ├── pyproject.toml ├── pytest.ini ├── requirements.in ├── requirements.txt ├── run.py ├── runtime.txt ├── static ├── electrical-plug-th.png ├── fail.png ├── gumby.css ├── ok.png └── unknown.png ├── templates ├── index.html └── status_help.html ├── test_run.py ├── test_run ├── myplugin-1.0.0-py2.py3-none-any.whl └── src │ ├── myplugin.py │ ├── setup.cfg │ └── setup.py ├── test_update_index.py ├── test_web.py ├── update-index-requirements.txt ├── update_index.py └── web.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | __pycache__ 21 | 22 | # Installer logs 23 | pip-log.txt 24 | 25 | # Unit test / coverage reports 26 | .coverage 27 | .tox 28 | nosetests.xml 29 | 30 | # Translations 31 | *.mo 32 | 33 | # Mr Developer 34 | .mr.developer.cfg 35 | .project 36 | 37 | # Packages 38 | *.tar.gz 39 | *.tgz 40 | *.zip 41 | *.whl 42 | pytest-* 43 | *.env* 44 | .cache/ 45 | /.work/ 46 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: 19.10b0 4 | hooks: 5 | - id: black 6 | args: [--safe, --quiet] 7 | - repo: https://github.com/pre-commit/pre-commit-hooks 8 | rev: v2.2.3 9 | hooks: 10 | - id: trailing-whitespace 11 | - id: end-of-file-fixer 12 | - repo: https://github.com/asottile/reorder_python_imports 13 | rev: v1.4.0 14 | hooks: 15 | - id: reorder-python-imports 16 | args: ['--application-directories=.', --py3-plus] 17 | - repo: https://github.com/asottile/pyupgrade 18 | rev: v1.18.0 19 | hooks: 20 | - id: pyupgrade 21 | args: [--py3-plus] 22 | - repo: https://github.com/shellcheck-py/shellcheck-py 23 | rev: v0.7.1.1 24 | hooks: 25 | - id: shellcheck 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | install: 3 | - pip install -r dev-requirements.txt -U pytest==$PYTEST_VERSION 4 | 5 | env: 6 | global: 7 | - secure: "GYMlRL/xmnVjC2+RljsZj0aVNIOv/d7x36UBT5DNo+FlY4jGHin9nb3tckKzwh+VgNexcZ6O4UY6CRHZdTuwME1LlI4Mywx44y48oomA6lz1RMZI6OP9CF3SbcEl/Qs++sS/USEQNGB9IdWnF11dqbJ7XOI2E9CZk4bX9ZLQVdA=" 8 | - PYTEST_VERSION=6.0.1 9 | - PLUGINCOMPAT_SITE=http://plugincompat.herokuapp.com 10 | 11 | jobs: 12 | include: 13 | - env: RUN_COMMAND="python run.py" 14 | python: '3.6' 15 | - env: RUN_COMMAND="python run.py" 16 | python: '3.7' 17 | - env: RUN_COMMAND="python run.py" 18 | python: '3.8' 19 | - env: RUN_COMMAND="pytest" 20 | python: '3.6' 21 | - env: RUN_COMMAND="pytest" 22 | python: '3.7' 23 | - env: RUN_COMMAND="pytest" 24 | python: '3.8' 25 | - env: RUN_COMMAND="pre-commit run --all-files --show-diff-on-failure" 26 | python: '3.7' 27 | 28 | script: 29 | - $RUN_COMMAND 30 | 31 | branches: 32 | only: 33 | - master 34 | - /feature-.*/ 35 | -------------------------------------------------------------------------------- /HOWTOUPDATE.md: -------------------------------------------------------------------------------- 1 | # Update Site 2 | 3 | Follow this steps to update Python and pytest versions on the site: 4 | 5 | 1. Update pytest and/or python versions in `.travis.yml`: 6 | 7 | ```yaml 8 | python: 9 | - "2.7" 10 | - "3.6" 11 | env: 12 | matrix: 13 | - PYTEST_VERSION=3.3.0 PLUGINCOMPAT_SITE=http://plugincompat.herokuapp.com 14 | ``` 15 | 16 | 2. Update `get_pytest_versions()` and `get_python_versions()` in `web.py` to match the versions in `.travis.yml`. 17 | 18 | 3. Update `test_versions` in `test_web.py`. 19 | 20 | 4. Finally push `master` to GitHub and Heroku. 21 | 22 | # Update Requirements 23 | 24 | Install `pip-tools` in a Python 3.7 virtual environment and execute: 25 | 26 | ``` 27 | $ pip install --upgrade -r requirements.in 28 | $ pip-compile --upgrade 29 | ``` 30 | 31 | And commit everything. 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Bruno Oliveira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /OVERVIEW.md: -------------------------------------------------------------------------------- 1 | ## Overview ## 2 | 3 | For each each plugin, as identified by a search for `pytest-*` on PyPI, we 4 | download, install and execute its tests using [tox](https://tox.readthedocs.io/en/latest/). 5 | If a plugin doesn't have a `tox.ini` file, we generate a simple 6 | `tox.ini` which just ensures that the plugin was installed successfully by 7 | running `pytest --help`. 8 | 9 | Once we have tested all plugins, the results are posted to a web application 10 | that can be used to visualize them. 11 | 12 | The steps above are executed for some Python and pytest versions, 13 | resulting in a matrix of plugin x Python x pytest compatibility. 14 | 15 | [Travis](https://travis-ci.org) is used to execute the tests and post the results. The web 16 | page is hosted by [heroku](https://www.heroku.com) at http://plugincompat.herokuapp.com. 17 | 18 | ## Updating ## 19 | 20 | A [heroku scheduler](https://addons.heroku.com/scheduler) job runs once a day that executes the `heroku_update.bash` 21 | script. 22 | 23 | The main job of this script is to run `update_index.py`, which is responsible for querying PyPI and updating 24 | `index.json` with latest pytest plugin information. This file is then pushed back to GitHub which will trigger a new [travis](https://travis-ci.org) build. 25 | 26 | 27 | ## Details ## 28 | 29 | Below there's a more detailed description of the system for those interested. 30 | 31 | ### update_index.py ### 32 | 33 | This script creates/updates the file `index.json` file using new information 34 | from PyPI and contains the list of plugins to test. It is a `JSON` 35 | formatted file containing a list of `(plugin name, version, description)`, 36 | like this: 37 | 38 | ```json 39 | [ 40 | { 41 | "version": "1.3.7", 42 | "name": "pytest-allure-adaptor", 43 | "description": "Plugin for pytest to generate allure xml reports" 44 | }, 45 | { 46 | "version": "2.1.0", 47 | "name": "pytest-bdd", 48 | "description": "BDD for pytest" 49 | }, 50 | { 51 | "version": "0.0.1", 52 | "name": "pytest-beds", 53 | "description": "Fixtures for testing Google Appengine (GAE) apps" 54 | } 55 | ] 56 | ``` 57 | 58 | To run the script, just execute it without parameters: 59 | 60 | ``` 61 | python update_index.py 62 | index.json updated, push to GitHub. 63 | ``` 64 | 65 | If `index.json` was updated it means either new plugins were posted or some 66 | of the existing plugins were updated, so it should be 67 | committed and pushed to GitHub as the message says. 68 | 69 | If nothing has changed, no further action is needed: 70 | 71 | ``` 72 | python update_index.py 73 | index.json skipped, no changes. 74 | ``` 75 | 76 | ### run.py ### 77 | 78 | This script should be executed by travis: it reads `index.json` file, 79 | executes tests for each package in the current Python interpreter 80 | and posts results back to [heroku](https://www.heroku.com). 81 | 82 | It does so by downloading the source package for each plugin and extracts it into the 83 | current directory. It is assumed that plugins use [tox](https://tox.readthedocs.io/en/latest/) 84 | for testing; if a plugin doesn't have a `tox.ini` file, the script will generate 85 | a simple `tox.ini` that just tries to ensure the plugins installs cleanly. 86 | 87 | After all plugins are tested, results are posted to the web page. 88 | 89 | The script is configured by two environment variables: 90 | 91 | `PYTEST_VERSION`: pytest version that will be passed to `tox` as `--force-dep` 92 | parameter, ensuring that it is tested against that pytest version and not 93 | what is installed in the system. 94 | 95 | `PLUGINCOMPAT_SITE`: URL to post the test result data to. See below for an example of a payload. 96 | 97 | The above environment variables are configured in the 98 | [.travis.yml](/.travis.yml) file and are part of the travis build matrix. 99 | 100 | ### web.py ### 101 | 102 | This is the webserver that is hosted at [heroku](http://plugincompat.herokuapp.com). 103 | 104 | It serves an index page containing a table displaying test results for pytest 105 | plugins against different Python and pytest versions. 106 | 107 | It supports the following URLs: 108 | 109 | #### Main page #### 110 | ``` 111 | GET / 112 | ``` 113 | Returns main page, showing the test results table. 114 | 115 | #### Posting test results #### 116 | 117 | ``` 118 | POST / 119 | ``` 120 | Posts a new payload that update test results. This payload is generated by 121 | our travis build matrix. It expects a secret which is enabled as a Travis environment variable 122 | and must be part of the post. 123 | 124 | Example of an expected payload: 125 | 126 | ```json 127 | { 128 | "secret": "SECRET", 129 | "results": [ 130 | { 131 | "name": "pytest-blockage", 132 | "version": "0.1", 133 | "env": "py33", 134 | "pytest": "2.5.2", 135 | "status": "ok", 136 | "output": "GLOB sdist-make: /home/travis/...", 137 | "description": "Disable network requests during a test run." 138 | } 139 | ] 140 | } 141 | ``` 142 | 143 | #### Status images help #### 144 | ``` 145 | GET /status 146 | ``` 147 | Returns a page explaining on how to obtain status images (badges) for each plugin. 148 | 149 | #### Status images for plugins #### 150 | ``` 151 | GET /status/:name/` 152 | ``` 153 | Returns an image for a specific plugin indicating its 154 | status when tested against a Python and pytest versions. For example: 155 | `/status/pytest-pep8-1.0.5?py=py33&pytest=2.4.2` 156 | 157 | [web.py](/web.py) has test cases to ensure pages are behaving as expected, see 158 | [test_web.py](/test_web.py). 159 | 160 | #### Get test output #### 161 | ``` 162 | GET /output/:name/ 163 | ``` 164 | 165 | Receives the same parameter as `/status/:name/`, but returns the output 166 | of the tox run as plain text. 167 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn web:app 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # plugincompat # 2 | 3 | ## This repository has been retired ## 4 | 5 | For more information, see [#66](https://github.com/pytest-dev/plugincompat/issues/66). 6 | 7 | --- 8 | 9 | Compatibility checks for pytest plugins. 10 | 11 |  12 | 13 | This project tests pytest plugins compatibility across Python and pytest 14 | versions, displaying them in a web page for quick consulting. 15 | 16 | See test results are at http://plugincompat.herokuapp.com. 17 | 18 | PyPI projects whose 19 | name starts with `pytest-` are considered plugins. 20 | 21 | [](https://travis-ci.org/pytest-dev/plugincompat) 22 | 23 | [Overview](OVERVIEW.md) 24 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | -r update-index-requirements.txt 3 | asynctest 4 | pre-commit 5 | pytest-datadir 6 | pytest-mock 7 | pytest-trio 8 | -------------------------------------------------------------------------------- /drop_db.py: -------------------------------------------------------------------------------- 1 | from web import PlugsStorage 2 | 3 | s = PlugsStorage() 4 | s.drop_all() 5 | print("Database dropped") 6 | -------------------------------------------------------------------------------- /heroku_update.bash: -------------------------------------------------------------------------------- 1 | # script ran periodically by Heroku to update the plugin index file 2 | echo "Cloning..." 3 | git config --global user.name "pytestbot" 4 | git config --global user.email pytestbot@gmail.com 5 | git clone https://github.com/pytest-dev/plugincompat.git 6 | 7 | echo "Updating..." 8 | cd plugincompat || exit 9 | pip install -r update-index-requirements.txt 10 | python update_index.py 11 | 12 | echo "Push..." 13 | git commit -a -m "Updating index (from heroku)" 14 | # GITHUB_TOKEN is personal access token from the pytestbot account, created in: 15 | # https://github.com/settings/tokens 16 | # and made available to this script as a config var setting in Heroku: 17 | # https://dashboard.heroku.com/apps/plugincompat/settings 18 | git push "https://$GITHUB_TOKEN:x-oauth-basic@github.com/pytest-dev/plugincompat.git" master 19 | -------------------------------------------------------------------------------- /index.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "description": "A simple image diff plugin for pytest", 4 | "name": "pytest-Inomaly", 5 | "version": "0.2.5" 6 | }, 7 | { 8 | "description": "pytest plugin for generating test execution results within Jira Test Management (tm4j)", 9 | "name": "pytest-adaptavist", 10 | "version": "4.0.5" 11 | }, 12 | { 13 | "description": "Pytest plugin for writing Azure Data Factory integration tests", 14 | "name": "pytest-adf", 15 | "version": "0.1.2" 16 | }, 17 | { 18 | "description": "pytest plugin for pytest-repeat that generate aggregate report of the same test cases with additional statistics details.", 19 | "name": "pytest-aggreport", 20 | "version": "0.1.4" 21 | }, 22 | { 23 | "description": "pytest fixtures for writing aiofiles tests with pyfakefs", 24 | "name": "pytest-aiofiles", 25 | "version": "0.2.0" 26 | }, 27 | { 28 | "description": "pytest plugin for aiohttp support", 29 | "name": "pytest-aiohttp", 30 | "version": "0.3.0" 31 | }, 32 | { 33 | "description": "Pytest `client` fixture for the Aiohttp", 34 | "name": "pytest-aiohttp-client", 35 | "version": "0.0.3" 36 | }, 37 | { 38 | "description": "A plugin to test aioworkers project with pytest", 39 | "name": "pytest-aioworkers", 40 | "version": "0.3.0" 41 | }, 42 | { 43 | "description": "pytest support for airflow.", 44 | "name": "pytest-airflow", 45 | "version": "0.0.3" 46 | }, 47 | { 48 | "description": "A pytest plugin for verifying alembic migrations.", 49 | "name": "pytest-alembic", 50 | "version": "0.2.5" 51 | }, 52 | { 53 | "description": "Pytest fixture extending Numpy's allclose function", 54 | "name": "pytest-allclose", 55 | "version": "1.0.0" 56 | }, 57 | { 58 | "description": "Plugin for py.test to generate allure xml reports", 59 | "name": "pytest-allure-adaptor", 60 | "version": "1.7.10" 61 | }, 62 | { 63 | "description": "Plugin for py.test to generate allure xml reports", 64 | "name": "pytest-allure-adaptor2", 65 | "version": "1.8.2" 66 | }, 67 | { 68 | "description": "pytest plugin to test case doc string dls instructions", 69 | "name": "pytest-allure-dsl", 70 | "version": "1.0.0" 71 | }, 72 | { 73 | "description": "Static code checks used at Alphamoon", 74 | "name": "pytest-alphamoon", 75 | "version": "0.5.3" 76 | }, 77 | { 78 | "description": "This fixture provides a configured \"driver\" for Android Automated Testing, using uiautomator2.", 79 | "name": "pytest-android", 80 | "version": "2019.2a3" 81 | }, 82 | { 83 | "description": "pytest-annotate: Generate PyAnnotate annotations from your pytest tests.", 84 | "name": "pytest-annotate", 85 | "version": "1.0.3" 86 | }, 87 | { 88 | "description": "Plugin for py.test to simplify calling ansible modules from tests or fixtures", 89 | "name": "pytest-ansible", 90 | "version": "2.2.3" 91 | }, 92 | { 93 | "description": "Pytest fixture which runs given ansible playbook file.", 94 | "name": "pytest-ansible-playbook", 95 | "version": "0.4.1" 96 | }, 97 | { 98 | "description": "Pytest fixture which runs given ansible playbook file.", 99 | "name": "pytest-ansible-playbook-runner", 100 | "version": "0.0.5" 101 | }, 102 | { 103 | "description": "Bust functools.lru_cache when running pytest to avoid test pollution", 104 | "name": "pytest-antilru", 105 | "version": "1.0.5" 106 | }, 107 | { 108 | "description": "Pytest fixtures to assert anything and something", 109 | "name": "pytest-anything", 110 | "version": "0.1.1" 111 | }, 112 | { 113 | "description": "Downloads puzzle inputs for Advent of Code and synthesizes PyTest fixtures", 114 | "name": "pytest-aoc", 115 | "version": "1.1" 116 | }, 117 | { 118 | "description": "apistellar plugin for pytest.", 119 | "name": "pytest-apistellar", 120 | "version": "0.2.0" 121 | }, 122 | { 123 | "description": "AppEngine integration that works well with pytest-django", 124 | "name": "pytest-appengine", 125 | "version": "0.0.2" 126 | }, 127 | { 128 | "description": "Pytest plugin for appium", 129 | "name": "pytest-appium", 130 | "version": "0.1" 131 | }, 132 | { 133 | "description": "A plugin to use approvaltests with pytest", 134 | "name": "pytest-approvaltests", 135 | "version": "0.1.1" 136 | }, 137 | { 138 | "description": "pytest plugin to help with comparing array output from tests", 139 | "name": "pytest-arraydiff", 140 | "version": "0.3" 141 | }, 142 | { 143 | "description": "Convenient ASGI client/server fixtures for Pytest", 144 | "name": "pytest-asgi-server", 145 | "version": "0.2.3" 146 | }, 147 | { 148 | "description": "test Answer Set Programming programs", 149 | "name": "pytest-asptest", 150 | "version": "0.1.0" 151 | }, 152 | { 153 | "description": "Useful assertion utilities for use with pytest", 154 | "name": "pytest-assert-utils", 155 | "version": "0.2.1" 156 | }, 157 | { 158 | "description": "pytest-assertutil", 159 | "name": "pytest-assertutil", 160 | "version": "0.0.2" 161 | }, 162 | { 163 | "description": "A pytest plugin that allows multiple failures per test", 164 | "name": "pytest-assume", 165 | "version": "2.3.3" 166 | }, 167 | { 168 | "description": "A plugin for pytest devs to view how assertion rewriting recodes the AST", 169 | "name": "pytest-ast-back-to-python", 170 | "version": "1.2.1" 171 | }, 172 | { 173 | "description": "", 174 | "name": "pytest-ast-transformer", 175 | "version": "1.0.3" 176 | }, 177 | { 178 | "description": "Meta-package containing dependencies for testing", 179 | "name": "pytest-astropy", 180 | "version": "0.8.0" 181 | }, 182 | { 183 | "description": "pytest plugin to add diagnostic information to the header of the test output", 184 | "name": "pytest-astropy-header", 185 | "version": "0.1.2" 186 | }, 187 | { 188 | "description": "pytest plugin for async MongoDB", 189 | "name": "pytest-async-mongodb", 190 | "version": "0.0.1.dev3" 191 | }, 192 | { 193 | "description": "Pytest support for asyncio.", 194 | "name": "pytest-asyncio", 195 | "version": "0.14.0" 196 | }, 197 | { 198 | "description": "Run all your asynchronous tests cooperatively.", 199 | "name": "pytest-asyncio-cooperative", 200 | "version": "0.12.0" 201 | }, 202 | { 203 | "description": "pytest-asyncio-network-simulator: Plugin for pytest for simulator the network in tests", 204 | "name": "pytest-asyncio-network-simulator", 205 | "version": "0.1.0a2" 206 | }, 207 | { 208 | "description": "Skip rest of tests if previous test failed.", 209 | "name": "pytest-atomic", 210 | "version": "2.0.0" 211 | }, 212 | { 213 | "description": "pytest plugin to select tests based on attributes similar to the nose-attrib plugin", 214 | "name": "pytest-attrib", 215 | "version": "0.1.3" 216 | }, 217 | { 218 | "description": "Austin plugin for pytest", 219 | "name": "pytest-austin", 220 | "version": "0.1.0" 221 | }, 222 | { 223 | "description": "pytest plugin: avoid repeating arguments in parametrize", 224 | "name": "pytest-auto-parametrize", 225 | "version": "0.1.0" 226 | }, 227 | { 228 | "description": "automatically check condition and log all the checks", 229 | "name": "pytest-autochecklog", 230 | "version": "0.2.0" 231 | }, 232 | { 233 | "description": "Pytest plugin for automatical mocks creation", 234 | "name": "pytest-automock", 235 | "version": "0.7.0" 236 | }, 237 | { 238 | "description": "Makes pytest skip tests that don not need rerunning", 239 | "name": "pytest-avoidance", 240 | "version": "0.3.0" 241 | }, 242 | { 243 | "description": "pytest plugin for testing AWS resource configurations", 244 | "name": "pytest-aws", 245 | "version": "0.1.0" 246 | }, 247 | { 248 | "description": "pytest plugin for axe-selenium-python", 249 | "name": "pytest-axe", 250 | "version": "1.1.6" 251 | }, 252 | { 253 | "description": "Formatting PyTest output for Azure Pipelines UI", 254 | "name": "pytest-azurepipelines", 255 | "version": "0.8.0" 256 | }, 257 | { 258 | "description": "A bandit plugin for pytest", 259 | "name": "pytest-bandit", 260 | "version": "0.5.2" 261 | }, 262 | { 263 | "description": "pytest plugin for URL based testing", 264 | "name": "pytest-base-url", 265 | "version": "1.4.2" 266 | }, 267 | { 268 | "description": "BDD for pytest", 269 | "name": "pytest-bdd", 270 | "version": "4.0.1" 271 | }, 272 | { 273 | "description": "Common steps for pytest bdd and splinter integration", 274 | "name": "pytest-bdd-splinter", 275 | "version": "0.4.0" 276 | }, 277 | { 278 | "description": "A simple plugin to use with pytest", 279 | "name": "pytest-bdd-web", 280 | "version": "0.1.1" 281 | }, 282 | { 283 | "description": "", 284 | "name": "pytest-bdd-wrappers", 285 | "version": "0.1.3" 286 | }, 287 | { 288 | "description": "A pytest plugin that reports test results to the BeakerLib framework", 289 | "name": "pytest-beakerlib", 290 | "version": "0.7.1" 291 | }, 292 | { 293 | "description": "Fixtures for testing Google Appengine (GAE) apps", 294 | "name": "pytest-beds", 295 | "version": "0.3.0" 296 | }, 297 | { 298 | "description": "Benchmark utility that plugs into pytest.", 299 | "name": "pytest-bench", 300 | "version": "0.3.0" 301 | }, 302 | { 303 | "description": "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer. See calibration_ and FAQ_.", 304 | "name": "pytest-benchmark", 305 | "version": "3.2.3" 306 | }, 307 | { 308 | "description": "A BigchainDB plugin for pytest.", 309 | "name": "pytest-bigchaindb", 310 | "version": "0.1.0" 311 | }, 312 | { 313 | "description": "A pytest plugin to enable format checking with black", 314 | "name": "pytest-black", 315 | "version": "0.3.12" 316 | }, 317 | { 318 | "description": "Allow '--black' on older Pythons", 319 | "name": "pytest-black-multipy", 320 | "version": "1.0.0" 321 | }, 322 | { 323 | "description": "A pytest plugin helps developers to debug by providing useful commits history.", 324 | "name": "pytest-blame", 325 | "version": "0.1.7" 326 | }, 327 | { 328 | "description": "Pytest plugin to emit notifications via the Blink(1) RGB LED", 329 | "name": "pytest-blink1", 330 | "version": "0.0.8" 331 | }, 332 | { 333 | "description": "Disable network requests during a test run.", 334 | "name": "pytest-blockage", 335 | "version": "0.2.2" 336 | }, 337 | { 338 | "description": "pytest plugin to mark a test as blocker and skip all other tests", 339 | "name": "pytest-blocker", 340 | "version": "0.2" 341 | }, 342 | { 343 | "description": "Local continuous test runner with pytest and watchdog.", 344 | "name": "pytest-board", 345 | "version": "0.1.0" 346 | }, 347 | { 348 | "description": "A py.test plug-in to enable drop to bpdb debugger on test failure.", 349 | "name": "pytest-bpdb", 350 | "version": "0.1.4" 351 | }, 352 | { 353 | "description": "A simple plugin to connect with breed-server", 354 | "name": "pytest-breed-adapter", 355 | "version": "1.2.0" 356 | }, 357 | { 358 | "description": "A pytest plugin for running tests on a Briefcase project.", 359 | "name": "pytest-briefcase", 360 | "version": "0.1.1" 361 | }, 362 | { 363 | "description": "A pytest plugin for console based browser test selection just after the collection phase", 364 | "name": "pytest-browser", 365 | "version": "0.2.0" 366 | }, 367 | { 368 | "description": "BrowserMob proxy plugin for py.test.", 369 | "name": "pytest-browsermob-proxy", 370 | "version": "0.1" 371 | }, 372 | { 373 | "description": "``py.test`` plugin to run ``BrowserStackLocal`` in background.", 374 | "name": "pytest-browserstack-local", 375 | "version": "0.5.0" 376 | }, 377 | { 378 | "description": "Pytest plugin for marking tests as a bug", 379 | "name": "pytest-bug", 380 | "version": "1.0.0" 381 | }, 382 | { 383 | "description": "py.test bugzilla integration plugin", 384 | "name": "pytest-bugzilla", 385 | "version": "0.2" 386 | }, 387 | { 388 | "description": "A plugin that allows you to execute create, update, and read information from BugZilla bugs", 389 | "name": "pytest-bugzilla-notifier", 390 | "version": "1.1.9" 391 | }, 392 | { 393 | "description": "Plugin for pytest that automatically publishes coverage and pytest report annotations to Buildkite.", 394 | "name": "pytest-buildkite", 395 | "version": "0.3.0" 396 | }, 397 | { 398 | "description": "Run your tests in Bubblewrap sandboxes", 399 | "name": "pytest-bwrap", 400 | "version": "0.1" 401 | }, 402 | { 403 | "description": "pytest plugin with mechanisms for caching across test runs", 404 | "name": "pytest-cache", 405 | "version": "1.0" 406 | }, 407 | { 408 | "description": "Pytest plugin to only run tests affected by changes", 409 | "name": "pytest-cagoule", 410 | "version": "0.4.0" 411 | }, 412 | { 413 | "description": "Enable CamelCase-aware pytest class collection", 414 | "name": "pytest-camel-collect", 415 | "version": "1.0.2" 416 | }, 417 | { 418 | "description": "A plugin which allows to compare results with canonical results, based on previous runs", 419 | "name": "pytest-canonical-data", 420 | "version": "0.1.0" 421 | }, 422 | { 423 | "description": "A plugin that replays pRNG state on failure.", 424 | "name": "pytest-caprng", 425 | "version": "0.1.0" 426 | }, 427 | { 428 | "description": "pytest plugin to capture all deprecatedwarnings and put them in one file", 429 | "name": "pytest-capture-deprecatedwarnings", 430 | "version": "0.2" 431 | }, 432 | { 433 | "description": "Separate test code from test cases in pytest.", 434 | "name": "pytest-cases", 435 | "version": "2.4.0" 436 | }, 437 | { 438 | "description": "Cassandra CCM Test Fixtures for pytest", 439 | "name": "pytest-cassandra", 440 | "version": "0.1.0" 441 | }, 442 | { 443 | "description": "Pytest plugin with server for catching HTTP requests.", 444 | "name": "pytest-catch-server", 445 | "version": "1.0.0" 446 | }, 447 | { 448 | "description": "py.test plugin to catch log messages. This is a fork of pytest-capturelog.", 449 | "name": "pytest-catchlog", 450 | "version": "1.2.2" 451 | }, 452 | { 453 | "description": "pytest-celery a shim pytest plugin to enable celery.contrib.pytest", 454 | "name": "pytest-celery", 455 | "version": "0.0.0a1" 456 | }, 457 | { 458 | "description": "A set of py.test fixtures for AWS Chalice", 459 | "name": "pytest-chalice", 460 | "version": "0.0.5" 461 | }, 462 | { 463 | "description": "turn . into √,turn F into x", 464 | "name": "pytest-change-report", 465 | "version": "1.0" 466 | }, 467 | { 468 | "description": "A pytest fixture for changing current working directory", 469 | "name": "pytest-chdir", 470 | "version": "0.1.3" 471 | }, 472 | { 473 | "description": "A pytest plugin that allows multiple failures per test.", 474 | "name": "pytest-check", 475 | "version": "0.3.9" 476 | }, 477 | { 478 | "description": "Check links in files", 479 | "name": "pytest-check-links", 480 | "version": "0.4.4" 481 | }, 482 | { 483 | "description": "pytest plugin to test Check_MK checks", 484 | "name": "pytest-check-mk", 485 | "version": "0.1.1" 486 | }, 487 | { 488 | "description": "check the README when running tests", 489 | "name": "pytest-checkdocs", 490 | "version": "2.1.1" 491 | }, 492 | { 493 | "description": "plugin to check if there are ipdb debugs left", 494 | "name": "pytest-checkipdb", 495 | "version": "1.0.9" 496 | }, 497 | { 498 | "description": "py.test plugin for CircleCI", 499 | "name": "pytest-circleci", 500 | "version": "0.0.3" 501 | }, 502 | { 503 | "description": "Parallelize pytest across CircleCI workers.", 504 | "name": "pytest-circleci-parallelized", 505 | "version": "0.0.4" 506 | }, 507 | { 508 | "description": "Backport of CKAN 2.9 pytest plugin and fixtures to CAKN 2.8", 509 | "name": "pytest-ckan", 510 | "version": "0.0.12" 511 | }, 512 | { 513 | "description": "A plugin providing an alternative, colourful diff output for failing assertions.", 514 | "name": "pytest-clarity", 515 | "version": "0.3.0a0" 516 | }, 517 | { 518 | "description": "Easy quality control for CLDF datasets using pytest", 519 | "name": "pytest-cldf", 520 | "version": "0.2.1" 521 | }, 522 | { 523 | "description": "Py.test plugin for Click", 524 | "name": "pytest-click", 525 | "version": "1.0.2" 526 | }, 527 | { 528 | "description": "", 529 | "name": "pytest-clld", 530 | "version": "1.0.2" 531 | }, 532 | { 533 | "description": "Distributed tests planner plugin for pytest testing framework.", 534 | "name": "pytest-cloud", 535 | "version": "5.0.3" 536 | }, 537 | { 538 | "description": "pytest plugin for testing cloudflare workers", 539 | "name": "pytest-cloudflare-worker", 540 | "version": "0.0.2" 541 | }, 542 | { 543 | "description": "PyTest plugin for testing Smart Contracts for Ethereum blockchain.", 544 | "name": "pytest-cobra", 545 | "version": "1.0.4" 546 | }, 547 | { 548 | "description": "pytest plugin to add source code sanity checks (pep8 and friends)", 549 | "name": "pytest-codecheckers", 550 | "version": "0.2" 551 | }, 552 | { 553 | "description": "Automatically create pytest test signatures", 554 | "name": "pytest-codegen", 555 | "version": "0.0.3" 556 | }, 557 | { 558 | "description": "pytest plugin to run pycodestyle", 559 | "name": "pytest-codestyle", 560 | "version": "2.0.1" 561 | }, 562 | { 563 | "description": "Formatter for pytest collect output", 564 | "name": "pytest-collect-formatter", 565 | "version": "0.3.0" 566 | }, 567 | { 568 | "description": "Colorizes the progress indicators", 569 | "name": "pytest-colordots", 570 | "version": "1.1" 571 | }, 572 | { 573 | "description": "An interactive GUI test runner for PyTest", 574 | "name": "pytest-commander", 575 | "version": "2.3.1" 576 | }, 577 | { 578 | "description": "pytest framework for testing different aspects of a common method", 579 | "name": "pytest-common-subject", 580 | "version": "1.0.5" 581 | }, 582 | { 583 | "description": "Concurrently execute test cases with multithread, multiprocess and gevent", 584 | "name": "pytest-concurrent", 585 | "version": "0.2.2" 586 | }, 587 | { 588 | "description": "Base configurations and utilities for developing\n your Python project test suite with pytest.", 589 | "name": "pytest-config", 590 | "version": "0.0.11" 591 | }, 592 | { 593 | "description": "Package stands for pytest plugin to upload results into Confluence page.", 594 | "name": "pytest-confluence-report", 595 | "version": "0.0.3" 596 | }, 597 | { 598 | "description": "Pytest plugin for testing console scripts", 599 | "name": "pytest-console-scripts", 600 | "version": "1.1.0" 601 | }, 602 | { 603 | "description": "pytest plugin with fixtures for testing consul aware apps", 604 | "name": "pytest-consul", 605 | "version": "0.2.0" 606 | }, 607 | { 608 | "description": "Define pytest fixtures as context managers.", 609 | "name": "pytest-contextfixture", 610 | "version": "0.1.1" 611 | }, 612 | { 613 | "description": "A plugin to run tests written with the Contexts framework using pytest", 614 | "name": "pytest-contexts", 615 | "version": "0.1.3" 616 | }, 617 | { 618 | "description": "The pytest plugin for your Cookiecutter templates. 🍪", 619 | "name": "pytest-cookies", 620 | "version": "0.5.1" 621 | }, 622 | { 623 | "description": "py.test extension for per-test couchdb databases using couchdbkit", 624 | "name": "pytest-couchdbkit", 625 | "version": "0.5.1" 626 | }, 627 | { 628 | "description": "count erros and send email", 629 | "name": "pytest-count", 630 | "version": "0.1.0" 631 | }, 632 | { 633 | "description": "Pytest plugin for measuring coverage.", 634 | "name": "pytest-cov", 635 | "version": "2.10.1" 636 | }, 637 | { 638 | "description": "Pytest plugin for excluding tests based on coverage data", 639 | "name": "pytest-cov-exclude", 640 | "version": "0.0.9" 641 | }, 642 | { 643 | "description": "Pytest plugin for measuring coverage. Forked from `pytest-cov`.", 644 | "name": "pytest-cover", 645 | "version": "3.0.0" 646 | }, 647 | { 648 | "description": "", 649 | "name": "pytest-coverage", 650 | "version": "0.0.1" 651 | }, 652 | { 653 | "description": "Use pytest's runner to discover and execute C++ tests", 654 | "name": "pytest-cpp", 655 | "version": "1.4.0" 656 | }, 657 | { 658 | "description": "Run cram tests with pytest.", 659 | "name": "pytest-cram", 660 | "version": "0.2.2" 661 | }, 662 | { 663 | "description": "Manages CrateDB instances during your integration tests", 664 | "name": "pytest-crate", 665 | "version": "0.3.0" 666 | }, 667 | { 668 | "description": "A Cricri plugin for pytest.", 669 | "name": "pytest-cricri", 670 | "version": "1.0" 671 | }, 672 | { 673 | "description": "add crontab task in crontab", 674 | "name": "pytest-crontab", 675 | "version": "0.1" 676 | }, 677 | { 678 | "description": "CSV output for pytest.", 679 | "name": "pytest-csv", 680 | "version": "2.0.2" 681 | }, 682 | { 683 | "description": "Pytest support for curio.", 684 | "name": "pytest-curio", 685 | "version": "1.0.1" 686 | }, 687 | { 688 | "description": "pytest plugin to generate curl command line report", 689 | "name": "pytest-curl-report", 690 | "version": "0.5.4" 691 | }, 692 | { 693 | "description": "Exit pytest test session with custom exit code in different scenarios", 694 | "name": "pytest-custom-exit-code", 695 | "version": "0.3.0" 696 | }, 697 | { 698 | "description": "Configure the symbols displayed for test outcomes", 699 | "name": "pytest-custom-report", 700 | "version": "1.0.1" 701 | }, 702 | { 703 | "description": "A plugin for testing Cython extension modules", 704 | "name": "pytest-cython", 705 | "version": "0.1.0" 706 | }, 707 | { 708 | "description": "A pytest plugin for checking of modified code using Darker", 709 | "name": "pytest-darker", 710 | "version": "0.1.2" 711 | }, 712 | { 713 | "description": "pytest fixtures to run dash applications.", 714 | "name": "pytest-dash", 715 | "version": "2.1.2" 716 | }, 717 | { 718 | "description": "Useful functions for managing data for pytest fixtures", 719 | "name": "pytest-data", 720 | "version": "0.4" 721 | }, 722 | { 723 | "description": "Fixture \"data\" and \"case_data\" for test from yaml file", 724 | "name": "pytest-data-file", 725 | "version": "0.1" 726 | }, 727 | { 728 | "description": "Pytest plugin for remote Databricks notebooks testing", 729 | "name": "pytest-databricks", 730 | "version": "0.0.8" 731 | }, 732 | { 733 | "description": "pytest plugin for test data directories and files", 734 | "name": "pytest-datadir", 735 | "version": "1.3.1" 736 | }, 737 | { 738 | "description": "Manager for test data providing downloads, caching of generated files, and a context for temp directories.", 739 | "name": "pytest-datadir-mgr", 740 | "version": "1.2.3" 741 | }, 742 | { 743 | "description": "Fixtures for pytest allowing test functions/methods to easily retrieve test resources from the local filesystem.", 744 | "name": "pytest-datadir-ng", 745 | "version": "1.1.1" 746 | }, 747 | { 748 | "description": "py.test plugin to create a 'tmpdir' containing predefined files/directories.", 749 | "name": "pytest-datafiles", 750 | "version": "2.0" 751 | }, 752 | { 753 | "description": "Data fixtures for pytest made simple", 754 | "name": "pytest-datafixtures", 755 | "version": "0.1.0" 756 | }, 757 | { 758 | "description": "A pytest plugin for managing an archive of test data.", 759 | "name": "pytest-dataplugin", 760 | "version": "0.0.2" 761 | }, 762 | { 763 | "description": "A py.test plugin recording and comparing test output.", 764 | "name": "pytest-datarecorder", 765 | "version": "1.3.0" 766 | }, 767 | { 768 | "description": "A pytest plugin for test driven data-wrangling (this is the development version of datatest's pytest integration).", 769 | "name": "pytest-datatest", 770 | "version": "0.1.4" 771 | }, 772 | { 773 | "description": "Session scope fixture \"db\" for mysql query or change", 774 | "name": "pytest-db", 775 | "version": "0.1" 776 | }, 777 | { 778 | "description": "Databases fixtures plugin for py.test.", 779 | "name": "pytest-dbfixtures", 780 | "version": "1.0.0" 781 | }, 782 | { 783 | "description": "A pytest plugin for testing dbt adapter plugins", 784 | "name": "pytest-dbt-adapter", 785 | "version": "0.3.0" 786 | }, 787 | { 788 | "description": "D-BUS notifications for pytest results.", 789 | "name": "pytest-dbus-notification", 790 | "version": "1.0.1" 791 | }, 792 | { 793 | "description": "A simple plugin to list unused fixtures in pytest", 794 | "name": "pytest-deadfixtures", 795 | "version": "2.2.1" 796 | }, 797 | { 798 | "description": "", 799 | "name": "pytest-demo", 800 | "version": "0.1.3" 801 | }, 802 | { 803 | "description": "Manage dependencies of tests", 804 | "name": "pytest-dependency", 805 | "version": "0.5.1" 806 | }, 807 | { 808 | "description": "Tests that depend on other tests", 809 | "name": "pytest-depends", 810 | "version": "1.0.1" 811 | }, 812 | { 813 | "description": "Mark tests as testing a deprecated feature with a warning note.", 814 | "name": "pytest-deprecate", 815 | "version": "1.0.2" 816 | }, 817 | { 818 | "description": "Describe-style plugin for pytest", 819 | "name": "pytest-describe", 820 | "version": "1.0.0" 821 | }, 822 | { 823 | "description": "plugin for rich text descriptions", 824 | "name": "pytest-describe-it", 825 | "version": "0.1.0" 826 | }, 827 | { 828 | "description": "DevPI server fixture for py.test", 829 | "name": "pytest-devpi-server", 830 | "version": "1.7.0" 831 | }, 832 | { 833 | "description": "pytest plugin for diamond", 834 | "name": "pytest-diamond", 835 | "version": "0.0.1" 836 | }, 837 | { 838 | "description": "pytest plugin to provide DICOM fixtures", 839 | "name": "pytest-dicom", 840 | "version": "0.0.1a0" 841 | }, 842 | { 843 | "description": "", 844 | "name": "pytest-dictsdiff", 845 | "version": "0.5.8" 846 | }, 847 | { 848 | "description": "A simple plugin to use with pytest", 849 | "name": "pytest-diff", 850 | "version": "0.1.14" 851 | }, 852 | { 853 | "description": "Common py.test support for Diffeo packages", 854 | "name": "pytest-diffeo", 855 | "version": "0.2.0" 856 | }, 857 | { 858 | "description": "pytest plugin to disable a test and skip it from testrun", 859 | "name": "pytest-disable", 860 | "version": "0.2" 861 | }, 862 | { 863 | "description": "Disable plugins per test", 864 | "name": "pytest-disable-plugin", 865 | "version": "0.1.2" 866 | }, 867 | { 868 | "description": "A pytest plugin to notify test results to a Discord channel.", 869 | "name": "pytest-discord", 870 | "version": "0.0.5" 871 | }, 872 | { 873 | "description": "Picky test coverage for pytest", 874 | "name": "pytest-divide-and-cover", 875 | "version": "0.5.1" 876 | }, 877 | { 878 | "description": "A Django plugin for pytest.", 879 | "name": "pytest-django", 880 | "version": "4.1.0" 881 | }, 882 | { 883 | "description": "A Django plugin for pytest.", 884 | "name": "pytest-django-ahead", 885 | "version": "3.0.0.2" 886 | }, 887 | { 888 | "description": "A djangocachexdist plugin for pytest", 889 | "name": "pytest-django-cache-xdist", 890 | "version": "0.1.1" 891 | }, 892 | { 893 | "description": "Integrate CasperJS with your django tests as a pytest fixture.", 894 | "name": "pytest-django-casperjs", 895 | "version": "0.1.0" 896 | }, 897 | { 898 | "description": "Pytest plugin used to setup environment variables with django-dotenv", 899 | "name": "pytest-django-dotenv", 900 | "version": "0.1.2" 901 | }, 902 | { 903 | "description": "Factories for your Django models that can be used as Pytest fixtures.", 904 | "name": "pytest-django-factories", 905 | "version": "0.2.3" 906 | }, 907 | { 908 | "description": "A Django plugin for pytest.", 909 | "name": "pytest-django-gcir", 910 | "version": "2.8.1" 911 | }, 912 | { 913 | "description": "Cleanup your Haystack indexes between tests", 914 | "name": "pytest-django-haystack", 915 | "version": "0.3.0" 916 | }, 917 | { 918 | "description": "A model instance factory for pytest-django", 919 | "name": "pytest-django-ifactory", 920 | "version": "0.3.0" 921 | }, 922 | { 923 | "description": "The bare minimum to integrate py.test with Django.", 924 | "name": "pytest-django-lite", 925 | "version": "0.1.1" 926 | }, 927 | { 928 | "description": "A Simple Way to Test your Django Models", 929 | "name": "pytest-django-model", 930 | "version": "0.1.9" 931 | }, 932 | { 933 | "description": "A pytest plugin for preserving the order in which Django runs tests.", 934 | "name": "pytest-django-ordering", 935 | "version": "1.2.0" 936 | }, 937 | { 938 | "description": "Generate performance reports from your django database performance tests.", 939 | "name": "pytest-django-queries", 940 | "version": "1.1.0" 941 | }, 942 | { 943 | "description": "A pytest plugin to help writing unit test for django-rq", 944 | "name": "pytest-django-rq", 945 | "version": "0.2.0" 946 | }, 947 | { 948 | "description": "py.test plugin for reporting the number of SQLs executed per django testcase.", 949 | "name": "pytest-django-sqlcounts", 950 | "version": "0.1.0" 951 | }, 952 | { 953 | "description": "Use a temporary PostgreSQL database with pytest-django", 954 | "name": "pytest-django-testing-postgresql", 955 | "version": "0.1.post0" 956 | }, 957 | { 958 | "description": "Nice pytest plugin to help you with Django pluggable application testing.", 959 | "name": "pytest-djangoapp", 960 | "version": "0.15.0" 961 | }, 962 | { 963 | "description": "A djangorestframework plugin for pytest", 964 | "name": "pytest-djangorestframework", 965 | "version": "0.1.2" 966 | }, 967 | { 968 | "description": "A documentation plugin for py.test.", 969 | "name": "pytest-doc", 970 | "version": "0.0.1" 971 | }, 972 | { 973 | "description": "An RST Documentation Generator for pytest-based test suites", 974 | "name": "pytest-docgen", 975 | "version": "1.3.0" 976 | }, 977 | { 978 | "description": "Simple pytest fixtures for Docker and docker-compose based tests", 979 | "name": "pytest-docker", 980 | "version": "0.10.1" 981 | }, 982 | { 983 | "description": "", 984 | "name": "pytest-docker-butla", 985 | "version": "0.7.0" 986 | }, 987 | { 988 | "description": "Manages Docker containers during your integration tests", 989 | "name": "pytest-docker-compose", 990 | "version": "3.2.0" 991 | }, 992 | { 993 | "description": "A plugin to use docker databases for pytests", 994 | "name": "pytest-docker-db", 995 | "version": "1.0.4" 996 | }, 997 | { 998 | "description": "pytest docker fixtures", 999 | "name": "pytest-docker-fixtures", 1000 | "version": "1.3.11" 1001 | }, 1002 | { 1003 | "description": "pytest plugin for writing functional tests with pexpect and docker", 1004 | "name": "pytest-docker-pexpect", 1005 | "version": "0.9" 1006 | }, 1007 | { 1008 | "description": "A simple plugin to use with pytest", 1009 | "name": "pytest-docker-postgresql", 1010 | "version": "0.1.0" 1011 | }, 1012 | { 1013 | "description": "Easy to use, simple to extend, pytest plugin that minimally leverages docker-py.", 1014 | "name": "pytest-docker-py", 1015 | "version": "1.1.3" 1016 | }, 1017 | { 1018 | "description": "Pytest fixtures for testing with docker registries.", 1019 | "name": "pytest-docker-registry-fixtures", 1020 | "version": "0.1.2" 1021 | }, 1022 | { 1023 | "description": "Docker integration tests for pytest", 1024 | "name": "pytest-docker-tools", 1025 | "version": "1.0.0" 1026 | }, 1027 | { 1028 | "description": "Run, manage and stop Docker Compose project from Docker API", 1029 | "name": "pytest-dockerc", 1030 | "version": "1.0.8" 1031 | }, 1032 | { 1033 | "description": "Documentation tool for pytest", 1034 | "name": "pytest-docs", 1035 | "version": "0.1.0" 1036 | }, 1037 | { 1038 | "description": "pytest plugin to run pydocstyle", 1039 | "name": "pytest-docstyle", 1040 | "version": "2.0.1" 1041 | }, 1042 | { 1043 | "description": "A py.test plugin for customizing string representations of doctest results.", 1044 | "name": "pytest-doctest-custom", 1045 | "version": "1.0.0" 1046 | }, 1047 | { 1048 | "description": "Setup additional values for ELLIPSIS_MARKER for doctests", 1049 | "name": "pytest-doctest-ellipsis-markers", 1050 | "version": "0.1.0" 1051 | }, 1052 | { 1053 | "description": "A simple pytest plugin to import names and add them to the doctest namespace.", 1054 | "name": "pytest-doctest-import", 1055 | "version": "0.1.1" 1056 | }, 1057 | { 1058 | "description": "A plugin to run doctests in docstrings of Numpy ufuncs", 1059 | "name": "pytest-doctest-ufunc", 1060 | "version": "0.1.3" 1061 | }, 1062 | { 1063 | "description": "Pytest plugin with advanced doctest features.", 1064 | "name": "pytest-doctestplus", 1065 | "version": "0.8.0" 1066 | }, 1067 | { 1068 | "description": "Some extra stuff that we use ininternally", 1069 | "name": "pytest-dolphin", 1070 | "version": "0.3.9" 1071 | }, 1072 | { 1073 | "description": "A pytest plugin for adding test results into doorstop items.", 1074 | "name": "pytest-doorstop", 1075 | "version": "1.0.0" 1076 | }, 1077 | { 1078 | "description": "A py.test plugin that parses environment files before running tests", 1079 | "name": "pytest-dotenv", 1080 | "version": "0.5.2" 1081 | }, 1082 | { 1083 | "description": "A Django REST framework plugin for pytest.", 1084 | "name": "pytest-drf", 1085 | "version": "1.1.2" 1086 | }, 1087 | { 1088 | "description": "A Pytest plugin to drop duplicated tests during collection", 1089 | "name": "pytest-drop-dup-tests", 1090 | "version": "0.3.0" 1091 | }, 1092 | { 1093 | "description": "A pytest plugin for dumping test results to json.", 1094 | "name": "pytest-dump2json", 1095 | "version": "0.1.0" 1096 | }, 1097 | { 1098 | "description": "A pytest plugin to rerun tests dynamically based off of test outcome and output.", 1099 | "name": "pytest-dynamicrerun", 1100 | "version": "1.1.1" 1101 | }, 1102 | { 1103 | "description": "DynamoDB fixtures for pytest", 1104 | "name": "pytest-dynamodb", 1105 | "version": "2.0.1" 1106 | }, 1107 | { 1108 | "description": "pytest-easy-addoption: Easy way to work with pytest addoption", 1109 | "name": "pytest-easy-addoption", 1110 | "version": "0.1.1" 1111 | }, 1112 | { 1113 | "description": "Simple API testing with pytest", 1114 | "name": "pytest-easy-api", 1115 | "version": "0.0.3" 1116 | }, 1117 | { 1118 | "description": "Package that supports mpi tests in pytest", 1119 | "name": "pytest-easyMPI", 1120 | "version": "0.0.1" 1121 | }, 1122 | { 1123 | "description": "pytest plugin that makes terminal printouts of the reports easier to read", 1124 | "name": "pytest-easyread", 1125 | "version": "0.1.0" 1126 | }, 1127 | { 1128 | "description": "Pytest execution on EC2 instance", 1129 | "name": "pytest-ec2", 1130 | "version": "0.1" 1131 | }, 1132 | { 1133 | "description": "pytest plugin with mechanisms for echoing environment variables, package version and generic attributes", 1134 | "name": "pytest-echo", 1135 | "version": "1.7.1" 1136 | }, 1137 | { 1138 | "description": "Elasticsearch process and client fixtures for py.test.", 1139 | "name": "pytest-elasticsearch", 1140 | "version": "2.0.1" 1141 | }, 1142 | { 1143 | "description": "A simple plugin to use with pytest", 1144 | "name": "pytest-elk-reporter", 1145 | "version": "0.1.10" 1146 | }, 1147 | { 1148 | "description": "Send execution result email", 1149 | "name": "pytest-email", 1150 | "version": "0.3" 1151 | }, 1152 | { 1153 | "description": "A pytest plugin that adds emojis to your test result report", 1154 | "name": "pytest-emoji", 1155 | "version": "0.2.0" 1156 | }, 1157 | { 1158 | "description": "Pytest plugin to represent test output with emoji support", 1159 | "name": "pytest-emoji-output", 1160 | "version": "0.1.7" 1161 | }, 1162 | { 1163 | "description": "Improvements for pytest (rejected upstream)", 1164 | "name": "pytest-enhancements", 1165 | "version": "0.0.4" 1166 | }, 1167 | { 1168 | "description": "py.test plugin that allows you to add environment variables.", 1169 | "name": "pytest-env", 1170 | "version": "0.6.2" 1171 | }, 1172 | { 1173 | "description": "Push information about the running pytest into envvars", 1174 | "name": "pytest-env-info", 1175 | "version": "0.3.0" 1176 | }, 1177 | { 1178 | "description": "", 1179 | "name": "pytest-env-yaml", 1180 | "version": "0.2.0" 1181 | }, 1182 | { 1183 | "description": "A py.test plugin that parses environment files before running tests", 1184 | "name": "pytest-envfiles", 1185 | "version": "0.1.0" 1186 | }, 1187 | { 1188 | "description": "py.test plugin that allows you to add environment variables.", 1189 | "name": "pytest-envraw", 1190 | "version": "0.1.1" 1191 | }, 1192 | { 1193 | "description": "Pytest plugin to validate use of envvars on your tests", 1194 | "name": "pytest-envvars", 1195 | "version": "1.2.1" 1196 | }, 1197 | { 1198 | "description": "pytest plugin to check for commented out code", 1199 | "name": "pytest-eradicate", 1200 | "version": "0.0.5" 1201 | }, 1202 | { 1203 | "description": "Pytest plugin to treat skipped tests a test failure", 1204 | "name": "pytest-error-for-skips", 1205 | "version": "2.0.2" 1206 | }, 1207 | { 1208 | "description": "PyTest plugin for testing Smart Contracts for Ethereum Virtual Machine (EVM).", 1209 | "name": "pytest-eth", 1210 | "version": "0.0.0.dev1" 1211 | }, 1212 | { 1213 | "description": "pytest-ethereum: Pytest library for ethereum projects.", 1214 | "name": "pytest-ethereum", 1215 | "version": "0.1.2" 1216 | }, 1217 | { 1218 | "description": "Pytest Plugin for BDD", 1219 | "name": "pytest-eucalyptus", 1220 | "version": "0.3.3" 1221 | }, 1222 | { 1223 | "description": "pytest plugin for generating excel reports", 1224 | "name": "pytest-excel", 1225 | "version": "1.4.2" 1226 | }, 1227 | { 1228 | "description": "Walk your code through exception script to check it's resiliency to failures.", 1229 | "name": "pytest-exception-script", 1230 | "version": "0.1.0" 1231 | }, 1232 | { 1233 | "description": "Better exceptions", 1234 | "name": "pytest-exceptional", 1235 | "version": "0.1.1" 1236 | }, 1237 | { 1238 | "description": "pytest plugin for testing executables", 1239 | "name": "pytest-executable", 1240 | "version": "0.5.2" 1241 | }, 1242 | { 1243 | "description": "py.test plugin to store test expectations and mark tests based on them", 1244 | "name": "pytest-expect", 1245 | "version": "1.1.0" 1246 | }, 1247 | { 1248 | "description": "Better testing with expecter and pytest.", 1249 | "name": "pytest-expecter", 1250 | "version": "2.2" 1251 | }, 1252 | { 1253 | "description": "This plugin is used to expect multiple assert using pytest framework.", 1254 | "name": "pytest-expectr", 1255 | "version": "1.4.2" 1256 | }, 1257 | { 1258 | "description": "Interactive console for pytest.", 1259 | "name": "pytest-exploratory", 1260 | "version": "0.1" 1261 | }, 1262 | { 1263 | "description": "a special outcome for tests that are blocked for external reasons", 1264 | "name": "pytest-external-blockers", 1265 | "version": "0.0.1" 1266 | }, 1267 | { 1268 | "description": "A pytest plugin to get durations on a per-function basis and per module basis.", 1269 | "name": "pytest-extra-durations", 1270 | "version": "0.1.3" 1271 | }, 1272 | { 1273 | "description": "Provides test utilities to run fabric task tests by using docker containers", 1274 | "name": "pytest-fabric", 1275 | "version": "1.0.0" 1276 | }, 1277 | { 1278 | "description": "Use factories for test setup with py.test", 1279 | "name": "pytest-factory", 1280 | "version": "0.0.1.dev0" 1281 | }, 1282 | { 1283 | "description": "Factory Boy support for pytest.", 1284 | "name": "pytest-factoryboy", 1285 | "version": "2.0.3" 1286 | }, 1287 | { 1288 | "description": "Generates pytest fixtures that allow the use of type hinting", 1289 | "name": "pytest-factoryboy-fixtures", 1290 | "version": "0.1" 1291 | }, 1292 | { 1293 | "description": "A pytest plugin that helps better distinguishing real test failures from setup flakiness.", 1294 | "name": "pytest-failed-to-verify", 1295 | "version": "0.1.5" 1296 | }, 1297 | { 1298 | "description": "Faker integration with the pytest framework.", 1299 | "name": "pytest-faker", 1300 | "version": "2.0.0" 1301 | }, 1302 | { 1303 | "description": "Pytest helpers for Falcon.", 1304 | "name": "pytest-falcon", 1305 | "version": "0.4.2" 1306 | }, 1307 | { 1308 | "description": "Pytest `client` fixture for the Falcon Framework", 1309 | "name": "pytest-falcon-client", 1310 | "version": "2.0.1" 1311 | }, 1312 | { 1313 | "description": "Pytest plugin for Flask Fantasy Framework", 1314 | "name": "pytest-fantasy", 1315 | "version": "0.2.15" 1316 | }, 1317 | { 1318 | "description": "Use SCM and coverage to run only needed tests", 1319 | "name": "pytest-fastest", 1320 | "version": "0.0.10" 1321 | }, 1322 | { 1323 | "description": "py.test plugin that activates the fault handler module for tests (dummy package)", 1324 | "name": "pytest-faulthandler", 1325 | "version": "2.0.1" 1326 | }, 1327 | { 1328 | "description": "Integration of fauxfactory into pytest.", 1329 | "name": "pytest-fauxfactory", 1330 | "version": "1.1.1" 1331 | }, 1332 | { 1333 | "description": "py.test figleaf coverage plugin", 1334 | "name": "pytest-figleaf", 1335 | "version": "1.0" 1336 | }, 1337 | { 1338 | "description": "easily load data from files", 1339 | "name": "pytest-filedata", 1340 | "version": "0.4.0" 1341 | }, 1342 | { 1343 | "description": "A pytest plugin that runs marked tests when files change.", 1344 | "name": "pytest-filemarker", 1345 | "version": "0.1.0.dev4" 1346 | }, 1347 | { 1348 | "description": "run test cases filter by mark", 1349 | "name": "pytest-filter-case", 1350 | "version": "1.3.2" 1351 | }, 1352 | { 1353 | "description": "Pytest plugin for filtering based on sub-packages", 1354 | "name": "pytest-filter-subpackage", 1355 | "version": "0.1.1" 1356 | }, 1357 | { 1358 | "description": "A pytest plugin to treat non-assertion failures as test errors.", 1359 | "name": "pytest-finer-verdicts", 1360 | "version": "1.0.6.post1" 1361 | }, 1362 | { 1363 | "description": "pytest plugin to manipulate firefox", 1364 | "name": "pytest-firefox", 1365 | "version": "0.1.1" 1366 | }, 1367 | { 1368 | "description": "Fixture configuration utils for py.test", 1369 | "name": "pytest-fixture-config", 1370 | "version": "1.7.0" 1371 | }, 1372 | { 1373 | "description": "A pytest plugin to add markers based on fixtures used.", 1374 | "name": "pytest-fixture-marker", 1375 | "version": "1.0.0" 1376 | }, 1377 | { 1378 | "description": "pytest plugin to control fixture evaluation order", 1379 | "name": "pytest-fixture-order", 1380 | "version": "0.1.3" 1381 | }, 1382 | { 1383 | "description": "Plugin for pytest which provides tools for fixtures", 1384 | "name": "pytest-fixture-tools", 1385 | "version": "1.1.0" 1386 | }, 1387 | { 1388 | "description": "Common fixtures for pytest", 1389 | "name": "pytest-fixtures", 1390 | "version": "0.1.0" 1391 | }, 1392 | { 1393 | "description": "pytest plugin to check FLAKE8 requirements", 1394 | "name": "pytest-flake8", 1395 | "version": "1.0.6" 1396 | }, 1397 | { 1398 | "description": "A pytest fixture for testing flake8 plugins.", 1399 | "name": "pytest-flake8dir", 1400 | "version": "2.2.0" 1401 | }, 1402 | { 1403 | "description": "Runs tests multiple times to expose flakiness.", 1404 | "name": "pytest-flakefinder", 1405 | "version": "1.0.0" 1406 | }, 1407 | { 1408 | "description": "pytest plugin to check source code with pyflakes", 1409 | "name": "pytest-flakes", 1410 | "version": "4.0.2" 1411 | }, 1412 | { 1413 | "description": "Flaptastic py.test plugin", 1414 | "name": "pytest-flaptastic", 1415 | "version": "0.0.25" 1416 | }, 1417 | { 1418 | "description": "A set of py.test fixtures to test Flask applications.", 1419 | "name": "pytest-flask", 1420 | "version": "1.1.0" 1421 | }, 1422 | { 1423 | "description": "A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions.", 1424 | "name": "pytest-flask-sqlalchemy", 1425 | "version": "1.0.2" 1426 | }, 1427 | { 1428 | "description": "Run tests in transactions using pytest, Flask, and SQLalchemy.", 1429 | "name": "pytest-flask-sqlalchemy-transactions", 1430 | "version": "1.0.2" 1431 | }, 1432 | { 1433 | "description": "A pytest plugin that alerts user of failed test cases with screen notifications", 1434 | "name": "pytest-focus", 1435 | "version": "0.1.1" 1436 | }, 1437 | { 1438 | "description": "py.test plugin to make the test failing regardless of pytest.mark.xfail", 1439 | "name": "pytest-forcefail", 1440 | "version": "0.0.0.3" 1441 | }, 1442 | { 1443 | "description": "run tests in isolated forked subprocesses", 1444 | "name": "pytest-forked", 1445 | "version": "1.3.0" 1446 | }, 1447 | { 1448 | "description": "A name to avoid typosquating pytest-foward-compatibility", 1449 | "name": "pytest-forward-compatability", 1450 | "version": "0.1.0" 1451 | }, 1452 | { 1453 | "description": "A pytest plugin to shim pytest commandline options for fowards compatibility", 1454 | "name": "pytest-forward-compatibility", 1455 | "version": "0.1.1" 1456 | }, 1457 | { 1458 | "description": "Check if requirement files are frozen", 1459 | "name": "pytest-freeze-reqs", 1460 | "version": "0.1.8" 1461 | }, 1462 | { 1463 | "description": "Wrap tests with fixtures in freeze_time", 1464 | "name": "pytest-freezegun", 1465 | "version": "0.4.2" 1466 | }, 1467 | { 1468 | "description": "Pytest plugin for measuring function coverage", 1469 | "name": "pytest-func-cov", 1470 | "version": "0.2.2" 1471 | }, 1472 | { 1473 | "description": "pytest plugin for Firefox Accounts", 1474 | "name": "pytest-fxa", 1475 | "version": "1.4.0" 1476 | }, 1477 | { 1478 | "description": "", 1479 | "name": "pytest-fxtest", 1480 | "version": "0.1.0" 1481 | }, 1482 | { 1483 | "description": "The garbage collector plugin for py.test", 1484 | "name": "pytest-gc", 1485 | "version": "0.0.1" 1486 | }, 1487 | { 1488 | "description": "Uses gcov to measure test coverage of a C library", 1489 | "name": "pytest-gcov", 1490 | "version": "0.0.1-alpha" 1491 | }, 1492 | { 1493 | "description": "Ensure that gevent is properly patched when invoking pytest", 1494 | "name": "pytest-gevent", 1495 | "version": "1.1.0" 1496 | }, 1497 | { 1498 | "description": "A flexible framework for executing BDD gherkin tests", 1499 | "name": "pytest-gherkin", 1500 | "version": "0.1.7" 1501 | }, 1502 | { 1503 | "description": "For finding/executing Ghost Inspector tests", 1504 | "name": "pytest-ghostinspector", 1505 | "version": "0.4.0" 1506 | }, 1507 | { 1508 | "description": "A set of pytest fixtures for testing Girder applications.", 1509 | "name": "pytest-girder", 1510 | "version": "3.1.3" 1511 | }, 1512 | { 1513 | "description": "Git repository fixture for py.test", 1514 | "name": "pytest-git", 1515 | "version": "1.7.0" 1516 | }, 1517 | { 1518 | "description": "Pytest plugin for reporting on coverage of the last git commit.", 1519 | "name": "pytest-gitcov", 1520 | "version": "0.1.5" 1521 | }, 1522 | { 1523 | "description": "Plugin for py.test that associates tests with github issues using a marker.", 1524 | "name": "pytest-github", 1525 | "version": "0.3.1" 1526 | }, 1527 | { 1528 | "description": "pytest plugin to annotate failed tests with a workflow command for GitHub Actions", 1529 | "name": "pytest-github-actions-annotate-failures", 1530 | "version": "0.1.1" 1531 | }, 1532 | { 1533 | "description": "py.test plugin to ignore the same files as git", 1534 | "name": "pytest-gitignore", 1535 | "version": "1.3" 1536 | }, 1537 | { 1538 | "description": "Plugin for pytest that offloads expected outputs to data files", 1539 | "name": "pytest-golden", 1540 | "version": "0.2.1" 1541 | }, 1542 | { 1543 | "description": "Get graphql schema as fixture for pytest", 1544 | "name": "pytest-graphql-schema", 1545 | "version": "0.0.2" 1546 | }, 1547 | { 1548 | "description": "Green progress dots", 1549 | "name": "pytest-greendots", 1550 | "version": "0.3" 1551 | }, 1552 | { 1553 | "description": "Growl notifications for pytest results.", 1554 | "name": "pytest-growl", 1555 | "version": "0.2" 1556 | }, 1557 | { 1558 | "description": "pytest plugin for grpc", 1559 | "name": "pytest-grpc", 1560 | "version": "0.8.0" 1561 | }, 1562 | { 1563 | "description": "Display \"🔨 \" instead of \".\" for passed pytest tests.", 1564 | "name": "pytest-hammertime", 1565 | "version": "1.1.1" 1566 | }, 1567 | { 1568 | "description": "Store data created during your pytest tests execution, and retrieve it at the end of the session, e.g. for applicative benchmarking purposes.", 1569 | "name": "pytest-harvest", 1570 | "version": "1.10.0" 1571 | }, 1572 | { 1573 | "description": "A plugin to provide different types and configs of Kubernetes clusters that can be used for testing.", 1574 | "name": "pytest-helm-chart", 1575 | "version": "0.1.1" 1576 | }, 1577 | { 1578 | "description": "A plugin to provide different types and configs of Kubernetes clusters that can be used for testing.", 1579 | "name": "pytest-helm-charts", 1580 | "version": "0.2.1" 1581 | }, 1582 | { 1583 | "description": "Functions to help in using the pytest testing framework", 1584 | "name": "pytest-helper", 1585 | "version": "0.2.2" 1586 | }, 1587 | { 1588 | "description": "pytest helpers", 1589 | "name": "pytest-helpers", 1590 | "version": "0.1.0" 1591 | }, 1592 | { 1593 | "description": "PyTest Helpers Namespace", 1594 | "name": "pytest-helpers-namespace", 1595 | "version": "2019.1.8" 1596 | }, 1597 | { 1598 | "description": "Hide captured output", 1599 | "name": "pytest-hidecaptured", 1600 | "version": "0.2.2" 1601 | }, 1602 | { 1603 | "description": "Custom report to display pytest historical execution records", 1604 | "name": "pytest-historic", 1605 | "version": "0.1.2" 1606 | }, 1607 | { 1608 | "description": "Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report", 1609 | "name": "pytest-historic-hook", 1610 | "version": "0.1.2" 1611 | }, 1612 | { 1613 | "description": "A pytest plugin for use with homeassistant custom components.", 1614 | "name": "pytest-homeassistant", 1615 | "version": "0.1.3" 1616 | }, 1617 | { 1618 | "description": "Experimental package to automatically extract test plugins for Home Assistant custom components", 1619 | "name": "pytest-homeassistant-custom-component", 1620 | "version": "0.0.21" 1621 | }, 1622 | { 1623 | "description": "Report on tests that honor constraints, and guard against regressions", 1624 | "name": "pytest-honors", 1625 | "version": "0.1.5" 1626 | }, 1627 | { 1628 | "description": "Integrates the Hoverfly HTTP proxy into Pytest", 1629 | "name": "pytest-hoverfly-wrapper", 1630 | "version": "0.4.0" 1631 | }, 1632 | { 1633 | "description": "pytest plugin for generating HTML reports", 1634 | "name": "pytest-html", 1635 | "version": "3.0.0" 1636 | }, 1637 | { 1638 | "description": "optimized pytest plugin for generating HTML reports", 1639 | "name": "pytest-html-lee", 1640 | "version": "0.0.1" 1641 | }, 1642 | { 1643 | "description": "Pytest plugin for generating HTML reports with per-test profiling and optionally call graph visualizations. Based on pytest-html by Dave Hunt.", 1644 | "name": "pytest-html-profiling", 1645 | "version": "1.0.0" 1646 | }, 1647 | { 1648 | "description": "Generates a static html report based on pytest framework", 1649 | "name": "pytest-html-reporter", 1650 | "version": "0.2.3" 1651 | }, 1652 | { 1653 | "description": "Fixture \"http\" for http requests", 1654 | "name": "pytest-http", 1655 | "version": "0.1" 1656 | }, 1657 | { 1658 | "description": "Pytest plugin for http mocking (via https://github.com/vilus/mocker)", 1659 | "name": "pytest-http-mocker", 1660 | "version": "0.0.1" 1661 | }, 1662 | { 1663 | "description": "Easily test your HTTP library against a local copy of httpbin", 1664 | "name": "pytest-httpbin", 1665 | "version": "1.0.0" 1666 | }, 1667 | { 1668 | "description": "A thin wrapper of HTTPretty for pytest", 1669 | "name": "pytest-httpretty", 1670 | "version": "0.2.0" 1671 | }, 1672 | { 1673 | "description": "pytest-httpserver is a httpserver for pytest", 1674 | "name": "pytest-httpserver", 1675 | "version": "0.3.6" 1676 | }, 1677 | { 1678 | "description": "Send responses to httpx.", 1679 | "name": "pytest-httpx", 1680 | "version": "0.10.1" 1681 | }, 1682 | { 1683 | "description": "Visualise PyTest status via your Phillips Hue lights", 1684 | "name": "pytest-hue", 1685 | "version": "1.0.0" 1686 | }, 1687 | { 1688 | "description": "help hypo module for pytest", 1689 | "name": "pytest-hypo-25", 1690 | "version": "2.3" 1691 | }, 1692 | { 1693 | "description": "A plugin to sent pytest results to an Ibutsu server", 1694 | "name": "pytest-ibutsu", 1695 | "version": "1.12" 1696 | }, 1697 | { 1698 | "description": "use icdiff for better error messages in pytest assertions", 1699 | "name": "pytest-icdiff", 1700 | "version": "0.5" 1701 | }, 1702 | { 1703 | "description": "A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api", 1704 | "name": "pytest-idapro", 1705 | "version": "0.4.3" 1706 | }, 1707 | { 1708 | "description": "ignore failures from flaky tests (pytest plugin)", 1709 | "name": "pytest-ignore-flaky", 1710 | "version": "1.0.0" 1711 | }, 1712 | { 1713 | "description": "", 1714 | "name": "pytest-image-diff", 1715 | "version": "0.0.3" 1716 | }, 1717 | { 1718 | "description": "an incremental test runner (pytest plugin)", 1719 | "name": "pytest-incremental", 1720 | "version": "0.5.0" 1721 | }, 1722 | { 1723 | "description": "Plugin for influxdb and pytest integration.", 1724 | "name": "pytest-influxdb", 1725 | "version": "0.0.31" 1726 | }, 1727 | { 1728 | "description": "pytest plugin to collect information from tests", 1729 | "name": "pytest-info-collector", 1730 | "version": "0.3" 1731 | }, 1732 | { 1733 | "description": "display more node ininformation.", 1734 | "name": "pytest-informative-node", 1735 | "version": "1.0.0" 1736 | }, 1737 | { 1738 | "description": "pytest stack validation prior to testing executing", 1739 | "name": "pytest-infrastructure", 1740 | "version": "0.0.2" 1741 | }, 1742 | { 1743 | "description": "A py.test plugin providing fixtures to simplify inmanta modules testing.", 1744 | "name": "pytest-inmanta", 1745 | "version": "1.4.0" 1746 | }, 1747 | { 1748 | "description": "Inmanta tests package", 1749 | "name": "pytest-inmanta-extensions", 1750 | "version": "2020.5.1" 1751 | }, 1752 | { 1753 | "description": "A practical snapshot testing plugin for pytest", 1754 | "name": "pytest-insta", 1755 | "version": "0.1.1" 1756 | }, 1757 | { 1758 | "description": "pytest plugin to show failures instantly", 1759 | "name": "pytest-instafail", 1760 | "version": "0.4.2" 1761 | }, 1762 | { 1763 | "description": "pytest plugin to instrument tests", 1764 | "name": "pytest-instrument", 1765 | "version": "0.3.1" 1766 | }, 1767 | { 1768 | "description": "Organizing pytests by integration or not", 1769 | "name": "pytest-integration", 1770 | "version": "0.2.2" 1771 | }, 1772 | { 1773 | "description": "A pytest plugin for console based interactive test selection just after the collection phase", 1774 | "name": "pytest-interactive", 1775 | "version": "0.1.4" 1776 | }, 1777 | { 1778 | "description": "Pytest fixtures for Invenio.", 1779 | "name": "pytest-invenio", 1780 | "version": "1.4.0" 1781 | }, 1782 | { 1783 | "description": "Run tests covering a specific file or changeset", 1784 | "name": "pytest-involve", 1785 | "version": "0.1.4" 1786 | }, 1787 | { 1788 | "description": "A py.test plug-in to enable drop to ipdb debugger on test failure.", 1789 | "name": "pytest-ipdb", 1790 | "version": "0.1-prerelease2" 1791 | }, 1792 | { 1793 | "description": "THIS PROJECT IS ABANDONED", 1794 | "name": "pytest-ipynb", 1795 | "version": "1.1.1" 1796 | }, 1797 | { 1798 | "description": "py.test plugin to check import ordering using isort", 1799 | "name": "pytest-isort", 1800 | "version": "1.2.0" 1801 | }, 1802 | { 1803 | "description": "Pytest plugin to display test reports as a plaintext spec, inspired by Rspec: https://github.com/mattduck/pytest-it.", 1804 | "name": "pytest-it", 1805 | "version": "0.1.4" 1806 | }, 1807 | { 1808 | "description": "Nicer list and iterable assertion messages for pytest", 1809 | "name": "pytest-iterassert", 1810 | "version": "0.0.3" 1811 | }, 1812 | { 1813 | "description": "Run jasmine tests from your pytest test suite", 1814 | "name": "pytest-jasmine", 1815 | "version": "0.0.2" 1816 | }, 1817 | { 1818 | "description": "A custom jest-pytest oriented Pytest reporter", 1819 | "name": "pytest-jest", 1820 | "version": "0.3.0" 1821 | }, 1822 | { 1823 | "description": "py.test JIRA integration plugin, using markers", 1824 | "name": "pytest-jira", 1825 | "version": "0.3.15" 1826 | }, 1827 | { 1828 | "description": "Limit parallel tests with posix jobserver.", 1829 | "name": "pytest-jobserver", 1830 | "version": "1.0.0" 1831 | }, 1832 | { 1833 | "description": "Test failures are better served with humor.", 1834 | "name": "pytest-joke", 1835 | "version": "0.1.1" 1836 | }, 1837 | { 1838 | "description": "Generate JSON test reports", 1839 | "name": "pytest-json", 1840 | "version": "0.4.0" 1841 | }, 1842 | { 1843 | "description": "A pytest plugin to report test results as JSON files", 1844 | "name": "pytest-json-report", 1845 | "version": "1.2.4" 1846 | }, 1847 | { 1848 | "description": "UNKNOWN", 1849 | "name": "pytest-jsonlint", 1850 | "version": "0.0.1" 1851 | }, 1852 | { 1853 | "description": "A pytest plugin for testing Jupyter libraries and extensions.", 1854 | "name": "pytest-jupyter", 1855 | "version": "0.0.1" 1856 | }, 1857 | { 1858 | "description": "Zookeeper, Kafka server, and Kafka consumer fixtures for Pytest", 1859 | "name": "pytest-kafka", 1860 | "version": "0.4.0" 1861 | }, 1862 | { 1863 | "description": "Kubernetes test support with KIND for pytest", 1864 | "name": "pytest-kind", 1865 | "version": "20.10.0" 1866 | }, 1867 | { 1868 | "description": "A pytest plugin that can automaticly skip test case based on dependence info calculated by trace", 1869 | "name": "pytest-knows", 1870 | "version": "0.1.5" 1871 | }, 1872 | { 1873 | "description": "Run Konira DSL tests with py.test", 1874 | "name": "pytest-konira", 1875 | "version": "0.2" 1876 | }, 1877 | { 1878 | "description": "pytest krtech common library", 1879 | "name": "pytest-krtech-common", 1880 | "version": "0.1.35" 1881 | }, 1882 | { 1883 | "description": "Define pytest fixtures with lambda functions.", 1884 | "name": "pytest-lambda", 1885 | "version": "1.2.3" 1886 | }, 1887 | { 1888 | "description": "", 1889 | "name": "pytest-lamp", 1890 | "version": "0.1.0" 1891 | }, 1892 | { 1893 | "description": "Pytest fixtures for layab.", 1894 | "name": "pytest-layab", 1895 | "version": "2.0.0" 1896 | }, 1897 | { 1898 | "description": "It helps to use fixtures in pytest.mark.parametrize", 1899 | "name": "pytest-lazy-fixture", 1900 | "version": "0.6.3" 1901 | }, 1902 | { 1903 | "description": "python-ldap fixtures for pytest", 1904 | "name": "pytest-ldap", 1905 | "version": "0.0.1" 1906 | }, 1907 | { 1908 | "description": "A pytest plugin to trace resource leaks.", 1909 | "name": "pytest-leaks", 1910 | "version": "0.3.1" 1911 | }, 1912 | { 1913 | "description": "Select tests of a given level or lower", 1914 | "name": "pytest-level", 1915 | "version": "0.1.3" 1916 | }, 1917 | { 1918 | "description": "A python-libfaketime plugin for pytest.", 1919 | "name": "pytest-libfaketime", 1920 | "version": "0.1.2" 1921 | }, 1922 | { 1923 | "description": "A pytest plugin to manage interfacing with libiio contexts", 1924 | "name": "pytest-libiio", 1925 | "version": "0.0.2" 1926 | }, 1927 | { 1928 | "description": "Pytest plugin that shows notifications about the test run", 1929 | "name": "pytest-libnotify", 1930 | "version": "1.0.0" 1931 | }, 1932 | { 1933 | "description": "", 1934 | "name": "pytest-ligo", 1935 | "version": "0.1.3" 1936 | }, 1937 | { 1938 | "description": "A simple network listener", 1939 | "name": "pytest-listener", 1940 | "version": "1.7.0" 1941 | }, 1942 | { 1943 | "description": "A pytest plugin that stream output in LITF format", 1944 | "name": "pytest-litf", 1945 | "version": "0.1.5" 1946 | }, 1947 | { 1948 | "description": "Live results for pytest", 1949 | "name": "pytest-live", 1950 | "version": "0.6" 1951 | }, 1952 | { 1953 | "description": "A PyTest plugin which provides an FTP fixture for your tests", 1954 | "name": "pytest-localftpserver", 1955 | "version": "1.0.1" 1956 | }, 1957 | { 1958 | "description": "py.test plugin to test server connections locally.", 1959 | "name": "pytest-localserver", 1960 | "version": "0.5.0" 1961 | }, 1962 | { 1963 | "description": "Pytest plugin for AWS integration tests", 1964 | "name": "pytest-localstack", 1965 | "version": "0.4.1" 1966 | }, 1967 | { 1968 | "description": "lockable resource plugin for pytest", 1969 | "name": "pytest-lockable", 1970 | "version": "0.6.0" 1971 | }, 1972 | { 1973 | "description": " Used to lock object during testing. Essentially changing assertions from being hard coded to asserting that nothing changed ", 1974 | "name": "pytest-locker", 1975 | "version": "0.2.4" 1976 | }, 1977 | { 1978 | "description": "Package for creating a pytest test run reprot", 1979 | "name": "pytest-log-report", 1980 | "version": "1.0.1" 1981 | }, 1982 | { 1983 | "description": "py.test plugin to capture logbook log messages", 1984 | "name": "pytest-logbook", 1985 | "version": "1.2.0" 1986 | }, 1987 | { 1988 | "description": "Pytest plugin providing three logger fixtures with basic or full writing to log files", 1989 | "name": "pytest-logfest", 1990 | "version": "0.3.0" 1991 | }, 1992 | { 1993 | "description": "Plugin configuring handlers for loggers from Python logging module.", 1994 | "name": "pytest-logger", 1995 | "version": "0.5.1" 1996 | }, 1997 | { 1998 | "description": "Configures logging and allows tweaking the log level with a py.test flag", 1999 | "name": "pytest-logging", 2000 | "version": "2015.11.4" 2001 | }, 2002 | { 2003 | "description": "pytest marker for marking manual tests", 2004 | "name": "pytest-manual-marker", 2005 | "version": "0.1" 2006 | }, 2007 | { 2008 | "description": "pytest plugin and bowler codemod to help migrate tests to Python 3", 2009 | "name": "pytest-mark-no-py3", 2010 | "version": "0.1.0" 2011 | }, 2012 | { 2013 | "description": "Docker integration tests for pytest", 2014 | "name": "pytest-markdown", 2015 | "version": "1.0.0" 2016 | }, 2017 | { 2018 | "description": "py.test bugzilla integration plugin, using markers", 2019 | "name": "pytest-marker-bugzilla", 2020 | "version": "0.9.4" 2021 | }, 2022 | { 2023 | "description": "A simple plugin to detect missed pytest tags and markers\"", 2024 | "name": "pytest-markers-presence", 2025 | "version": "0.10.0" 2026 | }, 2027 | { 2028 | "description": "UNKNOWN", 2029 | "name": "pytest-markfiltration", 2030 | "version": "0.8" 2031 | }, 2032 | { 2033 | "description": "UNKNOWN", 2034 | "name": "pytest-marks", 2035 | "version": "0.4" 2036 | }, 2037 | { 2038 | "description": "Skip matching marks. Matches partial marks using wildcards.", 2039 | "name": "pytest-match-skip", 2040 | "version": "0.2.1" 2041 | }, 2042 | { 2043 | "description": "Match test output against patterns stored in files", 2044 | "name": "pytest-matcher", 2045 | "version": "1.3.5" 2046 | }, 2047 | { 2048 | "description": "Provide tools for generating tests from combinations of fixtures.", 2049 | "name": "pytest-matrix", 2050 | "version": "0.7.7" 2051 | }, 2052 | { 2053 | "description": "pytest plugin to run the mccabe code complexity checker.", 2054 | "name": "pytest-mccabe", 2055 | "version": "2.0" 2056 | }, 2057 | { 2058 | "description": "Plugin for generating Markdown reports for pytest results", 2059 | "name": "pytest-md", 2060 | "version": "0.2.0" 2061 | }, 2062 | { 2063 | "description": "A pytest plugin to make a test results report with Markdown table format.", 2064 | "name": "pytest-md-report", 2065 | "version": "0.1.1" 2066 | }, 2067 | { 2068 | "description": "Estimates memory consumption of test functions", 2069 | "name": "pytest-memprof", 2070 | "version": "0.2.0" 2071 | }, 2072 | { 2073 | "description": "A pytest plugin for console based interactive test selection just after the collection phase", 2074 | "name": "pytest-menu", 2075 | "version": "0.0.4" 2076 | }, 2077 | { 2078 | "description": "pytest plugin to write integration tests for projects using Mercurial Python internals", 2079 | "name": "pytest-mercurial", 2080 | "version": "0.1.0" 2081 | }, 2082 | { 2083 | "description": "pytest plugin for test session metadata", 2084 | "name": "pytest-metadata", 2085 | "version": "1.10.0" 2086 | }, 2087 | { 2088 | "description": "Custom metrics report for pytest", 2089 | "name": "pytest-metrics", 2090 | "version": "0.4" 2091 | }, 2092 | { 2093 | "description": "Mimesis integration with the pytest test runner", 2094 | "name": "pytest-mimesis", 2095 | "version": "1.1.0" 2096 | }, 2097 | { 2098 | "description": "A pytest plugin for running tests against Minecraft releases", 2099 | "name": "pytest-minecraft", 2100 | "version": "0.1.1" 2101 | }, 2102 | { 2103 | "description": "Pytest plugin that creates missing fixtures", 2104 | "name": "pytest-missing-fixtures", 2105 | "version": "0.1.0" 2106 | }, 2107 | { 2108 | "description": "Test your machine learning!", 2109 | "name": "pytest-ml", 2110 | "version": "0.1.0" 2111 | }, 2112 | { 2113 | "description": "pytest plugin to display test execution output like a mochajs", 2114 | "name": "pytest-mocha", 2115 | "version": "0.4.0" 2116 | }, 2117 | { 2118 | "description": "Thin-wrapper around the mock package for easier use with pytest", 2119 | "name": "pytest-mock", 2120 | "version": "3.3.1" 2121 | }, 2122 | { 2123 | "description": "A mock API server with configurable routes and responses available as a fixture.", 2124 | "name": "pytest-mock-api", 2125 | "version": "0.1.0" 2126 | }, 2127 | { 2128 | "description": "Help you mock HTTP call and generate mock code", 2129 | "name": "pytest-mock-helper", 2130 | "version": "0.2.1" 2131 | }, 2132 | { 2133 | "description": "A pytest plugin for easily instantiating reproducible mock resources.", 2134 | "name": "pytest-mock-resources", 2135 | "version": "1.4.1" 2136 | }, 2137 | { 2138 | "description": "Mock server plugin for pytest", 2139 | "name": "pytest-mock-server", 2140 | "version": "0.2.0" 2141 | }, 2142 | { 2143 | "description": "Base fixtures for mockito", 2144 | "name": "pytest-mockito", 2145 | "version": "0.0.4" 2146 | }, 2147 | { 2148 | "description": "An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database.", 2149 | "name": "pytest-mockredis", 2150 | "version": "0.1.6" 2151 | }, 2152 | { 2153 | "description": "A set of fixtures to test your requests to HTTP/UDP servers", 2154 | "name": "pytest-mockservers", 2155 | "version": "0.6.0" 2156 | }, 2157 | { 2158 | "description": "Utility for adding additional properties to junit xml for IDM QE", 2159 | "name": "pytest-modifyjunit", 2160 | "version": "1.5.post0" 2161 | }, 2162 | { 2163 | "description": "pytest plugin to modify fixture scope", 2164 | "name": "pytest-modifyscope", 2165 | "version": "0.3.0" 2166 | }, 2167 | { 2168 | "description": "PyTest Molecule Plugin :: discover and run molecule tests", 2169 | "name": "pytest-molecule", 2170 | "version": "1.3.3" 2171 | }, 2172 | { 2173 | "description": "MongoDB process and client fixtures plugin for py.test.", 2174 | "name": "pytest-mongo", 2175 | "version": "2.0.0" 2176 | }, 2177 | { 2178 | "description": "pytest plugin for MongoDB fixtures", 2179 | "name": "pytest-mongodb", 2180 | "version": "2.2.0" 2181 | }, 2182 | { 2183 | "description": "Pytest plugin for analyzing resource usage.", 2184 | "name": "pytest-monitor", 2185 | "version": "1.5.0" 2186 | }, 2187 | { 2188 | "description": "pytest's monkeypatch subclass with extra functionalities", 2189 | "name": "pytest-monkeyplus", 2190 | "version": "1.1.0" 2191 | }, 2192 | { 2193 | "description": "pytest-monkeytype: Generate Monkeytype annotations from your pytest tests.", 2194 | "name": "pytest-monkeytype", 2195 | "version": "1.1.0" 2196 | }, 2197 | { 2198 | "description": "Fixtures for integration tests of AWS services,uses moto mocking library.", 2199 | "name": "pytest-moto", 2200 | "version": "0.2.0" 2201 | }, 2202 | { 2203 | "description": "Mozilla WebQA plugin for py.test.", 2204 | "name": "pytest-mozwebqa", 2205 | "version": "2.0" 2206 | }, 2207 | { 2208 | "description": "A test batcher for multiprocessed Pytest runs", 2209 | "name": "pytest-mp", 2210 | "version": "0.0.4" 2211 | }, 2212 | { 2213 | "description": "pytest plugin to collect information from tests", 2214 | "name": "pytest-mpi", 2215 | "version": "0.4" 2216 | }, 2217 | { 2218 | "description": "pytest plugin to help with testing figures output from Matplotlib", 2219 | "name": "pytest-mpl", 2220 | "version": "0.12" 2221 | }, 2222 | { 2223 | "description": "low-startup-overhead, scalable, distributed-testing pytest plugin", 2224 | "name": "pytest-mproc", 2225 | "version": "4.0.4" 2226 | }, 2227 | { 2228 | "description": "Utility for writing multi-host tests for pytest", 2229 | "name": "pytest-multihost", 2230 | "version": "3.4" 2231 | }, 2232 | { 2233 | "description": "Multi-process logs handling and other helpers for pytest", 2234 | "name": "pytest-multilog", 2235 | "version": "1.1" 2236 | }, 2237 | { 2238 | "description": "Add the mutation testing feature to pytest", 2239 | "name": "pytest-mutagen", 2240 | "version": "1.3" 2241 | }, 2242 | { 2243 | "description": "Mypy static type checker plugin for Pytest", 2244 | "name": "pytest-mypy", 2245 | "version": "0.8.0" 2246 | }, 2247 | { 2248 | "description": "pytest plugin for writing tests for mypy plugins", 2249 | "name": "pytest-mypy-plugins", 2250 | "version": "1.6.1" 2251 | }, 2252 | { 2253 | "description": "Pytest plugin to check mypy output.", 2254 | "name": "pytest-mypy-testing", 2255 | "version": "0.0.7" 2256 | }, 2257 | { 2258 | "description": "Mypy static type checker plugin for Pytest", 2259 | "name": "pytest-mypyd", 2260 | "version": "0.3.5" 2261 | }, 2262 | { 2263 | "description": "MySQL process and client fixtures for pytest", 2264 | "name": "pytest-mysql", 2265 | "version": "2.0.3" 2266 | }, 2267 | { 2268 | "description": "pytest plugin for visual testing websites using selenium", 2269 | "name": "pytest-needle", 2270 | "version": "0.3.11" 2271 | }, 2272 | { 2273 | "description": "pytest-neo is a plugin for pytest that shows tests like screen of Matrix.", 2274 | "name": "pytest-neo", 2275 | "version": "0.2.1" 2276 | }, 2277 | { 2278 | "description": "A simple plugin to disable network on socket level.", 2279 | "name": "pytest-network", 2280 | "version": "0.0.1" 2281 | }, 2282 | { 2283 | "description": "nginx fixture for pytest", 2284 | "name": "pytest-nginx", 2285 | "version": "1.1" 2286 | }, 2287 | { 2288 | "description": "nginx fixture for pytest - iplweb temporary fork", 2289 | "name": "pytest-nginx-iplweb", 2290 | "version": "1.1.1" 2291 | }, 2292 | { 2293 | "description": "", 2294 | "name": "pytest-ngrok", 2295 | "version": "0.0.3" 2296 | }, 2297 | { 2298 | "description": "pytest ngs fixtures", 2299 | "name": "pytest-ngsfixtures", 2300 | "version": "0.8.1" 2301 | }, 2302 | { 2303 | "description": "A pytest plugin that alerts user of failed test cases with screen notifications", 2304 | "name": "pytest-nice", 2305 | "version": "0.1.0" 2306 | }, 2307 | { 2308 | "description": "Run all tests without custom markers", 2309 | "name": "pytest-nocustom", 2310 | "version": "1.0" 2311 | }, 2312 | { 2313 | "description": "Test-driven source code search for Python.", 2314 | "name": "pytest-nodev", 2315 | "version": "1.0.1" 2316 | }, 2317 | { 2318 | "description": "A pytest plugin for testing Jupyter Notebooks", 2319 | "name": "pytest-notebook", 2320 | "version": "0.6.1" 2321 | }, 2322 | { 2323 | "description": "Send pytest execution result email", 2324 | "name": "pytest-notice", 2325 | "version": "0.1" 2326 | }, 2327 | { 2328 | "description": "A pytest plugin for sending a desktop notification and playing a sound upon completion of tests", 2329 | "name": "pytest-notification", 2330 | "version": "0.2.0" 2331 | }, 2332 | { 2333 | "description": "A pytest plugin to notify test result", 2334 | "name": "pytest-notifier", 2335 | "version": "1.0.4" 2336 | }, 2337 | { 2338 | "description": "Pytest markers for not implemented features and tests.", 2339 | "name": "pytest-notimplemented", 2340 | "version": "1.0.0" 2341 | }, 2342 | { 2343 | "description": "A PyTest Reporter to send test runs to Notion.so", 2344 | "name": "pytest-notion", 2345 | "version": "1.0.1" 2346 | }, 2347 | { 2348 | "description": "A pytest plugin for generating NUnit3 test result XML output", 2349 | "name": "pytest-nunit", 2350 | "version": "0.6.0" 2351 | }, 2352 | { 2353 | "description": "pytest results data-base and HTML reporter", 2354 | "name": "pytest-ochrus", 2355 | "version": "0.0.6" 2356 | }, 2357 | { 2358 | "description": "py.test plugin to run Odoo tests", 2359 | "name": "pytest-odoo", 2360 | "version": "0.6.0" 2361 | }, 2362 | { 2363 | "description": "Project description", 2364 | "name": "pytest-odoo-fixtures", 2365 | "version": "0.1.dev0" 2366 | }, 2367 | { 2368 | "description": "pytest plugin to test OpenERP modules", 2369 | "name": "pytest-oerp", 2370 | "version": "0.2.0" 2371 | }, 2372 | { 2373 | "description": "The ultimate pytest output plugin", 2374 | "name": "pytest-ok", 2375 | "version": "2019.4.1" 2376 | }, 2377 | { 2378 | "description": "Use @pytest.mark.only to run a single test", 2379 | "name": "pytest-only", 2380 | "version": "1.2.2" 2381 | }, 2382 | { 2383 | "description": "Run object-oriented tests in a simple format", 2384 | "name": "pytest-oot", 2385 | "version": "0.6.1" 2386 | }, 2387 | { 2388 | "description": "Pytest plugin for detecting inadvertent open file handles", 2389 | "name": "pytest-openfiles", 2390 | "version": "0.5.0" 2391 | }, 2392 | { 2393 | "description": "pytest plugin for publish results to opentmi", 2394 | "name": "pytest-opentmi", 2395 | "version": "0.2.1" 2396 | }, 2397 | { 2398 | "description": "include/exclude values of fixtures in pytest", 2399 | "name": "pytest-optional", 2400 | "version": "0.0.3" 2401 | }, 2402 | { 2403 | "description": "Easy declaration of optional tests (i.e., that are not run by default)", 2404 | "name": "pytest-optional-tests", 2405 | "version": "0.1.1" 2406 | }, 2407 | { 2408 | "description": "A pytest plugin for orchestrating tests", 2409 | "name": "pytest-orchestration", 2410 | "version": "0.0.10" 2411 | }, 2412 | { 2413 | "description": "pytest plugin to run your tests in a specific order", 2414 | "name": "pytest-order", 2415 | "version": "0.9.2" 2416 | }, 2417 | { 2418 | "description": "pytest plugin to run your tests in a specific order", 2419 | "name": "pytest-ordering", 2420 | "version": "0.6" 2421 | }, 2422 | { 2423 | "description": "pytest plugin to run your tests in a specific order", 2424 | "name": "pytest-ordering2", 2425 | "version": "0.7.0" 2426 | }, 2427 | { 2428 | "description": "OS X notifications for py.test results.", 2429 | "name": "pytest-osxnotify", 2430 | "version": "0.1.7" 2431 | }, 2432 | { 2433 | "description": "A simple plugin to use with pytest", 2434 | "name": "pytest-pact", 2435 | "version": "0.0.0" 2436 | }, 2437 | { 2438 | "description": "a pytest plugin for parallel and concurrent testing", 2439 | "name": "pytest-parallel", 2440 | "version": "0.1.0" 2441 | }, 2442 | { 2443 | "description": "pytest plugin to test all, first, last or random params", 2444 | "name": "pytest-param", 2445 | "version": "0.1.1" 2446 | }, 2447 | { 2448 | "description": "Configure pytest fixtures using a combination of\"parametrize\" and markers", 2449 | "name": "pytest-paramark", 2450 | "version": "0.1.1" 2451 | }, 2452 | { 2453 | "description": "Simpler PyTest parametrization", 2454 | "name": "pytest-parametrization", 2455 | "version": "2019.1.4" 2456 | }, 2457 | { 2458 | "description": "Pytest plugin for parametrizing tests with default iterables.", 2459 | "name": "pytest-parametrized", 2460 | "version": "1.3" 2461 | }, 2462 | { 2463 | "description": "Finally spell paramete?ri[sz]e correctly", 2464 | "name": "pytest-parawtf", 2465 | "version": "1.0.2" 2466 | }, 2467 | { 2468 | "description": "Check out https://github.com/elilutsky/pytest-pass", 2469 | "name": "pytest-pass", 2470 | "version": "1.1" 2471 | }, 2472 | { 2473 | "description": "Allow setting the path to a paste config file", 2474 | "name": "pytest-paste-config", 2475 | "version": "0.1" 2476 | }, 2477 | { 2478 | "description": "pytest plugin which adds pdb helper commands related to pytest.", 2479 | "name": "pytest-pdb", 2480 | "version": "0.3.1" 2481 | }, 2482 | { 2483 | "description": "pytest plugin for fuzzing with Peach API Security", 2484 | "name": "pytest-peach", 2485 | "version": "1.5.41" 2486 | }, 2487 | { 2488 | "description": "py.test plugin for pep257", 2489 | "name": "pytest-pep257", 2490 | "version": "0.0.5" 2491 | }, 2492 | { 2493 | "description": "pytest plugin to check PEP8 requirements", 2494 | "name": "pytest-pep8", 2495 | "version": "1.0.6" 2496 | }, 2497 | { 2498 | "description": "Change the exit code of pytest test sessions when a required percent of tests pass.", 2499 | "name": "pytest-percent", 2500 | "version": "0.1.2" 2501 | }, 2502 | { 2503 | "description": "A simple plugin to ensure the execution of critical sections of code has not been impacted", 2504 | "name": "pytest-performance", 2505 | "version": "0.1.0" 2506 | }, 2507 | { 2508 | "description": "Pytest plugins and helpers for tests using a Postgres database.", 2509 | "name": "pytest-pgsql", 2510 | "version": "1.1.2" 2511 | }, 2512 | { 2513 | "description": "Run the tests related to the changed files", 2514 | "name": "pytest-picked", 2515 | "version": "0.4.4" 2516 | }, 2517 | { 2518 | "description": "", 2519 | "name": "pytest-pigeonhole", 2520 | "version": "0.3.1" 2521 | }, 2522 | { 2523 | "description": "Show surprise when tests are passing", 2524 | "name": "pytest-pikachu", 2525 | "version": "0.1.0" 2526 | }, 2527 | { 2528 | "description": "Slice in your test base thanks to powerful markers.", 2529 | "name": "pytest-pilot", 2530 | "version": "0.8.0" 2531 | }, 2532 | { 2533 | "description": "🦊 The pytest plugin for Firefox Telemetry 📊", 2534 | "name": "pytest-pings", 2535 | "version": "0.1.0" 2536 | }, 2537 | { 2538 | "description": "A simple pytest plugin for pinning tests", 2539 | "name": "pytest-pinned", 2540 | "version": "0.4.0" 2541 | }, 2542 | { 2543 | "description": "A pytest plugin which runs SBFL algorithms to detect faults.", 2544 | "name": "pytest-pinpoint", 2545 | "version": "0.3.0" 2546 | }, 2547 | { 2548 | "description": "Pytest plugin for functional testing of data analysispipelines", 2549 | "name": "pytest-pipeline", 2550 | "version": "0.3.0" 2551 | }, 2552 | { 2553 | "description": "Markers for pytest to skip tests on specific platforms", 2554 | "name": "pytest-platform-markers", 2555 | "version": "1.0.0" 2556 | }, 2557 | { 2558 | "description": "pytest plugin that let you automate actions and assertions with test metrics reporting executing plain YAML files", 2559 | "name": "pytest-play", 2560 | "version": "2.3.1" 2561 | }, 2562 | { 2563 | "description": "A pytest wrapper with fixtures for Playwright to automate web browsers", 2564 | "name": "pytest-playwright", 2565 | "version": "0.0.9" 2566 | }, 2567 | { 2568 | "description": "Fixtures for quickly making Matplotlib plots in tests", 2569 | "name": "pytest-plt", 2570 | "version": "1.1.0" 2571 | }, 2572 | { 2573 | "description": "A plugin to help developing and testing other plugins", 2574 | "name": "pytest-plugin-helpers", 2575 | "version": "0.1.0" 2576 | }, 2577 | { 2578 | "description": "PyTest Plus Plugin :: extends pytest functionality", 2579 | "name": "pytest-plus", 2580 | "version": "0.2" 2581 | }, 2582 | { 2583 | "description": "", 2584 | "name": "pytest-pmisc", 2585 | "version": "1.0.7" 2586 | }, 2587 | { 2588 | "description": "pytest plugin for collecting test cases and recording test results", 2589 | "name": "pytest-polarion-cfme", 2590 | "version": "0.1.5" 2591 | }, 2592 | { 2593 | "description": "pytest plugin for collecting polarion test cases data", 2594 | "name": "pytest-polarion-collect", 2595 | "version": "0.25.0" 2596 | }, 2597 | { 2598 | "description": "Provides Polecat pytest fixtures", 2599 | "name": "pytest-polecat", 2600 | "version": "0.0.2" 2601 | }, 2602 | { 2603 | "description": "PonyORM in Pytest", 2604 | "name": "pytest-ponyorm", 2605 | "version": "0.3.3" 2606 | }, 2607 | { 2608 | "description": "Visualize your crappy tests", 2609 | "name": "pytest-poo", 2610 | "version": "0.2" 2611 | }, 2612 | { 2613 | "description": "Visualize your failed tests with poo", 2614 | "name": "pytest-poo-fail", 2615 | "version": "1.1" 2616 | }, 2617 | { 2618 | "description": "A pytest plugin to help with testing pop projects", 2619 | "name": "pytest-pop", 2620 | "version": "6.3" 2621 | }, 2622 | { 2623 | "description": "Run PostgreSQL in Docker container in Pytest.", 2624 | "name": "pytest-postgres", 2625 | "version": "0.7.0" 2626 | }, 2627 | { 2628 | "description": "Postgresql fixtures and fixture factories for Pytest.", 2629 | "name": "pytest-postgresql", 2630 | "version": "2.5.2" 2631 | }, 2632 | { 2633 | "description": "pytest plugin with powerful fixtures", 2634 | "name": "pytest-power", 2635 | "version": "1.0.0" 2636 | }, 2637 | { 2638 | "description": "Minitest-style test colors", 2639 | "name": "pytest-pride", 2640 | "version": "0.1.2" 2641 | }, 2642 | { 2643 | "description": "pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not stdout)", 2644 | "name": "pytest-print", 2645 | "version": "0.2.1" 2646 | }, 2647 | { 2648 | "description": "Profiling plugin for py.test", 2649 | "name": "pytest-profiling", 2650 | "version": "1.7.0" 2651 | }, 2652 | { 2653 | "description": "pytest plugin for instant test progress status", 2654 | "name": "pytest-progress", 2655 | "version": "1.2.2" 2656 | }, 2657 | { 2658 | "description": "Report test pass / failures to a Prometheus PushGateway", 2659 | "name": "pytest-prometheus", 2660 | "version": "0.1" 2661 | }, 2662 | { 2663 | "description": "Test helpers for Prosper projects", 2664 | "name": "pytest-prosper", 2665 | "version": "1.0.0" 2666 | }, 2667 | { 2668 | "description": "A rspec format reporter for Python ptest", 2669 | "name": "pytest-pspec", 2670 | "version": "0.0.4" 2671 | }, 2672 | { 2673 | "description": "Pytest PuDB debugger integration", 2674 | "name": "pytest-pudb", 2675 | "version": "0.7.0" 2676 | }, 2677 | { 2678 | "description": "py.test plugin for purkinje test runner", 2679 | "name": "pytest-purkinje", 2680 | "version": "0.1.6" 2681 | }, 2682 | { 2683 | "description": "Plugin for py.test to enter PyCharm debugger on uncaught exceptions", 2684 | "name": "pytest-pycharm", 2685 | "version": "0.7.0" 2686 | }, 2687 | { 2688 | "description": "pytest plugin to run pycodestyle", 2689 | "name": "pytest-pycodestyle", 2690 | "version": "2.2.0" 2691 | }, 2692 | { 2693 | "description": "py.test plugin to connect to a remote debug server with PyDev or PyCharm.", 2694 | "name": "pytest-pydev", 2695 | "version": "0.1.1" 2696 | }, 2697 | { 2698 | "description": "pytest plugin to run pydocstyle", 2699 | "name": "pytest-pydocstyle", 2700 | "version": "2.2.0" 2701 | }, 2702 | { 2703 | "description": "pytest plugin to check source code with pylint", 2704 | "name": "pytest-pylint", 2705 | "version": "0.18.0" 2706 | }, 2707 | { 2708 | "description": "Easily test your HTTP library against a local copy of pypi", 2709 | "name": "pytest-pypi", 2710 | "version": "0.1.1" 2711 | }, 2712 | { 2713 | "description": "Core engine for cookiecutter-qa and pytest-play packages", 2714 | "name": "pytest-pypom-navigation", 2715 | "version": "2.0.3" 2716 | }, 2717 | { 2718 | "description": "A plugin to run pyppeteer in pytest.", 2719 | "name": "pytest-pyppeteer", 2720 | "version": "0.2.2" 2721 | }, 2722 | { 2723 | "description": "Pytest fixture \"q\" for pyq", 2724 | "name": "pytest-pyq", 2725 | "version": "1.2.0" 2726 | }, 2727 | { 2728 | "description": "pytest pyramid providing basic fixtures for testing pyramid applications with pytest test suite", 2729 | "name": "pytest-pyramid", 2730 | "version": "0.3.3" 2731 | }, 2732 | { 2733 | "description": "Pyramid server fixture for py.test", 2734 | "name": "pytest-pyramid-server", 2735 | "version": "1.7.0" 2736 | }, 2737 | { 2738 | "description": "Pytest plugin for interaction with TestRail", 2739 | "name": "pytest-pytestrail", 2740 | "version": "0.10.5" 2741 | }, 2742 | { 2743 | "description": "pytest plugin for adding to the PYTHONPATH from command line or configs.", 2744 | "name": "pytest-pythonpath", 2745 | "version": "0.7.3" 2746 | }, 2747 | { 2748 | "description": "Run QML Tests with pytest", 2749 | "name": "pytest-qml", 2750 | "version": "0.3.0" 2751 | }, 2752 | { 2753 | "description": "pytest support for PyQt and PySide applications", 2754 | "name": "pytest-qt", 2755 | "version": "3.3.0" 2756 | }, 2757 | { 2758 | "description": "QT app fixture for py.test", 2759 | "name": "pytest-qt-app", 2760 | "version": "1.0.1" 2761 | }, 2762 | { 2763 | "description": "A plugin for pytest to manage expected test failures", 2764 | "name": "pytest-quarantine", 2765 | "version": "2.0.0" 2766 | }, 2767 | { 2768 | "description": "pytest plugin to generate random data inspired by QuickCheck", 2769 | "name": "pytest-quickcheck", 2770 | "version": "0.8.6" 2771 | }, 2772 | { 2773 | "description": "RabbitMQ process and client fixtures for pytest", 2774 | "name": "pytest-rabbitmq", 2775 | "version": "2.0.1" 2776 | }, 2777 | { 2778 | "description": "Race conditions tester for pytest", 2779 | "name": "pytest-race", 2780 | "version": "0.1.1" 2781 | }, 2782 | { 2783 | "description": "pytest plugin to implement PEP712", 2784 | "name": "pytest-rage", 2785 | "version": "0.1" 2786 | }, 2787 | { 2788 | "description": "An implementation of pytest.raises as a pytest.mark fixture", 2789 | "name": "pytest-raises", 2790 | "version": "0.11" 2791 | }, 2792 | { 2793 | "description": "Simple pytest plugin to look for regex in Exceptions", 2794 | "name": "pytest-raisesregexp", 2795 | "version": "2.1" 2796 | }, 2797 | { 2798 | "description": "Plugin enabling the use of exception instances with pytest.raises", 2799 | "name": "pytest-raisin", 2800 | "version": "0.3" 2801 | }, 2802 | { 2803 | "description": "py.test plugin to randomize tests", 2804 | "name": "pytest-random", 2805 | "version": "0.02" 2806 | }, 2807 | { 2808 | "description": "Randomise the order in which pytest tests are run with some control over the randomness", 2809 | "name": "pytest-random-num", 2810 | "version": "1.0.13" 2811 | }, 2812 | { 2813 | "description": "Randomise the order in which pytest tests are run with some control over the randomness", 2814 | "name": "pytest-random-order", 2815 | "version": "1.0.4" 2816 | }, 2817 | { 2818 | "description": "Pytest plugin to randomly order tests and control random.seed.", 2819 | "name": "pytest-randomly", 2820 | "version": "3.5.0" 2821 | }, 2822 | { 2823 | "description": "Pytest plugin about random seed management", 2824 | "name": "pytest-randomness", 2825 | "version": "0.1.0" 2826 | }, 2827 | { 2828 | "description": "Test your README.md file", 2829 | "name": "pytest-readme", 2830 | "version": "1.0.0" 2831 | }, 2832 | { 2833 | "description": "Pytest fixtures for REANA.", 2834 | "name": "pytest-reana", 2835 | "version": "0.7.0" 2836 | }, 2837 | { 2838 | "description": "A pytest plugin that allows you recording of network interactions via VCR.py", 2839 | "name": "pytest-recording", 2840 | "version": "0.11.0" 2841 | }, 2842 | { 2843 | "description": "Provides pytest plugins for reporting request/response traffic, screenshots, and more to ReportPortal", 2844 | "name": "pytest-recordings", 2845 | "version": "0.4.2" 2846 | }, 2847 | { 2848 | "description": "Redis fixtures and fixture factories for Pytest.", 2849 | "name": "pytest-redis", 2850 | "version": "2.0.0" 2851 | }, 2852 | { 2853 | "description": "Pytest plugin for redmine", 2854 | "name": "pytest-redmine", 2855 | "version": "0.0.1" 2856 | }, 2857 | { 2858 | "description": "A plugin to store reference files to ease regression testing", 2859 | "name": "pytest-ref", 2860 | "version": "0.2.0" 2861 | }, 2862 | { 2863 | "description": "Conveniently run pytest with a dot-formatted test reference.", 2864 | "name": "pytest-reference-formatter", 2865 | "version": "0.2" 2866 | }, 2867 | { 2868 | "description": "Easy to use fixtures to write regression tests.", 2869 | "name": "pytest-regressions", 2870 | "version": "2.0.2" 2871 | }, 2872 | { 2873 | "description": "pytest plugin for regression tests", 2874 | "name": "pytest-regtest", 2875 | "version": "1.4.5" 2876 | }, 2877 | { 2878 | "description": "Relaxed test discovery/organization for pytest", 2879 | "name": "pytest-relaxed", 2880 | "version": "1.1.5" 2881 | }, 2882 | { 2883 | "description": "Pytest plugin to create a temporary directory with remote files", 2884 | "name": "pytest-remfiles", 2885 | "version": "0.0.2" 2886 | }, 2887 | { 2888 | "description": "Pytest plugin for controlling remote data access.", 2889 | "name": "pytest-remotedata", 2890 | "version": "0.3.2" 2891 | }, 2892 | { 2893 | "description": "py.test plugin to remove stale byte code files.", 2894 | "name": "pytest-remove-stale-bytecode", 2895 | "version": "5.0.1" 2896 | }, 2897 | { 2898 | "description": "Reorder tests depending on their paths and names.", 2899 | "name": "pytest-reorder", 2900 | "version": "0.1.1" 2901 | }, 2902 | { 2903 | "description": "pytest plugin for repeating tests", 2904 | "name": "pytest-repeat", 2905 | "version": "0.9.1" 2906 | }, 2907 | { 2908 | "description": "Saves previous test runs and allow re-execute previous pytest runs to reproduce crashes or flaky tests", 2909 | "name": "pytest-replay", 2910 | "version": "1.2.1" 2911 | }, 2912 | { 2913 | "description": "A pytest plugin to report on repository standards conformance", 2914 | "name": "pytest-repo-health", 2915 | "version": "2.1.0" 2916 | }, 2917 | { 2918 | "description": "Creates json report that is compatible with atom.io's linter message format", 2919 | "name": "pytest-report", 2920 | "version": "0.2.1" 2921 | }, 2922 | { 2923 | "description": "pytest plugin for adding tests' parameters to junit report", 2924 | "name": "pytest-report-parameters", 2925 | "version": "0.6.0" 2926 | }, 2927 | { 2928 | "description": "Generate Pytest reports with templates", 2929 | "name": "pytest-reporter", 2930 | "version": "0.5.1" 2931 | }, 2932 | { 2933 | "description": "A basic HTML report template for Pytest", 2934 | "name": "pytest-reporter-html1", 2935 | "version": "0.8.1" 2936 | }, 2937 | { 2938 | "description": "Pytest plugin for reportinfra", 2939 | "name": "pytest-reportinfra", 2940 | "version": "0.1" 2941 | }, 2942 | { 2943 | "description": "A plugin to report summarized results in a table format", 2944 | "name": "pytest-reporting", 2945 | "version": "0.1.0" 2946 | }, 2947 | { 2948 | "description": "Replacement for the --resultlog option, focused in simplicity and extensibility", 2949 | "name": "pytest-reportlog", 2950 | "version": "0.1.1" 2951 | }, 2952 | { 2953 | "description": "Agent for Reporting results of tests to the Report Portal", 2954 | "name": "pytest-reportportal", 2955 | "version": "5.0.6" 2956 | }, 2957 | { 2958 | "description": "pytest plugin to check pinned requirements", 2959 | "name": "pytest-reqs", 2960 | "version": "0.2.1" 2961 | }, 2962 | { 2963 | "description": "A simple plugin to use with pytest", 2964 | "name": "pytest-requests", 2965 | "version": "0.3.0" 2966 | }, 2967 | { 2968 | "description": "Make multi-threaded pytest test cases fail when they should", 2969 | "name": "pytest-reraise", 2970 | "version": "1.0.3" 2971 | }, 2972 | { 2973 | "description": "Re-run only changed files in specified branch", 2974 | "name": "pytest-rerun", 2975 | "version": "0.0.1" 2976 | }, 2977 | { 2978 | "description": "pytest plugin to re-run tests to eliminate flaky failures", 2979 | "name": "pytest-rerunfailures", 2980 | "version": "9.1.1" 2981 | }, 2982 | { 2983 | "description": "Resilient Circuits fixtures for PyTest.", 2984 | "name": "pytest-resilient-circuits", 2985 | "version": "38.0.76" 2986 | }, 2987 | { 2988 | "description": "Load resource fixture plugin to use with pytest", 2989 | "name": "pytest-resource", 2990 | "version": "0.1.3" 2991 | }, 2992 | { 2993 | "description": "Provides path for uniform access to test resources in isolated directory", 2994 | "name": "pytest-resource-path", 2995 | "version": "1.2.1" 2996 | }, 2997 | { 2998 | "description": "Simplified requests calls mocking for pytest", 2999 | "name": "pytest-responsemock", 3000 | "version": "1.0.1" 3001 | }, 3002 | { 3003 | "description": "py.test integration for responses", 3004 | "name": "pytest-responses", 3005 | "version": "0.4.0" 3006 | }, 3007 | { 3008 | "description": "Pytest plugin to restrict the test types allowed", 3009 | "name": "pytest-restrict", 3010 | "version": "3.1.0" 3011 | }, 3012 | { 3013 | "description": "A RethinkDB plugin for pytest.", 3014 | "name": "pytest-rethinkdb", 3015 | "version": "0.1.3" 3016 | }, 3017 | { 3018 | "description": "Pytest plugin to reverse test order.", 3019 | "name": "pytest-reverse", 3020 | "version": "1.0.1" 3021 | }, 3022 | { 3023 | "description": "pytest plugin to test webapplications using the Ringo webframework", 3024 | "name": "pytest-ringo", 3025 | "version": "0.2.3" 3026 | }, 3027 | { 3028 | "description": "Fixtures for seeding tests and making randomness reproducible", 3029 | "name": "pytest-rng", 3030 | "version": "1.0.0" 3031 | }, 3032 | { 3033 | "description": "pytest plugin for ROAST configuration override and fixtures", 3034 | "name": "pytest-roast", 3035 | "version": "1.0.0" 3036 | }, 3037 | { 3038 | "description": "Pytest integration with rotest", 3039 | "name": "pytest-rotest", 3040 | "version": "0.1.0" 3041 | }, 3042 | { 3043 | "description": "Extend py.test for RPC OpenStack testing.", 3044 | "name": "pytest-rpc", 3045 | "version": "1.1.1" 3046 | }, 3047 | { 3048 | "description": "pytest data collector plugin for Testgr", 3049 | "name": "pytest-rt", 3050 | "version": "1.0.0" 3051 | }, 3052 | { 3053 | "description": "implement a --failed option for pytest", 3054 | "name": "pytest-runfailed", 3055 | "version": "0.6" 3056 | }, 3057 | { 3058 | "description": "Invoke py.test as distutils command with dependency resolution", 3059 | "name": "pytest-runner", 3060 | "version": "5.2" 3061 | }, 3062 | { 3063 | "description": "", 3064 | "name": "pytest-sa-pg", 3065 | "version": "0.3.2" 3066 | }, 3067 | { 3068 | "description": "Pytest Salt Plugin", 3069 | "name": "pytest-salt", 3070 | "version": "2020.1.27" 3071 | }, 3072 | { 3073 | "description": "A Pytest plugin that builds and creates docker containers", 3074 | "name": "pytest-salt-containers", 3075 | "version": "0.2.9" 3076 | }, 3077 | { 3078 | "description": "Pytest Salt Plugin", 3079 | "name": "pytest-salt-factories", 3080 | "version": "0.98.0" 3081 | }, 3082 | { 3083 | "description": "Simple PyTest Plugin For Salt's Test Suite Specifically", 3084 | "name": "pytest-salt-from-filenames", 3085 | "version": "2019.1.30.post3" 3086 | }, 3087 | { 3088 | "description": "Simple PyTest Plugin For Salt's Test Suite Specifically", 3089 | "name": "pytest-salt-runtests-bridge", 3090 | "version": "2019.12.5" 3091 | }, 3092 | { 3093 | "description": "a pytest plugin for Sanic", 3094 | "name": "pytest-sanic", 3095 | "version": "1.6.2" 3096 | }, 3097 | { 3098 | "description": "The complete web automation library for end-to-end testing.", 3099 | "name": "pytest-sbase", 3100 | "version": "1.50.13" 3101 | }, 3102 | { 3103 | "description": "pytest plugin for test scenarios", 3104 | "name": "pytest-scenario", 3105 | "version": "1.0a6" 3106 | }, 3107 | { 3108 | "description": "👍 Validate return values against a schema-like object in testing", 3109 | "name": "pytest-schema", 3110 | "version": "0.1.0" 3111 | }, 3112 | { 3113 | "description": "An encrypted password store for use within pytest cases", 3114 | "name": "pytest-securestore", 3115 | "version": "0.1.3" 3116 | }, 3117 | { 3118 | "description": "A pytest plugin which allows to (de-)select tests from a file.", 3119 | "name": "pytest-select", 3120 | "version": "0.1.2" 3121 | }, 3122 | { 3123 | "description": "pytest plugin for Selenium", 3124 | "name": "pytest-selenium", 3125 | "version": "2.0.1" 3126 | }, 3127 | { 3128 | "description": "pytest plugin for Selenium", 3129 | "name": "pytest-selenium-enhancer", 3130 | "version": "1.6.1" 3131 | }, 3132 | { 3133 | "description": "A pytest package implementing perceptualdiff for Selenium tests.", 3134 | "name": "pytest-selenium-pdiff", 3135 | "version": "0.4.0" 3136 | }, 3137 | { 3138 | "description": "The complete web automation library for end-to-end testing.", 3139 | "name": "pytest-seleniumbase", 3140 | "version": "1.50.13" 3141 | }, 3142 | { 3143 | "description": "Send pytest execution result email", 3144 | "name": "pytest-send-email", 3145 | "version": "0.1" 3146 | }, 3147 | { 3148 | "description": "A pytest plugin to send testrun information to Sentry.io", 3149 | "name": "pytest-sentry", 3150 | "version": "0.1.5" 3151 | }, 3152 | { 3153 | "description": "Extensible server fixures for py.test", 3154 | "name": "pytest-server-fixtures", 3155 | "version": "1.7.0" 3156 | }, 3157 | { 3158 | "description": "Automatically mocks resources from serverless.yml in pytest using moto.", 3159 | "name": "pytest-serverless", 3160 | "version": "0.10.1" 3161 | }, 3162 | { 3163 | "description": "Services plugin for pytest testing framework", 3164 | "name": "pytest-services", 3165 | "version": "2.2.1" 3166 | }, 3167 | { 3168 | "description": "py.test plugin to make session fixtures behave as if written in conftest, even if it is written in some modules", 3169 | "name": "pytest-session-fixture-globalize", 3170 | "version": "0.0.0.3" 3171 | }, 3172 | { 3173 | "description": "pytest-session2file (aka: pytest-session_to_file for v0.1.0 - v0.1.2) is a py.test plugin for capturing and saving to file the stdout of py.test.", 3174 | "name": "pytest-session2file", 3175 | "version": "0.1.10" 3176 | }, 3177 | { 3178 | "description": "pytest-session_to_file is a py.test plugin for capturing and saving to file the stdout of py.test.", 3179 | "name": "pytest-session_to_file", 3180 | "version": "0.1.2" 3181 | }, 3182 | { 3183 | "description": "py.test plugin to locally test sftp server connections.", 3184 | "name": "pytest-sftpserver", 3185 | "version": "1.3.0" 3186 | }, 3187 | { 3188 | "description": "", 3189 | "name": "pytest-shard", 3190 | "version": "0.1.1" 3191 | }, 3192 | { 3193 | "description": "A pytest plugin for testing shell scripts and line-based processes", 3194 | "name": "pytest-shell", 3195 | "version": "0.2.3" 3196 | }, 3197 | { 3198 | "description": "Versatile ZODB abstraction layer - pytest fixtures", 3199 | "name": "pytest-sheraf", 3200 | "version": "0.1.1" 3201 | }, 3202 | { 3203 | "description": "pytest plugin help to find coupled tests", 3204 | "name": "pytest-sherlock", 3205 | "version": "0.2.2" 3206 | }, 3207 | { 3208 | "description": "Expand command-line shortcuts listed in pytest configuration", 3209 | "name": "pytest-shortcuts", 3210 | "version": "0.4.0" 3211 | }, 3212 | { 3213 | "description": "A goodie-bag of unix shell and environment tools for py.test", 3214 | "name": "pytest-shutil", 3215 | "version": "1.7.0" 3216 | }, 3217 | { 3218 | "description": "Simple pytest plugin", 3219 | "name": "pytest-simple-plugin", 3220 | "version": "0.0.4" 3221 | }, 3222 | { 3223 | "description": "simple-settings plugin for pytest", 3224 | "name": "pytest-simple-settings", 3225 | "version": "0.1.5" 3226 | }, 3227 | { 3228 | "description": "Allow for multiple processes to log to a single file", 3229 | "name": "pytest-single-file-logging", 3230 | "version": "0.1.18" 3231 | }, 3232 | { 3233 | "description": "A plugin that selects only tests with changes in execution path", 3234 | "name": "pytest-skipper", 3235 | "version": "0.1.3" 3236 | }, 3237 | { 3238 | "description": "Automatically skip tests that don't need to run!", 3239 | "name": "pytest-skippy", 3240 | "version": "0.1.1" 3241 | }, 3242 | { 3243 | "description": "Pytest to Slack reporting plugin", 3244 | "name": "pytest-slack", 3245 | "version": "2.3.0" 3246 | }, 3247 | { 3248 | "description": "A plugin for collecting tests that touch changed code", 3249 | "name": "pytest-smartcollect", 3250 | "version": "1.0.2" 3251 | }, 3252 | { 3253 | "description": "Smart coverage plugin for pytest.", 3254 | "name": "pytest-smartcov", 3255 | "version": "0.3" 3256 | }, 3257 | { 3258 | "description": "Plugin for adding a marker to slow running tests. 🐌", 3259 | "name": "pytest-snail", 3260 | "version": "0.1.0" 3261 | }, 3262 | { 3263 | "description": "py.test plugin for Snap-CI", 3264 | "name": "pytest-snapci", 3265 | "version": "0.1.4" 3266 | }, 3267 | { 3268 | "description": "A plugin to enable snapshot testing with pytest.", 3269 | "name": "pytest-snapshot", 3270 | "version": "0.4.2" 3271 | }, 3272 | { 3273 | "description": "", 3274 | "name": "pytest-snmpserver", 3275 | "version": "0.1.7" 3276 | }, 3277 | { 3278 | "description": "Pytest Plugin to disable socket calls during tests", 3279 | "name": "pytest-socket", 3280 | "version": "0.3.5" 3281 | }, 3282 | { 3283 | "description": "", 3284 | "name": "pytest-soft-assertions", 3285 | "version": "0.1.2" 3286 | }, 3287 | { 3288 | "description": "Solr process and client fixtures for py.test.", 3289 | "name": "pytest-solr", 3290 | "version": "1.0.0" 3291 | }, 3292 | { 3293 | "description": "A simple plugin to first execute tests that historically failed more", 3294 | "name": "pytest-sorter", 3295 | "version": "0.2.2" 3296 | }, 3297 | { 3298 | "description": "Test-ordering plugin for pytest", 3299 | "name": "pytest-sourceorder", 3300 | "version": "0.5.1" 3301 | }, 3302 | { 3303 | "description": "pytest plugin to run the tests with support of pyspark.", 3304 | "name": "pytest-spark", 3305 | "version": "0.6.0" 3306 | }, 3307 | { 3308 | "description": "py.test plugin to spawn process and communicate with them.", 3309 | "name": "pytest-spawner", 3310 | "version": "0.1.0" 3311 | }, 3312 | { 3313 | "description": "pytest plugin to display test execution output like a SPECIFICATION", 3314 | "name": "pytest-spec", 3315 | "version": "3.0.6" 3316 | }, 3317 | { 3318 | "description": "Doctest plugin for pytest with support for Sphinx-specific doctest-directives", 3319 | "name": "pytest-sphinx", 3320 | "version": "0.3.1" 3321 | }, 3322 | { 3323 | "description": "Exports unit tests as test runs in SpiraTest/Team/Plan", 3324 | "name": "pytest-spiratest", 3325 | "version": "1.1.0" 3326 | }, 3327 | { 3328 | "description": "Splinter plugin for pytest testing framework", 3329 | "name": "pytest-splinter", 3330 | "version": "3.3.0" 3331 | }, 3332 | { 3333 | "description": "Pytest plugin for splitting test suite based on test execution time", 3334 | "name": "pytest-split", 3335 | "version": "0.1.5" 3336 | }, 3337 | { 3338 | "description": "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.", 3339 | "name": "pytest-split-tests", 3340 | "version": "1.0.9" 3341 | }, 3342 | { 3343 | "description": "Split.io SDK integration for e2e tests", 3344 | "name": "pytest-splitio", 3345 | "version": "0.1.0" 3346 | }, 3347 | { 3348 | "description": "A Dynamic test tool for Splunk Apps and Add-ons", 3349 | "name": "pytest-splunk-addon", 3350 | "version": "1.3.12" 3351 | }, 3352 | { 3353 | "description": "Library to support testing Splunk Add-on UX", 3354 | "name": "pytest-splunk-addon-ui-smartx", 3355 | "version": "1.0.0" 3356 | }, 3357 | { 3358 | "description": "pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud", 3359 | "name": "pytest-splunk-env", 3360 | "version": "0.1.2" 3361 | }, 3362 | { 3363 | "description": "sqitch for pytest", 3364 | "name": "pytest-sqitch", 3365 | "version": "0.1.1" 3366 | }, 3367 | { 3368 | "description": "Yet another SQL-testing framework for BigQuery provided by pytest plugin ", 3369 | "name": "pytest-sql-bigquery", 3370 | "version": "0.0.3" 3371 | }, 3372 | { 3373 | "description": "pytest plugin with sqlalchemy related fixtures", 3374 | "name": "pytest-sqlalchemy", 3375 | "version": "0.2.1" 3376 | }, 3377 | { 3378 | "description": "pytest plugin for ssh command run", 3379 | "name": "pytest-ssh", 3380 | "version": "0.1" 3381 | }, 3382 | { 3383 | "description": "Start pytest run from a given point", 3384 | "name": "pytest-start-from", 3385 | "version": "0.1.0" 3386 | }, 3387 | { 3388 | "description": "pytest plugin for reporting to graphite", 3389 | "name": "pytest-statsd", 3390 | "version": "1.1.6" 3391 | }, 3392 | { 3393 | "description": "A small description", 3394 | "name": "pytest-stepfunctions", 3395 | "version": "0.1" 3396 | }, 3397 | { 3398 | "description": "Create step-wise / incremental tests in pytest.", 3399 | "name": "pytest-steps", 3400 | "version": "1.7.3" 3401 | }, 3402 | { 3403 | "description": "Run a test suite one failing test at a time.", 3404 | "name": "pytest-stepwise", 3405 | "version": "0.4" 3406 | }, 3407 | { 3408 | "description": "A plugin to pytest stoq", 3409 | "name": "pytest-stoq", 3410 | "version": "0.7.1" 3411 | }, 3412 | { 3413 | "description": "A Pytest plugin that allows you to loop tests for a user defined amount of time.", 3414 | "name": "pytest-stress", 3415 | "version": "1.0.1" 3416 | }, 3417 | { 3418 | "description": "Structured logging assertions", 3419 | "name": "pytest-structlog", 3420 | "version": "0.3" 3421 | }, 3422 | { 3423 | "description": "provide structured temporary directory", 3424 | "name": "pytest-structmpd", 3425 | "version": "0.1.0" 3426 | }, 3427 | { 3428 | "description": "Stub packages, modules and attributes.", 3429 | "name": "pytest-stub", 3430 | "version": "1.1.0" 3431 | }, 3432 | { 3433 | "description": "Provide stub implementations for subprocesses in Python tests", 3434 | "name": "pytest-stubprocess", 3435 | "version": "0.1.0" 3436 | }, 3437 | { 3438 | "description": "A pytest plugin to organize long run tests (named studies) without interfering the regular tests", 3439 | "name": "pytest-study", 3440 | "version": "0.14" 3441 | }, 3442 | { 3443 | "description": "A plugin to fake subprocess for pytest", 3444 | "name": "pytest-subprocess", 3445 | "version": "1.0.0" 3446 | }, 3447 | { 3448 | "description": "A hack to explicitly set up and tear down fixtures.", 3449 | "name": "pytest-subtesthack", 3450 | "version": "0.1.1" 3451 | }, 3452 | { 3453 | "description": "unittest subTest() support and subtests fixture", 3454 | "name": "pytest-subtests", 3455 | "version": "0.3.2" 3456 | }, 3457 | { 3458 | "description": "pytest-subunit is a plugin for py.test which outputs testsresult in subunit format.", 3459 | "name": "pytest-subunit", 3460 | "version": "0.0.10" 3461 | }, 3462 | { 3463 | "description": "pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly).", 3464 | "name": "pytest-sugar", 3465 | "version": "0.9.4" 3466 | }, 3467 | { 3468 | "description": "Workaround for https://github.com/Frozenball/pytest-sugar/issues/159", 3469 | "name": "pytest-sugar-bugfix159", 3470 | "version": "1.0" 3471 | }, 3472 | { 3473 | "description": "Pytest plugin to check your TestCase classes call super in setUp, tearDown, etc.", 3474 | "name": "pytest-super-check", 3475 | "version": "2.1.0" 3476 | }, 3477 | { 3478 | "description": "SVN repository fixture for py.test", 3479 | "name": "pytest-svn", 3480 | "version": "1.7.0" 3481 | }, 3482 | { 3483 | "description": "pytest-symbols is a pytest plugin that adds support for passing test environment symbols into pytest tests.", 3484 | "name": "pytest-symbols", 3485 | "version": "0.1.1" 3486 | }, 3487 | { 3488 | "description": "Test Anything Protocol (TAP) reporting plugin for pytest", 3489 | "name": "pytest-tap", 3490 | "version": "3.2" 3491 | }, 3492 | { 3493 | "description": "tblineinfo is a py.test plugin that insert the node id in the final py.test report when --tb=line option is used", 3494 | "name": "pytest-tblineinfo", 3495 | "version": "0.4" 3496 | }, 3497 | { 3498 | "description": "py.test plugin to introduce block structure in teamcity build log, if output is not captured", 3499 | "name": "pytest-teamcity-logblock", 3500 | "version": "0.0.0.2" 3501 | }, 3502 | { 3503 | "description": "Predictable and repeatable tempdir support.", 3504 | "name": "pytest-tempdir", 3505 | "version": "2019.10.12" 3506 | }, 3507 | { 3508 | "description": "A pytest plugin for using terraform fixtures", 3509 | "name": "pytest-terraform", 3510 | "version": "0.5.2" 3511 | }, 3512 | { 3513 | "description": "generate terraform resources to use with pytest", 3514 | "name": "pytest-terraform-fixture", 3515 | "version": "0.1.2" 3516 | }, 3517 | { 3518 | "description": "A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups.", 3519 | "name": "pytest-test-groups", 3520 | "version": "1.0.3" 3521 | }, 3522 | { 3523 | "description": "Plugin for py.test to run relevant tests, based on naively checking if a test contains a reference to the symbol you supply", 3524 | "name": "pytest-test-this", 3525 | "version": "0.3.0" 3526 | }, 3527 | { 3528 | "description": "A plugin to run tests written in Jupyter notebook", 3529 | "name": "pytest-testbook", 3530 | "version": "0.0.10" 3531 | }, 3532 | { 3533 | "description": "Test configuration plugin for pytest.", 3534 | "name": "pytest-testconfig", 3535 | "version": "0.2.0" 3536 | }, 3537 | { 3538 | "description": "A py.test plugin providing temporary directories in unit tests.", 3539 | "name": "pytest-testdirectory", 3540 | "version": "3.1.0" 3541 | }, 3542 | { 3543 | "description": "A testdox format reporter for pytest", 3544 | "name": "pytest-testdox", 3545 | "version": "2.0.1" 3546 | }, 3547 | { 3548 | "description": "Test infrastructures", 3549 | "name": "pytest-testinfra", 3550 | "version": "6.1.0" 3551 | }, 3552 | { 3553 | "description": "pytest reporting plugin for testlink", 3554 | "name": "pytest-testlink-adaptor", 3555 | "version": "0.33" 3556 | }, 3557 | { 3558 | "description": "selects tests affected by changed files and methods", 3559 | "name": "pytest-testmon", 3560 | "version": "1.0.3" 3561 | }, 3562 | { 3563 | "description": "Plugin to use TestObject Suites with Pytest", 3564 | "name": "pytest-testobject", 3565 | "version": "1.0.0" 3566 | }, 3567 | { 3568 | "description": "pytest plugin for creating TestRail runs and adding results", 3569 | "name": "pytest-testrail", 3570 | "version": "2.9.0" 3571 | }, 3572 | { 3573 | "description": "Плагин Pytest, для интеграции с TestRail", 3574 | "name": "pytest-testrail-api", 3575 | "version": "0.3.1" 3576 | }, 3577 | { 3578 | "description": "pytest plugin for Testrail", 3579 | "name": "pytest-testrail-client", 3580 | "version": "1.0.8" 3581 | }, 3582 | { 3583 | "description": "pytest plugin for creating TestRail runs and adding results", 3584 | "name": "pytest-testrail-e2e", 3585 | "version": "2.2.2" 3586 | }, 3587 | { 3588 | "description": "PyTest plugin for TestRail", 3589 | "name": "pytest-testrail-plugin", 3590 | "version": "0.0.3" 3591 | }, 3592 | { 3593 | "description": "", 3594 | "name": "pytest-testrail-reporter", 3595 | "version": "1.9" 3596 | }, 3597 | { 3598 | "description": "A small example package", 3599 | "name": "pytest-testrail2", 3600 | "version": "2.8.2" 3601 | }, 3602 | { 3603 | "description": "Tesults plugin for pytest", 3604 | "name": "pytest-tesults", 3605 | "version": "1.2.0" 3606 | }, 3607 | { 3608 | "description": "pytest-ligo", 3609 | "name": "pytest-tezos", 3610 | "version": "0.1.3" 3611 | }, 3612 | { 3613 | "description": "Pytest plugin for time travel", 3614 | "name": "pytest-thawgun", 3615 | "version": "0.0.3" 3616 | }, 3617 | { 3618 | "description": "Detects thread leaks", 3619 | "name": "pytest-threadleak", 3620 | "version": "0.2.0" 3621 | }, 3622 | { 3623 | "description": "A pytest plugin to time test function runs", 3624 | "name": "pytest-timeit", 3625 | "version": "0.3.0" 3626 | }, 3627 | { 3628 | "description": "py.test plugin to abort hanging tests", 3629 | "name": "pytest-timeout", 3630 | "version": "1.4.2" 3631 | }, 3632 | { 3633 | "description": "Linux-only Pytest plugin to control durations of various test case execution phases", 3634 | "name": "pytest-timeouts", 3635 | "version": "1.2.1" 3636 | }, 3637 | { 3638 | "description": "A timer plugin for pytest", 3639 | "name": "pytest-timer", 3640 | "version": "0.0.8" 3641 | }, 3642 | { 3643 | "description": "", 3644 | "name": "pytest-tipsi-django", 3645 | "version": "2.6.0" 3646 | }, 3647 | { 3648 | "description": "Better fixtures management. Various helpers", 3649 | "name": "pytest-tipsi-testing", 3650 | "version": "1.3.4" 3651 | }, 3652 | { 3653 | "description": "A pytest plugin that limits the output to just the things you need.", 3654 | "name": "pytest-tldr", 3655 | "version": "0.2.2" 3656 | }, 3657 | { 3658 | "description": "Cloud Jira Test Management (TM4J) PyTest reporter plugin", 3659 | "name": "pytest-tm4j-reporter", 3660 | "version": "0.1.2" 3661 | }, 3662 | { 3663 | "description": "A small plugin for the pytest testing framework, marking TODO comments as failure", 3664 | "name": "pytest-todo", 3665 | "version": "0.2.1" 3666 | }, 3667 | { 3668 | "description": "", 3669 | "name": "pytest-tomato", 3670 | "version": "1.0.20" 3671 | }, 3672 | { 3673 | "description": "This is just a collection of utilities for pytest, but don't really belong in pytest proper.", 3674 | "name": "pytest-toolbelt", 3675 | "version": "0.1.0" 3676 | }, 3677 | { 3678 | "description": "Numerous useful plugins for pytest.", 3679 | "name": "pytest-toolbox", 3680 | "version": "0.4" 3681 | }, 3682 | { 3683 | "description": "A py.test plugin providing fixtures and markers to simplify testing of asynchronous tornado applications.", 3684 | "name": "pytest-tornado", 3685 | "version": "0.8.1" 3686 | }, 3687 | { 3688 | "description": "A py.test plugin providing fixtures and markers to simplify testing of asynchronous tornado applications.", 3689 | "name": "pytest-tornado-yen3", 3690 | "version": "0.5.2" 3691 | }, 3692 | { 3693 | "description": "A py.test plugin providing fixtures and markers to simplify testing of asynchronous tornado applications.", 3694 | "name": "pytest-tornado5", 3695 | "version": "2.0.0" 3696 | }, 3697 | { 3698 | "description": "py.test plugin for testing Python 3.5+ Tornado code", 3699 | "name": "pytest-tornasync", 3700 | "version": "0.6.0.post2" 3701 | }, 3702 | { 3703 | "description": "", 3704 | "name": "pytest-track", 3705 | "version": "0.1.2" 3706 | }, 3707 | { 3708 | "description": "Test your translation files.", 3709 | "name": "pytest-translations", 3710 | "version": "3.0.0" 3711 | }, 3712 | { 3713 | "description": "Folds captured output sections in Travis CI build log", 3714 | "name": "pytest-travis-fold", 3715 | "version": "1.3.0" 3716 | }, 3717 | { 3718 | "description": "Plugin for py.test that integrates trello using markers", 3719 | "name": "pytest-trello", 3720 | "version": "0.0.7" 3721 | }, 3722 | { 3723 | "description": "Pytest plugin for trepan debugger.", 3724 | "name": "pytest-trepan", 3725 | "version": "2.0.0" 3726 | }, 3727 | { 3728 | "description": "py.test plugin for using the same _trial_temp working directory as trial", 3729 | "name": "pytest-trialtemp", 3730 | "version": "1.0.1" 3731 | }, 3732 | { 3733 | "description": "Pytest plugin for trio", 3734 | "name": "pytest-trio", 3735 | "version": "0.7.0" 3736 | }, 3737 | { 3738 | "description": "Test Class Base", 3739 | "name": "pytest-tstcls", 3740 | "version": "2020.1.1" 3741 | }, 3742 | { 3743 | "description": "A twisted plugin for pytest.", 3744 | "name": "pytest-twisted", 3745 | "version": "1.13.2" 3746 | }, 3747 | { 3748 | "description": "Typhoon HIL plugin for pytest", 3749 | "name": "pytest-typhoon-xray", 3750 | "version": "0.1.16" 3751 | }, 3752 | { 3753 | "description": "Typhoon HIL plugin for pytest", 3754 | "name": "pytest-tytest", 3755 | "version": "0.1.13" 3756 | }, 3757 | { 3758 | "description": "Easily mock calls to ubersmith at the `requests` level.", 3759 | "name": "pytest-ubersmith", 3760 | "version": "1.2.0" 3761 | }, 3762 | { 3763 | "description": "Text User Interface for running python tests", 3764 | "name": "pytest-ui", 3765 | "version": "0.3.6b0" 3766 | }, 3767 | { 3768 | "description": "Plugin for py.test set a different exit code on uncaught exceptions", 3769 | "name": "pytest-unhandled-exception-exit-code", 3770 | "version": "0.0.2" 3771 | }, 3772 | { 3773 | "description": "A pytest plugin for filtering unittest-based test classes", 3774 | "name": "pytest-unittest-filter", 3775 | "version": "0.2.1" 3776 | }, 3777 | { 3778 | "description": "Run only unmarked tests", 3779 | "name": "pytest-unmarked", 3780 | "version": "1.3" 3781 | }, 3782 | { 3783 | "description": "Test equality of unordered collections in pytest", 3784 | "name": "pytest-unordered", 3785 | "version": "0.4.0" 3786 | }, 3787 | { 3788 | "description": "A py.test plugin providing access to vagrant.", 3789 | "name": "pytest-vagrant", 3790 | "version": "2.0.3" 3791 | }, 3792 | { 3793 | "description": "", 3794 | "name": "pytest-valgrind", 3795 | "version": "0.1.0" 3796 | }, 3797 | { 3798 | "description": "pytest plugin for providing variables to tests/fixtures", 3799 | "name": "pytest-variables", 3800 | "version": "1.9.0" 3801 | }, 3802 | { 3803 | "description": "Plugin for managing VCR.py cassettes", 3804 | "name": "pytest-vcr", 3805 | "version": "1.0.2" 3806 | }, 3807 | { 3808 | "description": "Test from HTTP interactions to dataframe processed.", 3809 | "name": "pytest-vcrpandas", 3810 | "version": "0.0.2" 3811 | }, 3812 | { 3813 | "description": "py.test fixture for creating a virtual environment", 3814 | "name": "pytest-venv", 3815 | "version": "0.2.1" 3816 | }, 3817 | { 3818 | "description": "More descriptive output for parametrized py.test tests", 3819 | "name": "pytest-verbose-parametrize", 3820 | "version": "1.7.0" 3821 | }, 3822 | { 3823 | "description": "Virtualenv fixture for py.test", 3824 | "name": "pytest-virtualenv", 3825 | "version": "1.7.0" 3826 | }, 3827 | { 3828 | "description": "Pytest plugin for asserting data against voluptuous schema.", 3829 | "name": "pytest-voluptuous", 3830 | "version": "1.2.0" 3831 | }, 3832 | { 3833 | "description": "pytest plugin for automatic recording of http stubbed tests", 3834 | "name": "pytest-vts", 3835 | "version": "0.4.8" 3836 | }, 3837 | { 3838 | "description": "pytest-vw makes your failing test cases succeed under CI tools scrutiny", 3839 | "name": "pytest-vw", 3840 | "version": "0.1.0" 3841 | }, 3842 | { 3843 | "description": "Plugin for the vyper smart contract language.", 3844 | "name": "pytest-vyper", 3845 | "version": "0.1.0" 3846 | }, 3847 | { 3848 | "description": "Pytest plugin for testing whatsapp bots with end to end tests", 3849 | "name": "pytest-wa-e2e-plugin", 3850 | "version": "0.1.3" 3851 | }, 3852 | { 3853 | "description": "pytest plugin to list Python warnings in pytest report", 3854 | "name": "pytest-warnings", 3855 | "version": "0.3.1" 3856 | }, 3857 | { 3858 | "description": "Local continuous test runner with pytest and watchdog.", 3859 | "name": "pytest-watch", 3860 | "version": "4.2.0" 3861 | }, 3862 | { 3863 | "description": "Pytest plugin for testing WDL workflows.", 3864 | "name": "pytest-wdl", 3865 | "version": "1.4.1" 3866 | }, 3867 | { 3868 | "description": "An interactive web UI test runner for PyTest", 3869 | "name": "pytest-web-ui", 3870 | "version": "1.4.0" 3871 | }, 3872 | { 3873 | "description": "Selenium webdriver fixture for py.test", 3874 | "name": "pytest-webdriver", 3875 | "version": "1.7.0" 3876 | }, 3877 | { 3878 | "description": "Welian API Automation test framework pytest plugin", 3879 | "name": "pytest-wetest", 3880 | "version": "1.0.1" 3881 | }, 3882 | { 3883 | "description": "Testing Tornado.", 3884 | "name": "pytest-whirlwind", 3885 | "version": "0.1.0" 3886 | }, 3887 | { 3888 | "description": "pytest addon for displaying the whole node id for failures", 3889 | "name": "pytest-wholenodeid", 3890 | "version": "0.2" 3891 | }, 3892 | { 3893 | "description": "Windows tray notifications for py.test results.", 3894 | "name": "pytest-winnotify", 3895 | "version": "0.4.1" 3896 | }, 3897 | { 3898 | "description": "A pytest plugin for configuring workflow/pipeline tests using YAML files", 3899 | "name": "pytest-workflow", 3900 | "version": "1.4.0" 3901 | }, 3902 | { 3903 | "description": "pytest xdist plugin for distributed testing and loop-on-failing modes", 3904 | "name": "pytest-xdist", 3905 | "version": "2.1.0" 3906 | }, 3907 | { 3908 | "description": "pytest xdist plugin for distributed testing and loop-on-failing modes", 3909 | "name": "pytest-xdist-debug-for-graingert", 3910 | "version": "0.0.1" 3911 | }, 3912 | { 3913 | "description": "forked from pytest-xdist", 3914 | "name": "pytest-xdist-forked", 3915 | "version": "0.0.1" 3916 | }, 3917 | { 3918 | "description": "Pytest fixtures providing data read from function, module or package related (x)files.", 3919 | "name": "pytest-xfiles", 3920 | "version": "0.2.0" 3921 | }, 3922 | { 3923 | "description": "Extended logging for test and decorators", 3924 | "name": "pytest-xlog", 3925 | "version": "0.1.5" 3926 | }, 3927 | { 3928 | "description": "An extended parametrizing plugin of pytest.", 3929 | "name": "pytest-xpara", 3930 | "version": "0.1.1" 3931 | }, 3932 | { 3933 | "description": "A pytest plugin for managing processes across test runs.", 3934 | "name": "pytest-xprocess", 3935 | "version": "0.16.0" 3936 | }, 3937 | { 3938 | "description": "", 3939 | "name": "pytest-xray", 3940 | "version": "0.2.1" 3941 | }, 3942 | { 3943 | "description": "", 3944 | "name": "pytest-xray-server", 3945 | "version": "1.1" 3946 | }, 3947 | { 3948 | "description": "", 3949 | "name": "pytest-xrayjira", 3950 | "version": "1.0.2" 3951 | }, 3952 | { 3953 | "description": "A pytest plugin to run Xvfb for tests.", 3954 | "name": "pytest-xvfb", 3955 | "version": "2.0.0" 3956 | }, 3957 | { 3958 | "description": "This plugin is used to load yaml output to your test using pytest framework.", 3959 | "name": "pytest-yaml", 3960 | "version": "1.2.1" 3961 | }, 3962 | { 3963 | "description": "Create or check file/directory trees described by YAML", 3964 | "name": "pytest-yamltree", 3965 | "version": "0.1.2" 3966 | }, 3967 | { 3968 | "description": "Run tests against wsgi apps defined in yaml", 3969 | "name": "pytest-yamlwsgi", 3970 | "version": "0.6" 3971 | }, 3972 | { 3973 | "description": "Run yapf", 3974 | "name": "pytest-yapf", 3975 | "version": "0.1.1" 3976 | }, 3977 | { 3978 | "description": "Validate your Python file format with yapf", 3979 | "name": "pytest-yapf3", 3980 | "version": "0.6.1" 3981 | }, 3982 | { 3983 | "description": "PyTest plugin to run tests concurrently, each `yield` switch context to other one", 3984 | "name": "pytest-yield", 3985 | "version": "1.0.0" 3986 | }, 3987 | { 3988 | "description": "A Zafira plugin for pytest", 3989 | "name": "pytest-zafira", 3990 | "version": "1.0.3" 3991 | }, 3992 | { 3993 | "description": "OWASP ZAP plugin for py.test.", 3994 | "name": "pytest-zap", 3995 | "version": "0.2" 3996 | }, 3997 | { 3998 | "description": "Extend py.test for RPC OpenStack testing.", 3999 | "name": "pytest-zigzag", 4000 | "version": "1.1.1" 4001 | } 4002 | ] 4003 | -------------------------------------------------------------------------------- /pypi_rpc_client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytest-dev/plugincompat/148b892c7969f9d8e7800af0dd259a78bd70a438/pypi_rpc_client/__init__.py -------------------------------------------------------------------------------- /pypi_rpc_client/proxy.py: -------------------------------------------------------------------------------- 1 | import re 2 | import time 3 | from xmlrpc.client import Fault 4 | from xmlrpc.client import ServerProxy 5 | 6 | 7 | class RateLimitedProxy: 8 | """ 9 | RateLimitedProxy is a wrapper around the xmlrpc.client.ServerProxy module used to make requests to PyPI. 10 | The methods are identical to the xmlrpc.client.ServerProxy methods except for the fact that requests are throttled 11 | based on the return messages from PyPI. The need for rate limiting is due to the issue described in 12 | https://github.com/pypa/warehouse/issues/8753. 13 | 14 | Note that this class should be deprecated with a migration to PyPIJSON: https://wiki.python.org/moin/PyPIJSON 15 | """ 16 | 17 | def __init__(self, uri): 18 | self._server_proxy = ServerProxy(uri) 19 | 20 | def browse(self, classifiers): 21 | return self._rate_limit_request(self._server_proxy.browse, classifiers) 22 | 23 | def list_packages(self): 24 | return self._rate_limit_request(self._server_proxy.list_packages) 25 | 26 | def package_releases(self, package_name): 27 | return self._rate_limit_request(self._server_proxy.package_releases, package_name) 28 | 29 | def release_data(self, name, version): 30 | return self._rate_limit_request(self._server_proxy.release_data, name, version) 31 | 32 | def release_urls(self, name, version): 33 | return self._rate_limit_request(self._server_proxy.release_urls, name, version) 34 | 35 | def _rate_limit_request(self, request_method, *args): 36 | while True: 37 | try: 38 | return request_method(*args) 39 | except Fault as fault: 40 | # If PyPI errors due to too many requests, sleep and try again depending on the error message received 41 | # The fault message is of form: 42 | # The action could not be performed because there were too many requests by the client. Limit may reset in 1 seconds. 43 | limit_reset_regex_match = re.search( 44 | r"^.+Limit may reset in (\d+) seconds\.$", fault.faultString 45 | ) 46 | if limit_reset_regex_match is not None: 47 | sleep_amt = int(limit_reset_regex_match.group(1)) 48 | time.sleep(sleep_amt) 49 | continue 50 | 51 | # The fault message is of form: 52 | # The action could not be performed because there were too many requests by the client. 53 | too_many_requests_regex_match = re.search( 54 | "^.+The action could not be performed because there were too many requests by the client.$", 55 | fault.faultString, 56 | ) 57 | if too_many_requests_regex_match is not None: 58 | time.sleep(60) 59 | continue 60 | 61 | raise 62 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 100 3 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | trio_mode = true 3 | filterwarnings= 4 | ignore:"@coroutine" decorator is deprecated 5 | ignore:the imp module 6 | -------------------------------------------------------------------------------- /requirements.in: -------------------------------------------------------------------------------- 1 | asks 2 | attrs 3 | colorama 4 | distlib >= 0.2.8 5 | Flask 6 | gunicorn >= 19.5 7 | packaging 8 | psycopg2 9 | requests >= 1.3.0 10 | sqlalchemy 11 | tox 12 | trio 13 | wimpy >= 0.4 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile 6 | # 7 | anyio==1.4.0 # via asks 8 | appdirs==1.4.4 # via virtualenv 9 | asks==2.4.8 # via -r requirements.in 10 | async-generator==1.10 # via anyio, asks, trio 11 | attrs==20.1.0 # via -r requirements.in, outcome, trio 12 | certifi==2020.6.20 # via requests 13 | cffi==1.14.2 # via trio 14 | chardet==3.0.4 # via requests 15 | click==7.1.2 # via flask 16 | colorama==0.4.3 # via -r requirements.in, tox 17 | distlib==0.3.1 # via -r requirements.in, virtualenv 18 | filelock==3.0.12 # via tox, virtualenv 19 | flask==1.1.2 # via -r requirements.in 20 | gunicorn==20.0.4 # via -r requirements.in 21 | h11==0.10.0 # via asks 22 | idna==2.10 # via anyio, requests, trio 23 | itsdangerous==1.1.0 # via flask 24 | jinja2==2.11.2 # via flask 25 | markupsafe==1.1.1 # via jinja2 26 | outcome==1.0.1 # via trio 27 | packaging==20.4 # via -r requirements.in, tox 28 | pluggy==0.13.1 # via tox 29 | psycopg2==2.8.5 # via -r requirements.in 30 | py==1.9.0 # via tox 31 | pycparser==2.20 # via cffi 32 | pyparsing==2.4.7 # via packaging 33 | requests==2.24.0 # via -r requirements.in 34 | six==1.15.0 # via packaging, tox, virtualenv 35 | sniffio==1.1.0 # via anyio, trio 36 | sortedcontainers==2.2.2 # via trio 37 | sqlalchemy==1.3.19 # via -r requirements.in 38 | toml==0.10.1 # via tox 39 | tox==3.19.0 # via -r requirements.in 40 | trio==0.16.0 # via -r requirements.in 41 | urllib3==1.25.10 # via requests 42 | virtualenv==20.0.31 # via tox 43 | werkzeug==1.0.1 # via flask 44 | wimpy==0.6 # via -r requirements.in 45 | 46 | # The following packages are considered to be unsafe in a requirements file: 47 | # setuptools 48 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | """ 2 | Reads index.json file containing plugins versions and descriptions, and 3 | test them against current python version and pytest version selected by 4 | $PYTEST_VERSION environment variable. 5 | 6 | The plugins are tested using tox. If a plugin provides a tox.ini file, 7 | that is used to test the plugin compatibility, otherwise we provide a simple 8 | tox.ini that practically just tests that the plugin was installed successfully 9 | by running `pytest --help`. 10 | 11 | The pytest version to use is obtained by $PYTEST_VERSION, which is forced as 12 | a dependency when invoking tox. 13 | 14 | Once all results are obtained, they are posted to the plugincompat heroku app 15 | which can then be visualized. 16 | """ 17 | import json 18 | import os 19 | import shutil 20 | import subprocess 21 | import sys 22 | import tarfile 23 | import time 24 | import traceback 25 | from argparse import ArgumentParser 26 | from collections import defaultdict 27 | from collections import namedtuple 28 | from contextlib import closing 29 | from functools import partial 30 | from io import StringIO 31 | from tempfile import mkdtemp 32 | from typing import List 33 | from typing import Optional 34 | from zipfile import ZipFile 35 | 36 | import asks 37 | import attr 38 | import colorama 39 | import distlib 40 | import trio 41 | from colorama import Fore 42 | from distlib.wheel import is_compatible 43 | from wimpy.util import strip_suffix 44 | from wimpy.util import working_directory 45 | 46 | import update_index 47 | from pypi_rpc_client.proxy import RateLimitedProxy 48 | 49 | 50 | async def download_package(client, session, name, version): 51 | urls = client.release_urls(name, version) 52 | dists = defaultdict(list) 53 | for data in urls: 54 | dists[data.get("packagetype")].append(data) 55 | url = fname = None 56 | for sdist in dists["sdist"]: 57 | url = sdist["url"] 58 | fname = sdist["filename"] 59 | break 60 | else: 61 | for bdist in dists["bdist_wheel"]: 62 | try: 63 | if not is_compatible(bdist["filename"]): 64 | continue 65 | except distlib.DistlibException: 66 | # is_compatible may also raise exceptions with invalid wheel 67 | # files instead of returning False :/ 68 | continue 69 | else: 70 | url = bdist["url"] 71 | fname = bdist["filename"] 72 | break 73 | if fname is not None: 74 | response = await session.get(url) 75 | await trio.Path(fname).write_bytes(response.content) 76 | return fname 77 | 78 | 79 | def extract(basename): 80 | """ 81 | Extracts the contents of the given archive into the current directory. 82 | 83 | :param basename: name of the archive related to the current directory 84 | :type basename: str 85 | 86 | :rtype: str 87 | :return: the name of the directory where the contents where extracted 88 | """ 89 | 90 | extractors = {".zip": ZipFile, ".tar.gz": tarfile.open, ".tgz": tarfile.open} 91 | for ext, extractor in extractors.items(): 92 | if basename.endswith(ext): 93 | with closing(extractor(basename)) as f: 94 | f.extractall(".") 95 | return basename[: -len(ext)] 96 | raise Exception("could not extract %s" % basename) 97 | 98 | 99 | async def run_tox(target, tox_env, pytest_version, mode="sdist"): 100 | """ 101 | Runs tox on the given directory and return (exit code, output) 102 | """ 103 | if mode == "sdist": 104 | directory = target 105 | PLACEHOLDER_TOX = PLACEHOLDER_TOX_SDIST 106 | elif mode == "bdist_wheel": 107 | directory = strip_suffix(target, ".whl") 108 | os.makedirs(directory) 109 | PLACEHOLDER_TOX = PLACEHOLDER_TOX_BDIST.format(wheel_fname=target) 110 | else: 111 | raise NotImplementedError 112 | tox_file = os.path.join(directory, "tox.ini") 113 | if not os.path.isfile(tox_file): 114 | with open(tox_file, "w") as f: 115 | f.write(PLACEHOLDER_TOX) 116 | 117 | cmdline = "tox --result-json=result.json -e %s --force-dep=pytest==%s" 118 | cmdline %= (tox_env, pytest_version) 119 | args = cmdline.split() 120 | 121 | try: 122 | output = await trio.to_thread.run_sync( 123 | partial( 124 | subprocess.check_output, 125 | args, 126 | stderr=subprocess.STDOUT, 127 | cwd=directory, 128 | encoding="UTF-8", 129 | ), 130 | cancellable=True, 131 | ) 132 | except subprocess.CalledProcessError as e: 133 | result = e.returncode 134 | output = e.output 135 | else: 136 | result = 0 137 | 138 | return result, output 139 | 140 | 141 | # tox.ini contents when downloaded package does not have a tox.ini file 142 | # in this case we only display help information 143 | PLACEHOLDER_TOX_SDIST = """\ 144 | [tox] 145 | 146 | [testenv] 147 | deps = pytest 148 | commands = pytest --trace-config --help 149 | """ 150 | 151 | PLACEHOLDER_TOX_BDIST = """\ 152 | [tox] 153 | skipsdist = True 154 | 155 | [testenv] 156 | deps = 157 | pytest 158 | pip 159 | commands = 160 | pip install ../{wheel_fname} 161 | pytest --trace-config --help 162 | """ 163 | 164 | 165 | def read_plugins_index(file_name): 166 | with open(file_name) as f: 167 | return json.load(f) 168 | 169 | 170 | PackageResult = namedtuple( 171 | "PackageResult", "name version status_code status output description elapsed" 172 | ) 173 | 174 | 175 | @attr.s 176 | class ProgressCounter: 177 | """Keeps track of progress during the run process. 178 | 179 | Each task will receive an instance of this class, and should call ``increment_percentage`` 180 | to increment the total percentage and obtain it for printing. 181 | """ 182 | 183 | _total = attr.ib() 184 | _current = attr.ib(init=False, default=0) 185 | 186 | def increment_percentage(self): 187 | self._current += 1 188 | return self._current * 100 // self._total 189 | 190 | 191 | @attr.s 192 | class ResultsPoster: 193 | """ 194 | Posts results of running the 'tox' command of a package back to the plugin compat site. 195 | 196 | It will post results in batches of ``post_chunks``. 197 | """ 198 | 199 | session: asks.Session = attr.ib() 200 | batch_size: int = attr.ib() 201 | tox_env: str = attr.ib() 202 | pytest_version: str = attr.ib() 203 | secret: Optional[str] = attr.ib() 204 | _package_results: List[PackageResult] = attr.ib(init=False, factory=list) 205 | _total_posted: int = attr.ib(init=False, default=0) 206 | 207 | @property 208 | def total_posted(self): 209 | return self._total_posted 210 | 211 | async def maybe_post_batch(self, package_result): 212 | if package_result.status == "SKIPPED": 213 | return 214 | self._package_results.append(package_result) 215 | if len(self._package_results) >= self.batch_size: 216 | await self.post_all() 217 | 218 | async def post_all(self): 219 | results = [ 220 | { 221 | "name": package_result.name, 222 | "version": package_result.version, 223 | "env": self.tox_env, 224 | "pytest": self.pytest_version, 225 | "status": "ok" if package_result.status_code == 0 else "fail", 226 | "output": package_result.output, 227 | "description": package_result.description, 228 | } 229 | for package_result in sorted(self._package_results) 230 | ] 231 | self._package_results.clear() 232 | 233 | if self.secret: 234 | post_url = os.environ["PLUGINCOMPAT_SITE"] 235 | data = {"secret": self.secret, "results": results} 236 | headers = {"content-type": "application/json"} 237 | response = await self.session.post(post_url, data=json.dumps(data), headers=headers) 238 | response.raise_for_status() 239 | self._total_posted += len(results) 240 | print(Fore.GREEN + "Batch of {} posted".format(len(results))) 241 | else: 242 | msg = "Skipping posting batch of {} because secret is not available" 243 | print(Fore.YELLOW + msg.format(len(results))) 244 | 245 | 246 | async def run_package(session, tox_env, pytest_version, name, version, description): 247 | def get_elapsed(): 248 | return time.time() - start 249 | 250 | start = time.time() 251 | 252 | # if we already have results, skip testing this plugin 253 | url = os.environ.get("PLUGINCOMPAT_SITE") 254 | if url: 255 | params = dict(py=tox_env, pytest=pytest_version) 256 | try: 257 | response = await session.get( 258 | "{}/output/{}-{}".format(url, name, version), params=params 259 | ) 260 | if response.status_code == 200: 261 | return PackageResult( 262 | name, version, 0, "SKIPPED", "Skipped", description, get_elapsed() 263 | ) 264 | except Exception: 265 | pass 266 | 267 | client = RateLimitedProxy("https://pypi.org/pypi") 268 | basename = await download_package(client, session, name, version) 269 | if basename is None: 270 | status_code, output = 1, "No source or compatible distribution found" 271 | return PackageResult( 272 | name, version, status_code, "NO DIST", output, description, get_elapsed() 273 | ) 274 | if basename.endswith(".whl"): 275 | target = basename 276 | mode = "bdist_wheel" 277 | else: 278 | target = extract(basename) 279 | mode = "sdist" 280 | 281 | with trio.move_on_after(5 * 60) as scope: 282 | try: 283 | status_code, output = await run_tox(target, tox_env, pytest_version, mode) 284 | except Exception: 285 | stream = StringIO() 286 | traceback.print_exc(file=stream) 287 | status_code, output = 1, "traceback:\n%s" % stream.getvalue() 288 | 289 | if scope.cancelled_caught: 290 | status_code, output = 1, "tox run timed out" 291 | 292 | output += "\n\nTime: %.1f seconds" % get_elapsed() 293 | status = "PASSED" if status_code == 0 else "FAILED" 294 | return PackageResult(name, version, status_code, status, output, description, get_elapsed()) 295 | 296 | 297 | def print_package_result(progress_counter: ProgressCounter, package_result): 298 | status_color_map = { 299 | "SKIPPED": Fore.YELLOW, 300 | "NO DIST": Fore.MAGENTA, 301 | "PASSED": Fore.GREEN, 302 | "FAILED": Fore.RED, 303 | } 304 | package = "{}-{}".format(package_result.name, package_result.version) 305 | print( 306 | "{package:<60s} {status_color}{package_result.status:>15s}" 307 | "{elapsed_color}{package_result.elapsed:>6.1f}s " 308 | "{percent_color}[%{percent:>3d}]".format( 309 | package=package, 310 | status_color=status_color_map[package_result.status], 311 | package_result=package_result, 312 | elapsed_color=Fore.CYAN, 313 | percent_color=Fore.LIGHTCYAN_EX, 314 | percent=progress_counter.increment_percentage(), 315 | ) 316 | ) 317 | 318 | 319 | async def process_package( 320 | semaphore, 321 | session, 322 | results_poster: ResultsPoster, 323 | progress_counter: ProgressCounter, 324 | tox_env, 325 | pytest_version, 326 | name, 327 | version, 328 | description, 329 | *, 330 | task_status, 331 | ): 332 | async with semaphore: 333 | task_status.started() 334 | package_result = await run_package( 335 | session, tox_env, pytest_version, name, version, description 336 | ) 337 | print_package_result(progress_counter, package_result) 338 | await results_poster.maybe_post_batch(package_result) 339 | 340 | 341 | async def main(): 342 | strip = False if "TRAVIS" in os.environ else None 343 | colorama.init(autoreset=True, strip=strip) 344 | parser = ArgumentParser() 345 | parser.add_argument("--limit", type=int) 346 | parser.add_argument("--workers", type=int, default=8) 347 | parser.add_argument("--post-batches", type=int, default=10) 348 | 349 | args = parser.parse_args() 350 | limit = args.limit 351 | post_batches = args.post_batches 352 | 353 | pytest_version = os.environ["PYTEST_VERSION"] 354 | 355 | # important to remove POST_KEY from environment so others cannot sniff it somehow (#26) 356 | secret = os.environ.pop("POST_KEY", None) 357 | if secret is None and limit is None: 358 | # bail out early so CI doesn't take forever for a PR 359 | limit = args.post_batches * 3 360 | print(Fore.CYAN + "Limit forced to {} since secret is unavailable".format(limit)) 361 | 362 | tox_env = "py%d%d" % sys.version_info[:2] 363 | 364 | plugins = read_plugins_index(update_index.INDEX_FILE_NAME) 365 | if limit is not None: 366 | plugins = plugins[:limit] 367 | 368 | n_total = len(plugins) 369 | print(Fore.CYAN + f"Processing {len(plugins)} packages with {args.workers} workers") 370 | 371 | tmp = mkdtemp() 372 | async with asks.Session() as session: 373 | results_poster = ResultsPoster( 374 | session, 375 | batch_size=post_batches, 376 | tox_env=tox_env, 377 | pytest_version=pytest_version, 378 | secret=secret, 379 | ) 380 | progress_counter = ProgressCounter(n_total) 381 | semaphore = trio.Semaphore(args.workers) 382 | with working_directory(tmp): 383 | async with trio.open_nursery() as nursery: 384 | for plugin in plugins: 385 | await nursery.start( 386 | process_package, 387 | semaphore, 388 | session, 389 | results_poster, 390 | progress_counter, 391 | tox_env, 392 | pytest_version, 393 | plugin["name"], 394 | plugin["version"], 395 | plugin["description"], 396 | ) 397 | 398 | await results_poster.post_all() 399 | 400 | print() 401 | if results_poster.total_posted: 402 | print(Fore.GREEN + f"Posted {results_poster.total_posted} new results") 403 | print(Fore.GREEN + "All done, congratulations :)") 404 | 405 | shutil.rmtree(tmp, ignore_errors=True) 406 | 407 | 408 | if __name__ == "__main__": 409 | trio.run(main) 410 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.7.10 2 | -------------------------------------------------------------------------------- /static/electrical-plug-th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytest-dev/plugincompat/148b892c7969f9d8e7800af0dd259a78bd70a438/static/electrical-plug-th.png -------------------------------------------------------------------------------- /static/fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytest-dev/plugincompat/148b892c7969f9d8e7800af0dd259a78bd70a438/static/fail.png -------------------------------------------------------------------------------- /static/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytest-dev/plugincompat/148b892c7969f9d8e7800af0dd259a78bd70a438/static/ok.png -------------------------------------------------------------------------------- /static/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytest-dev/plugincompat/148b892c7969f9d8e7800af0dd259a78bd70a438/static/unknown.png -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 |
A list of plugins is now available at https://docs.pytest.org/en/latest/reference/plugin_list.html in the official pytest documentation.
11 | 12 |This website was an excellent learning tool and provided a nice list of all pytest plugins available. It implements a non-trivial workflow where we execute jobs on Travis that test each plugin for compatibility against some pytest and Python versions, along with their descriptions (more info).
13 | 14 |Maintaining the website has a non-zero cost in time, and also things are not perfect, so I decided to just stop maintaining it, given that the new list of plugins in pytest documentation already gives a good overview of the plugin ecosystem (see #66 for more details).
15 | 16 |The website will be shut down sometime in the future, but the github repository will remain there for reference.
17 | 18 |The source code of the website, for those interested, is available at github.com/pytest-dev/plugincompat.
-------------------------------------------------------------------------------- /templates/status_help.html: -------------------------------------------------------------------------------- 1 | 2 |The API will return an image response encoded as "image/png"
as content-type, representing the status
8 | of the plugin requested in the URL.
You must pass the following parameters to this query:
12 |For example, to query the status of plugin {{ name }} for 22 | python 3.3 and pytest version 2.4.2, hit this url:
23 | 24 |/status/{{ name }}?py=py33&pytest=2.4.2
25 |
--------------------------------------------------------------------------------
/test_run.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import sys
4 | import zipfile
5 | from pathlib import Path
6 | from shutil import copy
7 | from textwrap import dedent
8 |
9 | import asynctest
10 | import distlib
11 | import pytest
12 |
13 | import run
14 | from run import download_package
15 | from run import extract
16 | from run import main
17 | from run import PackageResult
18 | from run import read_plugins_index
19 |
20 |
21 | packages_results = {
22 | "pytest-plugin-a": PackageResult(
23 | name="pytest-plugin-a",
24 | version="0.1.1",
25 | status_code=0,
26 | status="PASSED",
27 | output="whatever 1",
28 | description="the description 1",
29 | elapsed=0,
30 | ),
31 | "pytest-plugin-b": PackageResult(
32 | name="pytest-plugin-b",
33 | version="0.2.2",
34 | status_code=1,
35 | status="FAILED",
36 | output="whatever 2",
37 | description="the description 2",
38 | elapsed=0,
39 | ),
40 | }
41 |
42 | canned_tox_ini = """\
43 | [tox]
44 |
45 | [testenv]
46 | commands = python -c "print('hi from tox')"
47 | """
48 |
49 |
50 | @pytest.fixture(autouse=True)
51 | def patch_env(monkeypatch):
52 | monkeypatch.setenv("PYTEST_VERSION", "1.2.3")
53 | monkeypatch.setenv("PLUGINCOMPAT_SITE", "http://plugincompat.example.com")
54 |
55 |
56 | @pytest.fixture(autouse=True)
57 | def fake_index_json(monkeypatch):
58 | canned_data = [
59 | {"description": "the description 1", "name": "pytest-plugin-a", "version": "0.1.1"},
60 | {"description": "the description 2", "name": "pytest-plugin-b", "version": "0.2.2"},
61 | {"description": "the description 3", "name": "pytest-plugin-c", "version": "0.3.3"},
62 | ]
63 | monkeypatch.setattr("run.read_plugins_index", lambda file_name: canned_data)
64 |
65 |
66 | @pytest.fixture(autouse=True)
67 | def freeze_time(monkeypatch):
68 | monkeypatch.setattr("time.time", lambda: 1535608108.637679)
69 |
70 |
71 | @pytest.fixture(autouse=True)
72 | def greyorama(monkeypatch):
73 | class Fore:
74 | def __getattr__(self, name):
75 | return ""
76 |
77 | monkeypatch.setattr("run.Fore", Fore())
78 |
79 |
80 | async def fake_run_package(session, tox_env, pytest_version, name, version, description):
81 | result = PackageResult(
82 | name=name,
83 | version=version,
84 | status_code=0,
85 | status="PASSED",
86 | output="whatever",
87 | description=description,
88 | elapsed=0,
89 | )
90 | return result
91 |
92 |
93 | @pytest.fixture(name="mock_session")
94 | def mock_session_():
95 | session = asynctest.MagicMock()
96 | session.post = asynctest.CoroutineMock()
97 | session.get = asynctest.CoroutineMock()
98 | return session
99 |
100 |
101 | async def test_main(monkeypatch, capsys):
102 | collected = []
103 |
104 | class FakeResultsPoster:
105 | def __init__(self, *args, **kwargs):
106 | pass
107 |
108 | async def maybe_post_batch(self, package_result):
109 | collected.append(package_result)
110 |
111 | async def post_all(self):
112 | pass
113 |
114 | @property
115 | def total_posted(self):
116 | return len(collected)
117 |
118 | monkeypatch.setattr("run.ResultsPoster", FakeResultsPoster)
119 | monkeypatch.setattr("run.run_package", fake_run_package)
120 | monkeypatch.setattr("sys.argv", ["run.py", "--limit=2", "--workers=1"])
121 | monkeypatch.setattr("colorama.init", lambda autoreset, strip: None)
122 | monkeypatch.setenv("POST_KEY", "my cat's breath smells like cat food")
123 | await main()
124 | out, err = capsys.readouterr()
125 | assert err == ""
126 | assert out == dedent(
127 | """\
128 | Processing 2 packages with 1 workers
129 | pytest-plugin-a-0.1.1 PASSED 0.0s [% 50]
130 | pytest-plugin-b-0.2.2 PASSED 0.0s [%100]
131 |
132 | Posted 2 new results
133 | All done, congratulations :)
134 | """
135 | )
136 | assert collected == [
137 | PackageResult(
138 | name="pytest-plugin-a",
139 | version="0.1.1",
140 | status_code=0,
141 | status="PASSED",
142 | output="whatever",
143 | description="the description 1",
144 | elapsed=0,
145 | ),
146 | PackageResult(
147 | name="pytest-plugin-b",
148 | version="0.2.2",
149 | status_code=0,
150 | status="PASSED",
151 | output="whatever",
152 | description="the description 2",
153 | elapsed=0,
154 | ),
155 | ]
156 |
157 |
158 | async def test_post_test_results(capsys, mock_session):
159 |
160 | poster = run.ResultsPoster(
161 | mock_session, batch_size=2, tox_env="py38", pytest_version="3.5.2", secret="ILIKETURTLES"
162 | )
163 | await poster.maybe_post_batch(packages_results["pytest-plugin-a"])
164 | assert mock_session.post.call_count == 0 # not posted yet
165 |
166 | await poster.maybe_post_batch(packages_results["pytest-plugin-b"])
167 | assert mock_session.post.call_count == 1
168 | out, err = capsys.readouterr()
169 | assert err == ""
170 | assert "Batch of 2 posted\n" in out
171 | assert mock_session.post.call_count == 1
172 | args, kwargs = mock_session.post.call_args
173 | assert args[0] == "http://plugincompat.example.com"
174 | assert json.loads(kwargs["data"]) == {
175 | "results": [
176 | {
177 | "description": "the description 1",
178 | "env": "py38",
179 | "name": "pytest-plugin-a",
180 | "output": "whatever 1",
181 | "pytest": "3.5.2",
182 | "status": "ok",
183 | "version": "0.1.1",
184 | },
185 | {
186 | "description": "the description 2",
187 | "env": "py38",
188 | "name": "pytest-plugin-b",
189 | "output": "whatever 2",
190 | "pytest": "3.5.2",
191 | "status": "fail",
192 | "version": "0.2.2",
193 | },
194 | ],
195 | "secret": "ILIKETURTLES",
196 | }
197 |
198 |
199 | async def test_no_post_if_no_secret(capsys, mock_session):
200 | poster = run.ResultsPoster(
201 | mock_session, batch_size=1, tox_env="py38", pytest_version="3.5.2", secret=None
202 | )
203 | await poster.maybe_post_batch(packages_results["pytest-plugin-a"])
204 | out, err = capsys.readouterr()
205 | assert err == ""
206 | assert "Skipping posting batch of 1 because secret is not available" in out
207 |
208 |
209 | async def test_process_package_skips_if_result_already_on_plugincompat_website(mock_session):
210 | mock_session.get.return_value.status_code = 200
211 | result = await run.run_package(
212 | session=mock_session,
213 | tox_env="py10",
214 | pytest_version="1.2.3",
215 | name="myplugin",
216 | version="1.0",
217 | description="'sup",
218 | )
219 | assert mock_session.get.call_count == 1
220 | args, kwargs = mock_session.get.call_args
221 | assert args[0] == "http://plugincompat.example.com/output/myplugin-1.0"
222 | assert kwargs["params"] == dict(py="py10", pytest="1.2.3")
223 | assert result == PackageResult(
224 | name="myplugin",
225 | version="1.0",
226 | status_code=0,
227 | status="SKIPPED",
228 | output="Skipped",
229 | description="'sup",
230 | elapsed=0.0,
231 | )
232 |
233 |
234 | async def test_process_package_no_dist_available(monkeypatch, mock_session):
235 | mock_session.get.return_value.status_code = 404
236 | with asynctest.patch("run.download_package", return_value=None, autospec=True):
237 | result = await run.run_package(
238 | mock_session,
239 | tox_env="py10",
240 | pytest_version="1.2.3",
241 | name="myplugin",
242 | version="1.0",
243 | description="'sup",
244 | )
245 |
246 | assert mock_session.get.call_count == 1
247 | args, kwargs = mock_session.get.call_args
248 | assert args[0] == "http://plugincompat.example.com/output/myplugin-1.0"
249 | assert kwargs["params"] == dict(py="py10", pytest="1.2.3")
250 | assert result == PackageResult(
251 | name="myplugin",
252 | version="1.0",
253 | status_code=1,
254 | status="NO DIST",
255 | output="No source or compatible distribution found",
256 | description="'sup",
257 | elapsed=0.0,
258 | )
259 |
260 |
261 | async def test_process_package_tox_errored(tmpdir, monkeypatch, mock_session):
262 | mock_session.get.return_value.status_code = 404
263 | monkeypatch.chdir(tmpdir)
264 |
265 | tmpdir.join("myplugin").ensure_dir()
266 | tmpdir.join("myplugin").join("setup.py").ensure(file=True)
267 | with zipfile.ZipFile(str(tmpdir / "myplugin.zip"), mode="w") as z:
268 | z.write("myplugin")
269 |
270 | with asynctest.patch("run.download_package", return_value="myplugin.zip", autospec=True):
271 | result = await run.run_package(
272 | mock_session,
273 | tox_env="py36",
274 | pytest_version="1.2.3",
275 | name="myplugin",
276 | version="1.0",
277 | description="'sup",
278 | )
279 | assert result.name == "myplugin"
280 | assert result.status_code == 1
281 | assert result.status == "FAILED"
282 | assert "ERROR: setup.py is empty" in result.output
283 |
284 |
285 | async def test_process_package_tox_crash(tmpdir, monkeypatch, mock_session):
286 | mock_session.get.return_value.status_code = 404
287 | monkeypatch.chdir(tmpdir)
288 |
289 | empty_zipfile_bytes = b"PK\x05\x06" + b"\x00" * 18
290 | tmpdir.join("myplugin.zip").write(empty_zipfile_bytes)
291 |
292 | with asynctest.patch("run.download_package", return_value="myplugin.zip", autospec=True):
293 | result = await run.run_package(
294 | mock_session,
295 | tox_env="py36",
296 | pytest_version="1.2.3",
297 | name="myplugin",
298 | version="1.0",
299 | description="'sup",
300 | )
301 | assert result.name == "myplugin"
302 | assert result.status_code == 1
303 | assert result.status == "FAILED"
304 | assert result.output.startswith("traceback:\n")
305 | fn = os.path.join("myplugin", "tox.ini")
306 | assert "No such file or directory: {fn!r}".format(fn=fn) in result.output
307 |
308 |
309 | async def test_process_package_tox_succeeded(tmpdir, monkeypatch, mock_session):
310 | py = "py{}{}".format(*sys.version_info[:2])
311 | mock_session.get.return_value.status_code = 404
312 |
313 | monkeypatch.chdir(tmpdir)
314 | tmpdir.join("myplugin").ensure_dir()
315 | tmpdir.join("myplugin").join("setup.py").write(
316 | "from distutils.core import setup\nsetup(name='myplugin', version='1.0')"
317 | )
318 | tmpdir.join("myplugin").join("tox.ini").write(canned_tox_ini)
319 | with zipfile.ZipFile(str(tmpdir / "myplugin.zip"), mode="w") as z:
320 | z.write("myplugin")
321 | with asynctest.patch("run.download_package", return_value="myplugin.zip", autospec=True):
322 | result = await run.run_package(
323 | mock_session,
324 | tox_env=py,
325 | pytest_version="3.7.4",
326 | name="myplugin",
327 | version="1.0",
328 | description="'sup",
329 | )
330 | assert result.name == "myplugin"
331 | assert result.version == "1.0"
332 | assert result.status_code == 0
333 | assert result.status == "PASSED"
334 | assert result.description == "'sup"
335 | assert result.elapsed == 0.0
336 | assert "hi from tox" in result.output
337 | assert "congratulations :)" in result.output
338 |
339 |
340 | def test_unsupported_extraction_file_extension():
341 | with pytest.raises(Exception, match="could not extract myplugin.dat"):
342 | extract("myplugin.dat")
343 |
344 |
345 | def test_read_plugins(monkeypatch, tmpdir):
346 | monkeypatch.chdir(tmpdir)
347 | tmpdir.join("index.json").write('{"k":"v"}')
348 | result = read_plugins_index(file_name="index.json")
349 | assert result == {"k": "v"}
350 |
351 |
352 | async def test_download_package(mock_session):
353 | mock_session.get.return_value.content = expected_content = b"some contents"
354 |
355 | class FakeClient:
356 | def release_urls(self, name, version):
357 | return [
358 | {
359 | "filename": "whatever.tar.gz",
360 | "url": "/path/to/whatever.tar.gz",
361 | "packagetype": "sdist",
362 | }
363 | ]
364 |
365 | basename = await download_package(
366 | client=FakeClient(), session=mock_session, name="whatever", version="1.0"
367 | )
368 | assert mock_session.get.call_args[0][0] == "/path/to/whatever.tar.gz"
369 | assert basename == "whatever.tar.gz"
370 | assert Path(basename).read_bytes() == expected_content
371 |
372 |
373 | async def test_download_package_whl(monkeypatch, mocker, mock_session):
374 | mock_session.get.return_value.content = b"some contents"
375 |
376 | m = mocker.patch.object(run, "is_compatible", autospec=True, return_value=True)
377 |
378 | class FakeClient:
379 | def release_urls(self, name, version):
380 | return [
381 | {
382 | "filename": "myplugin-1.0.0-py2.py3-none-any.whl",
383 | "url": "/path/to/myplugin-1.0.0-py2.py3-none-any.whl",
384 | "packagetype": "bdist_wheel",
385 | }
386 | ]
387 |
388 | basename = await download_package(
389 | session=mock_session, client=FakeClient(), name="myplugin", version="1.0"
390 | )
391 | assert basename == "myplugin-1.0.0-py2.py3-none-any.whl"
392 |
393 | # incompatible wheel
394 | m.return_value = False
395 | assert (
396 | await download_package(
397 | session=mock_session, client=FakeClient(), name="myplugin", version="1.0"
398 | )
399 | is None
400 | )
401 |
402 | # invalid wheel
403 | m.side_effect = distlib.DistlibException()
404 | assert (
405 | await download_package(
406 | session=mock_session, client=FakeClient(), name="myplugin", version="1.0"
407 | )
408 | is None
409 | )
410 |
411 |
412 | async def test_process_package_tox_succeeded_bdist(datadir, monkeypatch, mock_session):
413 | py = "py{}{}".format(*sys.version_info[:2])
414 | mock_session.get.return_value.status_code = 404
415 |
416 | monkeypatch.chdir(datadir)
417 |
418 | with asynctest.patch(
419 | "run.download_package", return_value="myplugin-1.0.0-py2.py3-none-any.whl", autospec=True
420 | ):
421 | result = await run.run_package(
422 | session=mock_session,
423 | tox_env=py,
424 | pytest_version="3.7.4",
425 | name="myplugin",
426 | version="1.0.0",
427 | description="nope",
428 | )
429 | print(result.output)
430 | assert result.name == "myplugin"
431 | assert result.version == "1.0.0"
432 | assert result.status_code == 0
433 | assert result.status == "PASSED"
434 | assert result.description == "nope"
435 | assert result.elapsed == 0.0
436 | assert "hi from tox" not in result.output
437 | assert "hello world from .whl pytest plugin" in result.output
438 | assert "PLUGIN registered: