Compare commits
154 Commits
wip_fix_ca
...
7.0.0.dev0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
109312ba86 | ||
|
|
2623ee2e0e | ||
|
|
ba1ad7d517 | ||
|
|
c4c3b6d4fd | ||
|
|
e729e0d1e6 | ||
|
|
c19f63d39d | ||
|
|
51742e14a1 | ||
|
|
6573107b97 | ||
|
|
ef395e1c38 | ||
|
|
f0e5640497 | ||
|
|
cb1dba0489 | ||
|
|
0d6cb3b281 | ||
|
|
d7b0e17205 | ||
|
|
942789bace | ||
|
|
f573b56bb6 | ||
|
|
e44300de7e | ||
|
|
8eb8c42bd6 | ||
|
|
ac10fe0679 | ||
|
|
0a6a1fa225 | ||
|
|
d2886b8d23 | ||
|
|
68b329dda8 | ||
|
|
ab3cd644dc | ||
|
|
a1967e9594 | ||
|
|
c4da6fff42 | ||
|
|
605fe29d12 | ||
|
|
ced125ad15 | ||
|
|
7eb0792cba | ||
|
|
6447ca5f1e | ||
|
|
5ea541d415 | ||
|
|
c675d8054d | ||
|
|
16685dc279 | ||
|
|
c85b21eaa0 | ||
|
|
fb7e36b2f7 | ||
|
|
c94766a580 | ||
|
|
85faaf8a1d | ||
|
|
5a9139c5ec | ||
|
|
b04aa015b9 | ||
|
|
657e35618f | ||
|
|
8010fb9f40 | ||
|
|
58036d463d | ||
|
|
992eabc29e | ||
|
|
479209bde1 | ||
|
|
68bb0db808 | ||
|
|
595b7e894c | ||
|
|
bce0ceafe4 | ||
|
|
50b166ff0b | ||
|
|
8300b266a8 | ||
|
|
7fb5a9d033 | ||
|
|
bb9683deea | ||
|
|
77235e2759 | ||
|
|
9ad726a9a0 | ||
|
|
cde6920e49 | ||
|
|
c51520ab2a | ||
|
|
360ce686f1 | ||
|
|
7ce69347ce | ||
|
|
788d8785ce | ||
|
|
cf7425d22b | ||
|
|
20f00997ff | ||
|
|
4b7d8b2edd | ||
|
|
43faea832d | ||
|
|
798bca4076 | ||
|
|
627b446252 | ||
|
|
640b2c0e13 | ||
|
|
1d5ee4dd7c | ||
|
|
1ba5b48565 | ||
|
|
1b5f5326d7 | ||
|
|
c5bf5f6fb0 | ||
|
|
ef9d01826a | ||
|
|
847d8f42ea | ||
|
|
e6ed28f0e7 | ||
|
|
9719237fe6 | ||
|
|
c0d525e44c | ||
|
|
88d84a5791 | ||
|
|
4a472952f7 | ||
|
|
538b5c2499 | ||
|
|
c90fdc684b | ||
|
|
11538e35e4 | ||
|
|
c198a7a67e | ||
|
|
ff6d29717c | ||
|
|
864a2bc0a3 | ||
|
|
6bc6ec323a | ||
|
|
e2567a680e | ||
|
|
d52cd08757 | ||
|
|
249c5b37dd | ||
|
|
0d502328ea | ||
|
|
53a74feea7 | ||
|
|
88944bec6a | ||
|
|
8872e8e7c7 | ||
|
|
eb7acba9e9 | ||
|
|
e59d0c461b | ||
|
|
3f414d7bbe | ||
|
|
dd8ad3fa9c | ||
|
|
06718da5d6 | ||
|
|
c73e354019 | ||
|
|
2414d23c78 | ||
|
|
24ad886b15 | ||
|
|
dbe66d97b4 | ||
|
|
b8f1b7cdc6 | ||
|
|
a69ed66c2e | ||
|
|
6ae71a2c2b | ||
|
|
8b2f83772d | ||
|
|
c516dba69a | ||
|
|
33c6ad5bf7 | ||
|
|
364bbe42fc | ||
|
|
c5de274136 | ||
|
|
850a844779 | ||
|
|
51293de324 | ||
|
|
0d6e3b7005 | ||
|
|
045ad5ac2d | ||
|
|
7cec85a37d | ||
|
|
b4cd14aae3 | ||
|
|
822624c252 | ||
|
|
0a07b71046 | ||
|
|
48f14c48ea | ||
|
|
c519dd64ed | ||
|
|
e0a3dc7bf8 | ||
|
|
7caf47acc6 | ||
|
|
337a729d95 | ||
|
|
6b53714d57 | ||
|
|
647ac4a79d | ||
|
|
3ae0103975 | ||
|
|
9e11d645b1 | ||
|
|
80acc0ed6f | ||
|
|
1e3fcece6d | ||
|
|
886fd70e2a | ||
|
|
124691122a | ||
|
|
113a860a1f | ||
|
|
4b6188b3b1 | ||
|
|
634312b14a | ||
|
|
245eefafcf | ||
|
|
adc197424d | ||
|
|
385988ca1a | ||
|
|
b7416f7abd | ||
|
|
a62a28b4b8 | ||
|
|
2534b7725e | ||
|
|
27564e7768 | ||
|
|
915ff7640b | ||
|
|
5ae2106059 | ||
|
|
3f71d63067 | ||
|
|
4fc67eea4f | ||
|
|
382599287f | ||
|
|
61be48b485 | ||
|
|
e354c5c919 | ||
|
|
710446420c | ||
|
|
f1570dc038 | ||
|
|
2637ec3921 | ||
|
|
4e048e0827 | ||
|
|
f772e5e2b3 | ||
|
|
9c4da3e7b6 | ||
|
|
f1a97512da | ||
|
|
9fa205290e | ||
|
|
8f49ffdb57 | ||
|
|
9d9b84d175 | ||
|
|
992c403fc8 |
31
.github/workflows/main.yml
vendored
31
.github/workflows/main.yml
vendored
@@ -14,10 +14,18 @@ on:
|
||||
- main
|
||||
- "[0-9]+.[0-9]+.x"
|
||||
|
||||
env:
|
||||
PYTEST_ADDOPTS: "--color=yes"
|
||||
|
||||
# Set permissions at the job level.
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -137,10 +145,13 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python ${{ matrix.python }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
@@ -162,19 +173,29 @@ jobs:
|
||||
|
||||
linting:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
|
||||
- name: set PY
|
||||
run: echo "name=PY::$(python -c 'import hashlib, sys;print(hashlib.sha256(sys.version.encode()+sys.executable.encode()).hexdigest())')" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install tox
|
||||
|
||||
- run: tox -e linting
|
||||
|
||||
deploy:
|
||||
@@ -182,6 +203,8 @@ jobs:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
needs: [build]
|
||||
|
||||
@@ -189,25 +212,31 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.7"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade wheel setuptools tox
|
||||
|
||||
- name: Build package
|
||||
run: |
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
- name: Publish package to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_token }}
|
||||
|
||||
- name: Publish GitHub release notes
|
||||
env:
|
||||
GH_RELEASE_NOTES_TOKEN: ${{ secrets.release_notes }}
|
||||
GH_RELEASE_NOTES_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
sudo apt-get install pandoc
|
||||
tox -e publish-gh-release-notes
|
||||
|
||||
15
.github/workflows/prepare-release-pr.yml
vendored
15
.github/workflows/prepare-release-pr.yml
vendored
@@ -11,15 +11,26 @@ on:
|
||||
description: 'Major release? (yes/no)'
|
||||
required: true
|
||||
default: 'no'
|
||||
prerelease:
|
||||
description: 'Prerelease (ex: rc1). Leave empty if not a pre-release.'
|
||||
required: true
|
||||
default: ''
|
||||
|
||||
# Set permissions at the job level.
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
@@ -34,9 +45,9 @@ jobs:
|
||||
- name: Prepare release PR (minor/patch release)
|
||||
if: github.event.inputs.major == 'no'
|
||||
run: |
|
||||
tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ secrets.chatops }}
|
||||
tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ github.token }} --prerelease '${{ github.event.inputs.prerelease }}'
|
||||
|
||||
- name: Prepare release PR (major release)
|
||||
if: github.event.inputs.major == 'yes'
|
||||
run: |
|
||||
tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ secrets.chatops }} --major
|
||||
tox -e prepare-release-pr -- ${{ github.event.inputs.branch }} ${{ github.token }} --major --prerelease '${{ github.event.inputs.prerelease }}'
|
||||
|
||||
31
.github/workflows/release-on-comment.yml
vendored
31
.github/workflows/release-on-comment.yml
vendored
@@ -1,31 +0,0 @@
|
||||
# part of our release process, see `release-on-comment.py`
|
||||
name: release on comment
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: (github.event.comment && startsWith(github.event.comment.body, '@pytestbot please')) || (github.event.issue && !github.event.comment && startsWith(github.event.issue.body, '@pytestbot please'))
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.8"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade setuptools tox
|
||||
- name: Prepare release
|
||||
run: |
|
||||
tox -e release-on-comment -- $GITHUB_EVENT_PATH ${{ secrets.chatops }}
|
||||
13
.github/workflows/update-plugin-list.yml
vendored
13
.github/workflows/update-plugin-list.yml
vendored
@@ -7,22 +7,35 @@ on:
|
||||
- cron: '0 0 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
# Set permissions at the job level.
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
createPullRequest:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install packaging requests tabulate[widechars]
|
||||
|
||||
- name: Update Plugin List
|
||||
run: python scripts/update-plugin-list.py
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@2455e1596942c2902952003bbb574afbbe2ab2e6
|
||||
with:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 21.4b0
|
||||
rev: 21.6b0
|
||||
hooks:
|
||||
- id: black
|
||||
args: [--safe, --quiet]
|
||||
@@ -10,7 +10,7 @@ repos:
|
||||
- id: blacken-docs
|
||||
additional_dependencies: [black==20.8b1]
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
@@ -21,7 +21,7 @@ repos:
|
||||
exclude: _pytest/(debugging|hookspec).py
|
||||
language_version: python3
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 3.9.1
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
language_version: python3
|
||||
@@ -34,7 +34,7 @@ repos:
|
||||
- id: reorder-python-imports
|
||||
args: ['--application-directories=.:src', --py36-plus]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.13.0
|
||||
rev: v2.19.4
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py36-plus]
|
||||
@@ -44,11 +44,11 @@ repos:
|
||||
- id: setup-cfg-fmt
|
||||
args: [--max-py-version=3.10]
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.8.0
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: python-use-type-annotations
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.812
|
||||
rev: v0.902
|
||||
hooks:
|
||||
- id: mypy
|
||||
files: ^(src/|testing/)
|
||||
@@ -58,6 +58,8 @@ repos:
|
||||
- py>=1.8.2
|
||||
- attrs>=19.2.0
|
||||
- packaging
|
||||
- types-toml
|
||||
- types-pkg_resources
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: rst
|
||||
|
||||
8
AUTHORS
8
AUTHORS
@@ -24,6 +24,7 @@ Andras Tim
|
||||
Andrea Cimatoribus
|
||||
Andreas Motl
|
||||
Andreas Zeidler
|
||||
Andrew Shapton
|
||||
Andrey Paramonov
|
||||
Andrzej Klajnert
|
||||
Andrzej Ostrowski
|
||||
@@ -61,6 +62,7 @@ Charles Machalow
|
||||
Charnjit SiNGH (CCSJ)
|
||||
Chris Lamb
|
||||
Chris NeJame
|
||||
Chris Rose
|
||||
Christian Boelsen
|
||||
Christian Fetzer
|
||||
Christian Neumüller
|
||||
@@ -142,6 +144,7 @@ Iwan Briquemont
|
||||
Jaap Broekhuizen
|
||||
Jakob van Santen
|
||||
Jakub Mitoraj
|
||||
James Bourbeau
|
||||
Jan Balster
|
||||
Janne Vanhala
|
||||
Jason R. Coombs
|
||||
@@ -162,6 +165,7 @@ Josh Karpel
|
||||
Joshua Bronson
|
||||
Jurko Gospodnetić
|
||||
Justyna Janczyszyn
|
||||
Justice Ndou
|
||||
Kale Kundert
|
||||
Kamran Ahmad
|
||||
Karl O. Pinc
|
||||
@@ -229,6 +233,7 @@ Nicholas Murphy
|
||||
Niclas Olofsson
|
||||
Nicolas Delaby
|
||||
Nikolay Kondratyev
|
||||
Olga Matoula
|
||||
Oleg Pidsadnyi
|
||||
Oleg Sushchenko
|
||||
Oliver Bestwalter
|
||||
@@ -236,6 +241,7 @@ Omar Kohl
|
||||
Omer Hadari
|
||||
Ondřej Súkup
|
||||
Oscar Benjamin
|
||||
Parth Patel
|
||||
Patrick Hayes
|
||||
Pauli Virtanen
|
||||
Pavel Karateev
|
||||
@@ -270,6 +276,7 @@ Ross Lawley
|
||||
Ruaridh Williamson
|
||||
Russel Winder
|
||||
Ryan Wooden
|
||||
Saiprasad Kale
|
||||
Samuel Dion-Girardeau
|
||||
Samuel Searles-Bryant
|
||||
Samuele Pedroni
|
||||
@@ -330,5 +337,6 @@ Xuan Luong
|
||||
Xuecong Liao
|
||||
Yoav Caspi
|
||||
Zac Hatfield-Dodds
|
||||
Zachary Kneupper
|
||||
Zoltán Máté
|
||||
Zsolt Cserna
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2004-2020 Holger Krekel and others
|
||||
Copyright (c) 2004-2021 Holger Krekel and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
@@ -93,7 +93,7 @@ Features
|
||||
|
||||
- Python 3.6+ and PyPy3
|
||||
|
||||
- Rich plugin architecture, with over 850+ `external plugins <https://docs.pytest.org/en/stable/plugin_list.html>`_ and thriving community
|
||||
- Rich plugin architecture, with over 850+ `external plugins <https://docs.pytest.org/en/latest/reference/plugin_list.html>`_ and thriving community
|
||||
|
||||
|
||||
Documentation
|
||||
|
||||
100
RELEASING.rst
100
RELEASING.rst
@@ -14,60 +14,90 @@ Preparing: Automatic Method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We have developed an automated workflow for releases, that uses GitHub workflows and is triggered
|
||||
by opening an issue.
|
||||
by `manually running <https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow>`__
|
||||
the `prepare-release-pr workflow <https://github.com/pytest-dev/pytest/actions/workflows/prepare-release-pr.yml>`__
|
||||
on GitHub Actions.
|
||||
|
||||
Bug-fix releases
|
||||
^^^^^^^^^^^^^^^^
|
||||
The automation will decide the new version number based on the following criteria:
|
||||
|
||||
A bug-fix release is always done from a maintenance branch, so for example to release bug-fix
|
||||
``5.1.2``, open a new issue and add this comment to the body::
|
||||
- If the "major release" input is set to "yes", release a new major release
|
||||
(e.g. 7.0.0 -> 8.0.0)
|
||||
- If there are any ``.feature.rst`` or ``.breaking.rst`` files in the
|
||||
``changelog`` directory, release a new minor release (e.g. 7.0.0 -> 7.1.0)
|
||||
- Otherwise, release a bugfix release (e.g. 7.0.0 -> 7.0.1)
|
||||
- If the "prerelease" input is set, append the string to the version number
|
||||
(e.g. 7.0.0 -> 8.0.0rc1), if "major" is set, and "prerelease" is set to `rc1`)
|
||||
|
||||
@pytestbot please prepare release from 5.1.x
|
||||
Bug-fix and minor releases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Where ``5.1.x`` is the maintenance branch for the ``5.1`` series.
|
||||
Bug-fix and minor releases are always done from a maintenance branch. First,
|
||||
consider double-checking the ``changelog`` directory to see if there are any
|
||||
breaking changes or new features.
|
||||
|
||||
The automated workflow will publish a PR for a branch ``release-5.1.2``
|
||||
and notify it as a comment in the issue.
|
||||
For a new minor release, first create a new maintenance branch from ``main``::
|
||||
|
||||
Minor releases
|
||||
git fetch --all
|
||||
git branch 7.1.x upstream/main
|
||||
git push upstream 7.1.x
|
||||
|
||||
Then, trigger the workflow with the following inputs:
|
||||
|
||||
- branch: **7.1.x**
|
||||
- major release: **no**
|
||||
- prerelease: empty
|
||||
|
||||
Or via the commandline using `GitHub's cli <https://github.com/cli/cli>`__::
|
||||
|
||||
gh workflow run prepare-release-pr.yml -f branch=7.1.x -f major=no -f prerelease=
|
||||
|
||||
Where ``7.1.x`` is the maintenance branch for the ``7.1`` series. The automated
|
||||
workflow will publish a PR for a branch ``release-7.1.0``.
|
||||
|
||||
Similarly, for a bug-fix release, use the existing maintenance branch and
|
||||
trigger the workflow with e.g. ``branch: 7.0.x`` to get a new ``release-7.0.1``
|
||||
PR.
|
||||
|
||||
Major releases
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
1. Create a new maintenance branch from ``main``::
|
||||
|
||||
git fetch --all
|
||||
git branch 5.2.x upstream/main
|
||||
git push upstream 5.2.x
|
||||
git branch 8.0.x upstream/main
|
||||
git push upstream 8.0.x
|
||||
|
||||
2. Open a new issue and add this comment to the body::
|
||||
2. Trigger the workflow with the following inputs:
|
||||
|
||||
@pytestbot please prepare release from 5.2.x
|
||||
- branch: **8.0.x**
|
||||
- major release: **yes**
|
||||
- prerelease: empty
|
||||
|
||||
The automated workflow will publish a PR for a branch ``release-5.2.0`` and
|
||||
notify it as a comment in the issue.
|
||||
Or via the commandline::
|
||||
|
||||
Major and release candidates
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
gh workflow run prepare-release-pr.yml -f branch=8.0.x -f major=yes -f prerelease=
|
||||
|
||||
1. Create a new maintenance branch from ``main``::
|
||||
|
||||
git fetch --all
|
||||
git branch 6.0.x upstream/main
|
||||
git push upstream 6.0.x
|
||||
|
||||
2. For a **major release**, open a new issue and add this comment in the body::
|
||||
|
||||
@pytestbot please prepare major release from 6.0.x
|
||||
|
||||
For a **release candidate**, the comment must be (TODO: `#7551 <https://github.com/pytest-dev/pytest/issues/7551>`__)::
|
||||
|
||||
@pytestbot please prepare release candidate from 6.0.x
|
||||
|
||||
The automated workflow will publish a PR for a branch ``release-6.0.0`` and
|
||||
notify it as a comment in the issue.
|
||||
The automated workflow will publish a PR for a branch ``release-8.0.0``.
|
||||
|
||||
At this point on, this follows the same workflow as other maintenance branches: bug-fixes are merged
|
||||
into ``main`` and ported back to the maintenance branch, even for release candidates.
|
||||
|
||||
Release candidates
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To release a release candidate, set the "prerelease" input to the version number
|
||||
suffix to use. To release a ``8.0.0rc1``, proceed like under "major releases", but set:
|
||||
|
||||
- branch: 8.0.x
|
||||
- major release: yes
|
||||
- prerelease: **rc1**
|
||||
|
||||
Or via the commandline::
|
||||
|
||||
gh workflow run prepare-release-pr.yml -f branch=8.0.x -f major=yes -f prerelease=rc1
|
||||
|
||||
The automated workflow will publish a PR for a branch ``release-8.0.0rc1``.
|
||||
|
||||
**A note about release candidates**
|
||||
|
||||
During release candidates we can merge small improvements into
|
||||
@@ -117,7 +147,7 @@ Both automatic and manual processes described above follow the same steps from t
|
||||
#. Cherry-pick the CHANGELOG / announce files to the ``main`` branch::
|
||||
|
||||
git fetch --all --prune
|
||||
git checkout origin/main -b cherry-pick-release
|
||||
git checkout upstream/main -b cherry-pick-release
|
||||
git cherry-pick -x -m1 upstream/MAJOR.MINOR.x
|
||||
|
||||
#. Open a PR for ``cherry-pick-release`` and merge it once CI passes. No need to wait for approvals if there were no conflicts on the previous step.
|
||||
|
||||
@@ -25,6 +25,7 @@ The current list of contributors receiving funding are:
|
||||
|
||||
* `@asottile`_
|
||||
* `@nicoddemus`_
|
||||
* `@The-Compiler`_
|
||||
|
||||
Contributors interested in receiving a part of the funds just need to submit a PR adding their
|
||||
name to the list. Contributors that want to stop receiving the funds should also submit a PR
|
||||
@@ -56,3 +57,4 @@ funds. Just drop a line to one of the `@pytest-dev/tidelift-admins`_ or use the
|
||||
|
||||
.. _`@asottile`: https://github.com/asottile
|
||||
.. _`@nicoddemus`: https://github.com/nicoddemus
|
||||
.. _`@The-Compiler`: https://github.com/The-Compiler
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
Added :meth:`cache.mkdir() <pytest.Cache.mkdir>`, which is similar to the existing :meth:`cache.makedir() <pytest.Cache.makedir>`,
|
||||
but returns a :class:`pathlib.Path` instead of a legacy ``py.path.local``.
|
||||
|
||||
Added a ``paths`` type to :meth:`parser.addini() <pytest.Parser.addini>`,
|
||||
as in ``parser.addini("mypaths", "my paths", type="paths")``,
|
||||
which is similar to the existing ``pathlist``,
|
||||
but returns a list of :class:`pathlib.Path` instead of legacy ``py.path.local``.
|
||||
|
||||
@@ -6,5 +6,7 @@ Directly constructing the following classes is now deprecated:
|
||||
- ``_pytest.python.Metafunc``
|
||||
- ``_pytest.runner.CallInfo``
|
||||
- ``_pytest._code.ExceptionInfo``
|
||||
- ``_pytest.config.argparsing.Parser``
|
||||
- ``_pytest.config.argparsing.OptionGroup``
|
||||
|
||||
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
||||
|
||||
@@ -2,12 +2,16 @@ The types of objects used in pytest's API are now exported so they may be used i
|
||||
|
||||
The newly-exported types are:
|
||||
|
||||
- ``pytest.Config`` for :class:`Config <pytest.Config>`.
|
||||
- ``pytest.Mark`` for :class:`marks <pytest.Mark>`.
|
||||
- ``pytest.MarkDecorator`` for :class:`mark decorators <pytest.MarkDecorator>`.
|
||||
- ``pytest.MarkGenerator`` for the :class:`pytest.mark <pytest.MarkGenerator>` singleton.
|
||||
- ``pytest.Metafunc`` for the :class:`metafunc <pytest.MarkGenerator>` argument to the :func:`pytest_generate_tests <pytest.hookspec.pytest_generate_tests>` hook.
|
||||
- ``pytest.CallInfo`` for the :class:`CallInfo <pytest.CallInfo>` type passed to various hooks.
|
||||
- ``pytest.PytestPluginManager`` for :class:`PytestPluginManager <pytest.PytestPluginManager>`.
|
||||
- ``pytest.ExceptionInfo`` for the :class:`ExceptionInfo <pytest.ExceptionInfo>` type returned from :func:`pytest.raises` and passed to various hooks.
|
||||
- ``pytest.Parser`` for the :class:`Parser <pytest.Parser>` type passed to the :func:`pytest_addoption <pytest.hookspec.pytest_addoption>` hook.
|
||||
- ``pytest.OptionGroup`` for the :class:`OptionGroup <pytest.OptionGroup>` type returned from the :func:`parser.addgroup <pytest.Parser.getgroup>` method.
|
||||
|
||||
Constructing them directly is not supported; they are only meant for use in type annotations.
|
||||
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
|
||||
|
||||
1
changelog/8246.breaking.rst
Normal file
1
changelog/8246.breaking.rst
Normal file
@@ -0,0 +1 @@
|
||||
``--version`` now writes version information to ``stdout`` rather than ``stderr``.
|
||||
@@ -1,4 +1,4 @@
|
||||
Several behaviors of :meth:`Parser.addoption <_pytest.config.argparsing.Parser.addoption>` are now
|
||||
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
|
||||
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
||||
|
||||
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
||||
|
||||
10
changelog/8335.improvement.rst
Normal file
10
changelog/8335.improvement.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
Improved :func:`pytest.approx` assertion messages for sequences of numbers.
|
||||
|
||||
The assertion messages now dumps a table with the index and the error of each diff.
|
||||
Example::
|
||||
|
||||
> assert [1, 2, 3, 4] == pytest.approx([1, 3, 3, 5])
|
||||
E assert comparison failed for 2 values:
|
||||
E Index | Obtained | Expected
|
||||
E 1 | 2 | 3 +- 3.0e-06
|
||||
E 3 | 4 | 5 +- 5.0e-06
|
||||
1
changelog/8337.doc.rst
Normal file
1
changelog/8337.doc.rst
Normal file
@@ -0,0 +1 @@
|
||||
Recommend `numpy.testing <https://numpy.org/doc/stable/reference/routines.testing.html>`__ module on :func:`pytest.approx` documentation.
|
||||
4
changelog/8447.deprecation.rst
Normal file
4
changelog/8447.deprecation.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
Defining a custom pytest node type which is both an item and a collector now issues a warning.
|
||||
It was never sanely supported and triggers hard to debug errors.
|
||||
|
||||
Instead, a separate collector node should be used, which collects the item. See :ref:`non-python tests` for an example.
|
||||
5
changelog/8509.improvement.rst
Normal file
5
changelog/8509.improvement.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
Fixed issue where `TestCase.setUpClass` is not called when a test has `/` in its name since pytest 6.2.0.
|
||||
|
||||
This refers to the path part in pytest node IDs, e.g. `TestClass::test_it` in the node ID `tests/test_file.py::TestClass::test_it`.
|
||||
|
||||
Now, instead of assuming that the test name does not contain ``/``, it is assumed that test path does not contain ``::``. We plan to hopefully make both of these work in the future.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed assertion rewriting on Python 3.10.
|
||||
1
changelog/8548.bugfix.rst
Normal file
1
changelog/8548.bugfix.rst
Normal file
@@ -0,0 +1 @@
|
||||
Introduce fix to handle precision width in ``log-cli-format`` in turn to fix output coloring for certain formats.
|
||||
5
changelog/8606.feature.rst
Normal file
5
changelog/8606.feature.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
pytest invocations with ``--fixtures-per-test`` and ``--fixtures`` have been enabled with:
|
||||
|
||||
- Fixture location path printed with the fixture name.
|
||||
- First section of the fixture's docstring printed under the fixture name.
|
||||
- Whole of fixture's docstring printed under the fixture name using ``--verbose`` option.
|
||||
4
changelog/8645.improvement.rst
Normal file
4
changelog/8645.improvement.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
Reducing confusion from `pytest.warns(None)` by:
|
||||
|
||||
- Allowing no arguments to be passed in order to catch any exception (no argument defaults to `Warning`).
|
||||
- Emit a deprecation warning if passed `None`.
|
||||
1
changelog/8655.doc.rst
Normal file
1
changelog/8655.doc.rst
Normal file
@@ -0,0 +1 @@
|
||||
Help text for ``--pdbcls`` more accurately reflects the option's behavior.
|
||||
1
changelog/8761.feature.rst
Normal file
1
changelog/8761.feature.rst
Normal file
@@ -0,0 +1 @@
|
||||
New :ref:`version-tuple` attribute, which makes it simpler for users to do something depending on the pytest version (such as declaring hooks which are introduced in later versions).
|
||||
@@ -6,6 +6,7 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-6.2.4
|
||||
release-6.2.3
|
||||
release-6.2.2
|
||||
release-6.2.1
|
||||
|
||||
22
doc/en/announce/release-6.2.4.rst
Normal file
22
doc/en/announce/release-6.2.4.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
pytest-6.2.4
|
||||
=======================================
|
||||
|
||||
pytest 6.2.4 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/stable/changelog.html.
|
||||
|
||||
Thanks to all of the contributors to this release:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Christian Maurer
|
||||
* Florian Bruhin
|
||||
* Ran Benita
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -61,7 +61,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
namespace of doctests.
|
||||
|
||||
pytestconfig [session scope]
|
||||
Session-scoped fixture that returns the :class:`_pytest.config.Config` object.
|
||||
Session-scoped fixture that returns the :class:`pytest.Config` object.
|
||||
|
||||
Example::
|
||||
|
||||
|
||||
@@ -28,6 +28,15 @@ with advance notice in the **Deprecations** section of releases.
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
pytest 6.2.4 (2021-05-04)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#8539 <https://github.com/pytest-dev/pytest/issues/8539>`_: Fixed assertion rewriting on Python 3.10.
|
||||
|
||||
|
||||
pytest 6.2.3 (2021-04-03)
|
||||
=========================
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ master_doc = "contents"
|
||||
|
||||
# General information about the project.
|
||||
project = "pytest"
|
||||
copyright = "2015–2020, holger krekel and pytest-dev team"
|
||||
copyright = "2015–2021, holger krekel and pytest-dev team"
|
||||
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
@@ -293,7 +293,7 @@ man_pages = [("usage", "pytest", "pytest usage", ["holger krekel at merlinux eu"
|
||||
epub_title = "pytest"
|
||||
epub_author = "holger krekel at merlinux eu"
|
||||
epub_publisher = "holger krekel at merlinux eu"
|
||||
epub_copyright = "2013-2020, holger krekel et alii"
|
||||
epub_copyright = "2013-2021, holger krekel et alii"
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or en if the language is not set.
|
||||
|
||||
@@ -16,12 +16,13 @@ Contact channels
|
||||
|
||||
- `pytest-dev at python.org (mailing list)`_ pytest specific announcements and discussions.
|
||||
|
||||
- `pytest-commit at python.org (mailing list)`_: for commits and new issues
|
||||
|
||||
- :doc:`contribution guide <contributing>` for help on submitting pull
|
||||
requests to GitHub.
|
||||
|
||||
- ``#pylib`` on irc.freenode.net IRC channel for random questions.
|
||||
- ``#pytest`` `on irc.libera.chat <ircs://irc.libera.chat:6697/#pytest>`_ IRC
|
||||
channel for random questions (using an IRC client, `via webchat
|
||||
<https://web.libera.chat/#pytest>`_, or `via Matrix
|
||||
<https://matrix.to/#/%23pytest:libera.chat>`_).
|
||||
|
||||
- private mail to Holger.Krekel at gmail com if you want to communicate sensitive issues
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ Further topics
|
||||
license
|
||||
contact
|
||||
|
||||
history
|
||||
historical-notes
|
||||
talks
|
||||
projects
|
||||
|
||||
@@ -42,13 +42,27 @@ As pytest tries to move off `py.path.local <https://py.readthedocs.io/en/latest/
|
||||
|
||||
Pytest will provide compatibility for quite a while.
|
||||
|
||||
Diamond inheritance between :class:`pytest.File` and :class:`pytest.Item`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 6.3
|
||||
|
||||
Inheriting from both Item and file at once has never been supported officially,
|
||||
however some plugins providing linting/code analysis have been using this as a hack.
|
||||
|
||||
This practice is now officially deprecated and a common way to fix this is `example pr fixing inheritance`_.
|
||||
|
||||
|
||||
|
||||
.. _example pr fixing inheritance: https://github.com/asmeurer/pytest-flakes/pull/40/files
|
||||
|
||||
|
||||
Backward compatibilities in ``Parser.addoption``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 2.4
|
||||
|
||||
Several behaviors of :meth:`Parser.addoption <_pytest.config.argparsing.Parser.addoption>` are now
|
||||
Several behaviors of :meth:`Parser.addoption <pytest.Parser.addoption>` are now
|
||||
scheduled for removal in pytest 7 (deprecated since pytest 2.4.0):
|
||||
|
||||
- ``parser.addoption(..., help=".. %default ..")`` - use ``%(default)s`` instead.
|
||||
|
||||
@@ -139,10 +139,66 @@ And now with supplying a command line option:
|
||||
FAILED test_sample.py::test_answer - assert 0
|
||||
1 failed in 0.12s
|
||||
|
||||
You can see that the command line option arrived in our test. This
|
||||
completes the basic pattern. However, one often rather wants to process
|
||||
command line options outside of the test and rather pass in different or
|
||||
more complex objects.
|
||||
You can see that the command line option arrived in our test.
|
||||
|
||||
We could add simple validation for the input by listing the choices:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# content of conftest.py
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--cmdopt",
|
||||
action="store",
|
||||
default="type1",
|
||||
help="my option: type1 or type2",
|
||||
choices=("type1", "type2"),
|
||||
)
|
||||
|
||||
Now we'll get feedback on a bad argument:
|
||||
|
||||
.. code-block:: pytest
|
||||
|
||||
$ pytest -q --cmdopt=type3
|
||||
ERROR: usage: pytest [options] [file_or_dir] [file_or_dir] [...]
|
||||
pytest: error: argument --cmdopt: invalid choice: 'type3' (choose from 'type1', 'type2')
|
||||
|
||||
If you need to provide more detailed error messages, you can use the
|
||||
``type`` parameter and raise ``pytest.UsageError``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# content of conftest.py
|
||||
import pytest
|
||||
|
||||
|
||||
def type_checker(value):
|
||||
msg = "cmdopt must specify a numeric type as typeNNN"
|
||||
if not value.startswith("type"):
|
||||
raise pytest.UsageError(msg)
|
||||
try:
|
||||
int(value[4:])
|
||||
except ValueError:
|
||||
raise pytest.UsageError(msg)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--cmdopt",
|
||||
action="store",
|
||||
default="type1",
|
||||
help="my option: type1 or type2",
|
||||
type=type_checker,
|
||||
)
|
||||
|
||||
This completes the basic pattern. However, one often rather wants to
|
||||
process command line options outside of the test and rather pass in
|
||||
different or more complex objects.
|
||||
|
||||
Dynamically adding command line options
|
||||
--------------------------------------------------------------
|
||||
@@ -1012,7 +1068,7 @@ your frozen program work as the pytest runner by some clever
|
||||
argument handling during program startup. This allows you to
|
||||
have a single executable, which is usually more convenient.
|
||||
Please note that the mechanism for plugin discovery used by pytest
|
||||
(setupttools entry points) doesn't work with frozen executables so pytest
|
||||
(setuptools entry points) doesn't work with frozen executables so pytest
|
||||
can't find any third party plugins automatically. To include third party plugins
|
||||
like ``pytest-timeout`` they must be imported explicitly and passed on to pytest.main.
|
||||
|
||||
|
||||
@@ -153,6 +153,6 @@ to do this is by loading these data in a fixture for use by your tests.
|
||||
This makes use of the automatic caching mechanisms of pytest.
|
||||
|
||||
Another good approach is by adding the data files in the ``tests`` folder.
|
||||
There are also community plugins available to help managing this aspect of
|
||||
There are also community plugins available to help to manage this aspect of
|
||||
testing, e.g. `pytest-datadir <https://pypi.org/project/pytest-datadir/>`__
|
||||
and `pytest-datafiles <https://pypi.org/project/pytest-datafiles/>`__.
|
||||
|
||||
@@ -240,7 +240,7 @@ tox
|
||||
------
|
||||
|
||||
Once you are done with your work and want to make sure that your actual
|
||||
package passes all tests you may want to look into `tox`_, the
|
||||
package passes all tests you may want to look into `tox <https://tox.readthedocs.io/>`_, the
|
||||
virtualenv test automation tool and its `pytest support
|
||||
<https://tox.readthedocs.io/en/latest/example/pytest.html>`_.
|
||||
tox helps you to setup virtualenv environments with pre-defined
|
||||
|
||||
@@ -22,7 +22,7 @@ Install ``pytest``
|
||||
.. code-block:: bash
|
||||
|
||||
$ pytest --version
|
||||
pytest 6.2.3
|
||||
pytest 6.2.4
|
||||
|
||||
.. _`simpletest`:
|
||||
|
||||
@@ -169,40 +169,34 @@ This is outlined below:
|
||||
|
||||
# content of test_class_demo.py
|
||||
class TestClassDemoInstance:
|
||||
value = 0
|
||||
|
||||
def test_one(self):
|
||||
assert 0
|
||||
self.value = 1
|
||||
assert self.value == 1
|
||||
|
||||
def test_two(self):
|
||||
assert 0
|
||||
assert self.value == 1
|
||||
|
||||
|
||||
.. code-block:: pytest
|
||||
|
||||
$ pytest -k TestClassDemoInstance -q
|
||||
FF [100%]
|
||||
.F [100%]
|
||||
================================= FAILURES =================================
|
||||
______________________ TestClassDemoInstance.test_one ______________________
|
||||
|
||||
self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef>
|
||||
|
||||
def test_one(self):
|
||||
> assert 0
|
||||
E assert 0
|
||||
|
||||
test_class_demo.py:3: AssertionError
|
||||
______________________ TestClassDemoInstance.test_two ______________________
|
||||
|
||||
self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef>
|
||||
|
||||
def test_two(self):
|
||||
> assert 0
|
||||
E assert 0
|
||||
> assert self.value == 1
|
||||
E assert 0 == 1
|
||||
E + where 0 = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef>.value
|
||||
|
||||
test_class_demo.py:6: AssertionError
|
||||
test_class_demo.py:9: AssertionError
|
||||
========================= short test summary info ==========================
|
||||
FAILED test_class_demo.py::TestClassDemoInstance::test_one - assert 0
|
||||
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0
|
||||
2 failed in 0.12s
|
||||
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0 == 1
|
||||
1 failed, 1 passed in 0.04s
|
||||
|
||||
Note that attributes added at class level are *class attributes*, so they will be shared between tests.
|
||||
|
||||
|
||||
147
doc/en/history.rst
Normal file
147
doc/en/history.rst
Normal file
@@ -0,0 +1,147 @@
|
||||
History
|
||||
=======
|
||||
|
||||
pytest has a long and interesting history. The `first commit
|
||||
<https://github.com/pytest-dev/pytest/commit/5992a8ef21424d7571305a8d7e2a3431ee7e1e23>`__
|
||||
in this repository is from January 2007, and even that commit alone already
|
||||
tells a lot: The repository originally was from the `py
|
||||
<https://pypi.org/project/py/>`__ library (later split off to pytest), and it
|
||||
originally was a SVN revision, migrated to Mercurial, and finally migrated to
|
||||
git.
|
||||
|
||||
However, the commit says “create the new development trunk” and is
|
||||
already quite big: *435 files changed, 58640 insertions(+)*. This is because
|
||||
pytest originally was born as part of `PyPy <https://www.pypy.org/>`__, to make
|
||||
it easier to write tests for it. Here's how it evolved from there to its own
|
||||
project:
|
||||
|
||||
|
||||
- Late 2002 / early 2003, `PyPy was
|
||||
born <https://morepypy.blogspot.com/2018/09/the-first-15-years-of-pypy.html>`__.
|
||||
- Like that blog post mentioned, from very early on, there was a big
|
||||
focus on testing. There were various ``testsupport`` files on top of
|
||||
unittest.py, and as early as June 2003, Holger Krekel (`@hpk42 <https://github.com/hpk42>`__)
|
||||
`refactored <https://mail.python.org/pipermail/pypy-dev/2003-June/000787.html>`__
|
||||
its test framework to clean things up (``pypy.tool.test``, but still
|
||||
on top of ``unittest.py``, with nothing pytest-like yet).
|
||||
- In December 2003, there was `another
|
||||
iteration <https://foss.heptapod.net/pypy/pypy/-/commit/02752373e1b29d89c6bb0a97e5f940caa22bdd63>`__
|
||||
at improving their testing situation, by Stefan Schwarzer, called
|
||||
``pypy.tool.newtest``.
|
||||
- However, it didn’t seem to be around for long, as around June/July
|
||||
2004, efforts started on a thing called ``utest``, offering plain
|
||||
assertions. This seems like the start of something pytest-like, but
|
||||
unfortunately, it's unclear where the test runner's code was at the time.
|
||||
The closest thing still around is `this
|
||||
file <https://foss.heptapod.net/pypy/pypy/-/commit/0735f9ed287ec20950a7dd0a16fc10810d4f6847>`__,
|
||||
but that doesn’t seem like a complete test runner at all. What can be seen
|
||||
is that there were `various
|
||||
efforts <https://foss.heptapod.net/pypy/pypy/-/commits/branch/default?utf8=%E2%9C%93&search=utest>`__
|
||||
by Laura Creighton and Samuele Pedroni (`@pedronis <https://github.com/pedronis>`__) at automatically
|
||||
converting existing tests to the new ``utest`` framework.
|
||||
- Around the same time, for Europython 2004, @hpk42 `started a
|
||||
project <http://web.archive.org/web/20041020215353/http://codespeak.net/svn/user/hpk/talks/std-talk.txt>`__
|
||||
originally called “std”, intended to be a “complementary standard
|
||||
library” - already laying out the principles behind what later became
|
||||
pytest:
|
||||
|
||||
- current “batteries included” are very useful, but
|
||||
|
||||
- some of them are written in a pretty much java-like style,
|
||||
especially the unittest-framework
|
||||
- […]
|
||||
- the best API is one that doesn’t exist
|
||||
|
||||
[…]
|
||||
|
||||
- a testing package should require as few boilerplate code as
|
||||
possible and offer much flexibility
|
||||
- it should provide premium quality tracebacks and debugging aid
|
||||
|
||||
[…]
|
||||
|
||||
- first of all … forget about limited “assertXYZ APIs” and use the
|
||||
real thing, e.g.::
|
||||
|
||||
assert x == y
|
||||
|
||||
- this works with plain python but you get unhelpful “assertion
|
||||
failed” errors with no information
|
||||
|
||||
- std.utest (magic!) actually reinterprets the assertion expression
|
||||
and offers detailed information about underlying values
|
||||
|
||||
- In September 2004, the ``py-dev`` mailinglist gets born, which `is
|
||||
now <https://mail.python.org/pipermail/pytest-dev/>`__ ``pytest-dev``,
|
||||
but thankfully with all the original archives still intact.
|
||||
|
||||
- Around September/October 2004, the ``std`` project `was renamed
|
||||
<https://mail.python.org/pipermail/pypy-dev/2004-September/001565.html>`__ to
|
||||
``py`` and ``std.utest`` became ``py.test``. This is also the first time the
|
||||
`entire source
|
||||
code <https://foss.heptapod.net/pypy/pypy/-/commit/42cf50c412026028e20acd23d518bd92e623ac11>`__,
|
||||
seems to be available, with much of the API still being around today:
|
||||
|
||||
- ``py.path.local``, which is being phased out of pytest (in favour of
|
||||
pathlib) some 16-17 years later
|
||||
- The idea of the collection tree, including ``Collector``,
|
||||
``FSCollector``, ``Directory``, ``PyCollector``, ``Module``,
|
||||
``Class``
|
||||
- Arguments like ``-x`` / ``--exitfirst``, ``-l`` /
|
||||
``--showlocals``, ``--fulltrace``, ``--pdb``, ``-S`` /
|
||||
``--nocapture`` (``-s`` / ``--capture=off`` today),
|
||||
``--collectonly`` (``--collect-only`` today)
|
||||
|
||||
- In the same month, the ``py`` library `gets split off
|
||||
<https://foss.heptapod.net/pypy/pypy/-/commit/6bdafe9203ad92eb259270b267189141c53bce33>`__
|
||||
from ``PyPy``
|
||||
|
||||
- It seemed to get rather quiet for a while, and little seemed to happen
|
||||
between October 2004 (removing ``py`` from PyPy) and January
|
||||
2007 (first commit in the now-pytest repository). However, there were
|
||||
various discussions about features/ideas on the mailinglist, and `a
|
||||
couple of
|
||||
releases <https://pypi.org/project/py/0.8.0-alpha2/#history>`__ every
|
||||
couple of months:
|
||||
|
||||
- March 2006: py 0.8.0-alpha2
|
||||
- May 2007: py 0.9.0
|
||||
- March 2008: py 0.9.1 (first release to be found `in the pytest
|
||||
changelog <https://github.com/pytest-dev/pytest/blob/main/doc/en/changelog.rst#091>`__!)
|
||||
- August 2008: py 0.9.2
|
||||
|
||||
- In August 2009, py 1.0.0 was released, `introducing a lot of
|
||||
fundamental
|
||||
features <https://holgerkrekel.net/2009/08/04/pylib-1-0-0-released-the-testing-with-python-innovations-continue/>`__:
|
||||
|
||||
- funcargs/fixtures
|
||||
- A `plugin
|
||||
architecture <http://web.archive.org/web/20090629032718/https://codespeak.net/py/dist/test/extend.html>`__
|
||||
which still looks very much the same today!
|
||||
- Various `default
|
||||
plugins <http://web.archive.org/web/20091005181132/https://codespeak.net/py/dist/test/plugin/index.html>`__,
|
||||
including
|
||||
`monkeypatch <http://web.archive.org/web/20091012022829/http://codespeak.net/py/dist/test/plugin/monkeypatch.html>`__
|
||||
|
||||
- Even back there, the
|
||||
`FAQ <http://web.archive.org/web/20091005222413/http://codespeak.net/py/dist/faq.html>`__
|
||||
said:
|
||||
|
||||
Clearly, [a second standard library] was ambitious and the naming has
|
||||
maybe haunted the project rather than helping it. There may be a
|
||||
project name change and possibly a split up into different projects
|
||||
sometime.
|
||||
|
||||
and that finally happened in November 2010, when pytest 2.0.0 `was
|
||||
released <https://mail.python.org/pipermail/pytest-dev/2010-November/001687.html>`__
|
||||
as a package separate from ``py`` (but still called ``py.test``).
|
||||
|
||||
- In August 2016, pytest 3.0.0 `was
|
||||
released <https://docs.pytest.org/en/latest/changelog.html#id1313>`__,
|
||||
which adds ``pytest`` (rather than ``py.test``) as the recommended
|
||||
command-line entry point
|
||||
|
||||
Due to this history, it's diffcult to answer the question when pytest was started.
|
||||
It depends what point should really be seen as the start of it all. One
|
||||
possible interpretation is to pick Europython 2004, i.e. around June/July
|
||||
2004.
|
||||
@@ -173,8 +173,6 @@ DeprecationWarning and PendingDeprecationWarning
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
By default pytest will display ``DeprecationWarning`` and ``PendingDeprecationWarning`` warnings from
|
||||
user code and third-party libraries, as recommended by `PEP-0565 <https://www.python.org/dev/peps/pep-0565>`_.
|
||||
This helps users keep their code modern and avoid breakages when deprecated warnings are effectively removed.
|
||||
@@ -230,27 +228,8 @@ that a certain function call triggers a ``DeprecationWarning`` or
|
||||
This test will fail if ``myfunction`` does not issue a deprecation warning
|
||||
when called with a ``17`` argument.
|
||||
|
||||
By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be
|
||||
caught when using :func:`pytest.warns` or :ref:`recwarn <recwarn>` because
|
||||
the default Python warnings filters hide
|
||||
them. If you wish to record them in your own code, use
|
||||
``warnings.simplefilter('always')``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import warnings
|
||||
import pytest
|
||||
|
||||
|
||||
def test_deprecation(recwarn):
|
||||
warnings.simplefilter("always")
|
||||
myfunction(17)
|
||||
assert len(recwarn) == 1
|
||||
assert recwarn.pop(DeprecationWarning)
|
||||
|
||||
|
||||
The :ref:`recwarn <recwarn>` fixture automatically ensures to reset the warnings
|
||||
filter at the end of the test, so no global state is leaked.
|
||||
|
||||
.. _`asserting warnings`:
|
||||
|
||||
@@ -265,7 +244,7 @@ Asserting warnings with the warns function
|
||||
|
||||
|
||||
|
||||
You can check that code raises a particular warning using func:`pytest.warns`,
|
||||
You can check that code raises a particular warning using :func:`pytest.warns`,
|
||||
which works in a similar manner to :ref:`raises <assertraises>`:
|
||||
|
||||
.. code-block:: python
|
||||
@@ -293,7 +272,7 @@ argument ``match`` to assert that the exception matches a text or regex::
|
||||
...
|
||||
Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...
|
||||
|
||||
You can also call func:`pytest.warns` on a function or code string:
|
||||
You can also call :func:`pytest.warns` on a function or code string:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -317,9 +296,9 @@ additional information:
|
||||
Alternatively, you can examine raised warnings in detail using the
|
||||
:ref:`recwarn <recwarn>` fixture (see below).
|
||||
|
||||
.. note::
|
||||
``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated
|
||||
differently; see :ref:`ensuring_function_triggers`.
|
||||
|
||||
The :ref:`recwarn <recwarn>` fixture automatically ensures to reset the warnings
|
||||
filter at the end of the test, so no global state is leaked.
|
||||
|
||||
.. _`recording warnings`:
|
||||
|
||||
@@ -328,15 +307,15 @@ Alternatively, you can examine raised warnings in detail using the
|
||||
Recording warnings
|
||||
------------------
|
||||
|
||||
You can record raised warnings either using func:`pytest.warns` or with
|
||||
You can record raised warnings either using :func:`pytest.warns` or with
|
||||
the ``recwarn`` fixture.
|
||||
|
||||
To record with func:`pytest.warns` without asserting anything about the warnings,
|
||||
pass ``None`` as the expected warning type:
|
||||
To record with :func:`pytest.warns` without asserting anything about the warnings,
|
||||
pass no arguments as the expected warning type and it will default to a generic Warning:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with pytest.warns(None) as record:
|
||||
with pytest.warns() as record:
|
||||
warnings.warn("user", UserWarning)
|
||||
warnings.warn("runtime", RuntimeWarning)
|
||||
|
||||
@@ -360,7 +339,7 @@ The ``recwarn`` fixture will record warnings for the whole function:
|
||||
assert w.filename
|
||||
assert w.lineno
|
||||
|
||||
Both ``recwarn`` and func:`pytest.warns` return the same interface for recorded
|
||||
Both ``recwarn`` and :func:`pytest.warns` return the same interface for recorded
|
||||
warnings: a WarningsRecorder instance. To view the recorded warnings, you can
|
||||
iterate over this instance, call ``len`` on it to get the number of recorded
|
||||
warnings, or index into it to get a particular recorded warning.
|
||||
|
||||
@@ -369,9 +369,12 @@ Here is a simple test file with the several usages:
|
||||
|
||||
Running it with the report-on-xfail option gives this output:
|
||||
|
||||
.. FIXME: Use $ instead of ! again to reenable regendoc once it's fixed:
|
||||
https://github.com/pytest-dev/pytest/issues/8807
|
||||
|
||||
.. code-block:: pytest
|
||||
|
||||
example $ pytest -rx xfail_demo.py
|
||||
! pytest -rx xfail_demo.py
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
|
||||
cachedir: $PYTHON_PREFIX/.pytest_cache
|
||||
|
||||
@@ -168,15 +168,15 @@ You can invoke ``pytest`` from Python code directly:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytest.main()
|
||||
retcode = pytest.main()
|
||||
|
||||
this acts as if you would call "pytest" from the command line.
|
||||
It will not raise ``SystemExit`` but return the exitcode instead.
|
||||
It will not raise :class:`SystemExit` but return the :ref:`exit code <exit-codes>` instead.
|
||||
You can pass in options and arguments:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytest.main(["-x", "mytestdir"])
|
||||
retcode = pytest.main(["-x", "mytestdir"])
|
||||
|
||||
You can specify additional plugins to ``pytest.main``:
|
||||
|
||||
@@ -191,7 +191,8 @@ You can specify additional plugins to ``pytest.main``:
|
||||
print("*** test run reporting finishing")
|
||||
|
||||
|
||||
pytest.main(["-qq"], plugins=[MyPlugin()])
|
||||
if __name__ == "__main__":
|
||||
sys.exit(pytest.main(["-qq"], plugins=[MyPlugin()]))
|
||||
|
||||
Running it will show that ``MyPlugin`` was added and its
|
||||
hook was invoked:
|
||||
|
||||
@@ -337,7 +337,7 @@ testing directory:
|
||||
Alternatively you can invoke pytest with the ``-p pytester`` command line
|
||||
option.
|
||||
|
||||
This will allow you to use the :py:class:`pytester <_pytest.pytester.Pytester>`
|
||||
This will allow you to use the :py:class:`pytester <pytest.Pytester>`
|
||||
fixture for testing your plugin code.
|
||||
|
||||
Let's demonstrate what you can do with the plugin with an example. Imagine we
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
.. sidebar:: Next Open Trainings
|
||||
|
||||
- `Professionelles Testen für Python mit pytest <https://www.enterpy.de/lecture_compact1.php?id=12713>`_ (German), part of the enterPy conference, April 22nd (sold out) and May 20th, remote.
|
||||
- `Introduction to pytest <https://ep2021.europython.eu/talks/7S5Cnc6-introduction-to-pytest/>`_, part of `Europython 2021 <https://ep2021.europython.eu/>`_, July 27th, remote.
|
||||
- `pytest: Professionelles Testen (nicht nur) für Python <https://workshoptage.ch/workshops/2021/pytest-test-driven-development-nicht-nur-fuer-python-2/>`_ (German), part of `CH-Open Workshoptage <https://workshoptage.ch/>`_, September 9th, ETH Zurich, Switzerland.
|
||||
- `Professional Testing with Python <https://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, via `Python Academy <https://www.python-academy.com/>`_, Q4/2021 (TBD, 3 days), Leipzig (Germany) and remote.
|
||||
|
||||
Also see `previous talks and blogposts <talks.html>`_.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Distributed under the terms of the `MIT`_ license, pytest is free and open sourc
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2004-2020 Holger Krekel and others
|
||||
Copyright (c) 2004-2021 Holger Krekel and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
@@ -179,12 +179,12 @@ Files will only be matched for configuration if:
|
||||
The files are considered in the order above. Options from multiple ``configfiles`` candidates
|
||||
are never merged - the first match wins.
|
||||
|
||||
The internal :class:`Config <_pytest.config.Config>` object (accessible via hooks or through the :fixture:`pytestconfig` fixture)
|
||||
The :class:`Config <pytest.Config>` object (accessible via hooks or through the :fixture:`pytestconfig` fixture)
|
||||
will subsequently carry these attributes:
|
||||
|
||||
- :attr:`config.rootpath <_pytest.config.Config.rootpath>`: the determined root directory, guaranteed to exist.
|
||||
- :attr:`config.rootpath <pytest.Config.rootpath>`: the determined root directory, guaranteed to exist.
|
||||
|
||||
- :attr:`config.inipath <_pytest.config.Config.inipath>`: the determined ``configfile``, may be ``None``
|
||||
- :attr:`config.inipath <pytest.Config.inipath>`: the determined ``configfile``, may be ``None``
|
||||
(it is named ``inipath`` for historical reasons).
|
||||
|
||||
.. versionadded:: 6.1
|
||||
|
||||
@@ -410,7 +410,7 @@ example, consider this file:
|
||||
|
||||
.. literalinclude:: /example/fixtures/test_fixtures_order_autouse_multiple_scopes.py
|
||||
|
||||
Even though nothing in ``TestClassWithC1Request`` is requesting ``c1``, it still
|
||||
Even though nothing in ``TestClassWithoutC1Request`` is requesting ``c1``, it still
|
||||
is executed for the tests inside it anyway:
|
||||
|
||||
.. image:: /example/fixtures/test_fixtures_order_autouse_multiple_scopes.svg
|
||||
|
||||
@@ -6,23 +6,24 @@ Plugin List
|
||||
|
||||
PyPI projects that match "pytest-\*" are considered plugins and are listed
|
||||
automatically. Packages classified as inactive are excluded.
|
||||
This list contains 856 plugins.
|
||||
This list contains 887 plugins.
|
||||
|
||||
============================================================================================================== ======================================================================================================================================================================== ============== ===================== ================================================
|
||||
name summary last release status requires
|
||||
============================================================================================================== ======================================================================================================================================================================== ============== ===================== ================================================
|
||||
`pytest-accept <https://pypi.org/project/pytest-accept/>`_ A pytest-plugin for updating doctest outputs Jun 02, 2021 N/A pytest (>=6,<7)
|
||||
`pytest-adaptavist <https://pypi.org/project/pytest-adaptavist/>`_ pytest plugin for generating test execution results within Jira Test Management (tm4j) Apr 22, 2021 N/A pytest (>=3.4.1)
|
||||
`pytest-adf <https://pypi.org/project/pytest-adf/>`_ Pytest plugin for writing Azure Data Factory integration tests Mar 10, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-adf <https://pypi.org/project/pytest-adf/>`_ Pytest plugin for writing Azure Data Factory integration tests May 10, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-adf-azure-identity <https://pypi.org/project/pytest-adf-azure-identity/>`_ Pytest plugin for writing Azure Data Factory integration tests Mar 06, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-aggreport <https://pypi.org/project/pytest-aggreport/>`_ pytest plugin for pytest-repeat that generate aggregate report of the same test cases with additional statistics details. Mar 07, 2021 4 - Beta pytest (>=6.2.2)
|
||||
`pytest-aio <https://pypi.org/project/pytest-aio/>`_ Pytest plugin for testing async python code Apr 05, 2021 4 - Beta pytest ; extra == 'tests'
|
||||
`pytest-aio <https://pypi.org/project/pytest-aio/>`_ Pytest plugin for testing async python code May 21, 2021 4 - Beta pytest ; extra == 'tests'
|
||||
`pytest-aiofiles <https://pypi.org/project/pytest-aiofiles/>`_ pytest fixtures for writing aiofiles tests with pyfakefs May 14, 2017 5 - Production/Stable N/A
|
||||
`pytest-aiohttp <https://pypi.org/project/pytest-aiohttp/>`_ pytest plugin for aiohttp support Dec 05, 2017 N/A pytest
|
||||
`pytest-aiohttp-client <https://pypi.org/project/pytest-aiohttp-client/>`_ Pytest `client` fixture for the Aiohttp Nov 01, 2020 N/A pytest (>=6)
|
||||
`pytest-aioresponses <https://pypi.org/project/pytest-aioresponses/>`_ py.test integration for aioresponses Dec 21, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-aioworkers <https://pypi.org/project/pytest-aioworkers/>`_ A plugin to test aioworkers project with pytest Dec 04, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-airflow <https://pypi.org/project/pytest-airflow/>`_ pytest support for airflow. Apr 03, 2019 3 - Alpha pytest (>=4.4.0)
|
||||
`pytest-alembic <https://pypi.org/project/pytest-alembic/>`_ A pytest plugin for verifying alembic migrations. Jul 13, 2020 N/A pytest (>=1.0)
|
||||
`pytest-alembic <https://pypi.org/project/pytest-alembic/>`_ A pytest plugin for verifying alembic migrations. May 10, 2021 N/A pytest (>=1.0)
|
||||
`pytest-allclose <https://pypi.org/project/pytest-allclose/>`_ Pytest fixture extending Numpy's allclose function Jul 30, 2019 5 - Production/Stable pytest
|
||||
`pytest-allure-adaptor <https://pypi.org/project/pytest-allure-adaptor/>`_ Plugin for py.test to generate allure xml reports Jan 10, 2018 N/A pytest (>=2.7.3)
|
||||
`pytest-allure-adaptor2 <https://pypi.org/project/pytest-allure-adaptor2/>`_ Plugin for py.test to generate allure xml reports Oct 14, 2020 N/A pytest (>=2.7.3)
|
||||
@@ -30,31 +31,33 @@ name
|
||||
`pytest-alphamoon <https://pypi.org/project/pytest-alphamoon/>`_ Static code checks used at Alphamoon Nov 20, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-android <https://pypi.org/project/pytest-android/>`_ This fixture provides a configured "driver" for Android Automated Testing, using uiautomator2. Feb 21, 2019 3 - Alpha pytest
|
||||
`pytest-annotate <https://pypi.org/project/pytest-annotate/>`_ pytest-annotate: Generate PyAnnotate annotations from your pytest tests. Aug 23, 2019 3 - Alpha pytest (<6.0.0,>=3.2.0)
|
||||
`pytest-ansible <https://pypi.org/project/pytest-ansible/>`_ Plugin for py.test to simplify calling ansible modules from tests or fixtures Oct 26, 2020 5 - Production/Stable pytest
|
||||
`pytest-ansible <https://pypi.org/project/pytest-ansible/>`_ Plugin for py.test to simplify calling ansible modules from tests or fixtures May 25, 2021 5 - Production/Stable N/A
|
||||
`pytest-ansible-playbook <https://pypi.org/project/pytest-ansible-playbook/>`_ Pytest fixture which runs given ansible playbook file. Mar 08, 2019 4 - Beta N/A
|
||||
`pytest-ansible-playbook-runner <https://pypi.org/project/pytest-ansible-playbook-runner/>`_ Pytest fixture which runs given ansible playbook file. Dec 02, 2020 4 - Beta pytest (>=3.1.0)
|
||||
`pytest-antilru <https://pypi.org/project/pytest-antilru/>`_ Bust functools.lru_cache when running pytest to avoid test pollution Apr 11, 2019 5 - Production/Stable pytest
|
||||
`pytest-anything <https://pypi.org/project/pytest-anything/>`_ Pytest fixtures to assert anything and something Feb 18, 2021 N/A N/A
|
||||
`pytest-aoc <https://pypi.org/project/pytest-aoc/>`_ Downloads puzzle inputs for Advent of Code and synthesizes PyTest fixtures Dec 01, 2020 N/A pytest ; extra == 'dev'
|
||||
`pytest-api <https://pypi.org/project/pytest-api/>`_ PyTest-API Python Web Framework built for testing purposes. Mar 20, 2021 N/A N/A
|
||||
`pytest-api <https://pypi.org/project/pytest-api/>`_ PyTest-API Python Web Framework built for testing purposes. May 04, 2021 N/A N/A
|
||||
`pytest-apistellar <https://pypi.org/project/pytest-apistellar/>`_ apistellar plugin for pytest. Jun 18, 2019 N/A N/A
|
||||
`pytest-appengine <https://pypi.org/project/pytest-appengine/>`_ AppEngine integration that works well with pytest-django Feb 27, 2017 N/A N/A
|
||||
`pytest-appium <https://pypi.org/project/pytest-appium/>`_ Pytest plugin for appium Dec 05, 2019 N/A N/A
|
||||
`pytest-approvaltests <https://pypi.org/project/pytest-approvaltests/>`_ A plugin to use approvaltests with pytest Feb 07, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-argus <https://pypi.org/project/pytest-argus/>`_ pyest results colection plugin Jun 24, 2021 5 - Production/Stable pytest (>=6.2.4)
|
||||
`pytest-arraydiff <https://pypi.org/project/pytest-arraydiff/>`_ pytest plugin to help with comparing array output from tests Dec 06, 2018 4 - Beta pytest
|
||||
`pytest-asgi-server <https://pypi.org/project/pytest-asgi-server/>`_ Convenient ASGI client/server fixtures for Pytest Dec 12, 2020 N/A pytest (>=5.4.1)
|
||||
`pytest-asptest <https://pypi.org/project/pytest-asptest/>`_ test Answer Set Programming programs Apr 28, 2018 4 - Beta N/A
|
||||
`pytest-assertutil <https://pypi.org/project/pytest-assertutil/>`_ pytest-assertutil May 10, 2019 N/A N/A
|
||||
`pytest-assert-utils <https://pypi.org/project/pytest-assert-utils/>`_ Useful assertion utilities for use with pytest Mar 28, 2021 3 - Alpha N/A
|
||||
`pytest-assume <https://pypi.org/project/pytest-assume/>`_ A pytest plugin that allows multiple failures per test Dec 08, 2020 N/A pytest (>=2.7)
|
||||
`pytest-assume <https://pypi.org/project/pytest-assume/>`_ A pytest plugin that allows multiple failures per test Jun 24, 2021 N/A pytest (>=2.7)
|
||||
`pytest-ast-back-to-python <https://pypi.org/project/pytest-ast-back-to-python/>`_ A plugin for pytest devs to view how assertion rewriting recodes the AST Sep 29, 2019 4 - Beta N/A
|
||||
`pytest-astropy <https://pypi.org/project/pytest-astropy/>`_ Meta-package containing dependencies for testing Jan 16, 2020 5 - Production/Stable pytest (>=4.6)
|
||||
`pytest-astropy-header <https://pypi.org/project/pytest-astropy-header/>`_ pytest plugin to add diagnostic information to the header of the test output Dec 18, 2019 3 - Alpha pytest (>=2.8)
|
||||
`pytest-ast-transformer <https://pypi.org/project/pytest-ast-transformer/>`_ May 04, 2019 3 - Alpha pytest
|
||||
`pytest-asyncio <https://pypi.org/project/pytest-asyncio/>`_ Pytest support for asyncio. Apr 21, 2021 4 - Beta pytest (>=5.4.0)
|
||||
`pytest-asyncio-cooperative <https://pypi.org/project/pytest-asyncio-cooperative/>`_ Run all your asynchronous tests cooperatively. Apr 17, 2021 4 - Beta N/A
|
||||
`pytest-asyncio-cooperative <https://pypi.org/project/pytest-asyncio-cooperative/>`_ Run all your asynchronous tests cooperatively. Jun 25, 2021 4 - Beta N/A
|
||||
`pytest-asyncio-network-simulator <https://pypi.org/project/pytest-asyncio-network-simulator/>`_ pytest-asyncio-network-simulator: Plugin for pytest for simulator the network in tests Jul 31, 2018 3 - Alpha pytest (<3.7.0,>=3.3.2)
|
||||
`pytest-async-mongodb <https://pypi.org/project/pytest-async-mongodb/>`_ pytest plugin for async MongoDB Oct 18, 2017 5 - Production/Stable pytest (>=2.5.2)
|
||||
`pytest-async-sqlalchemy <https://pypi.org/project/pytest-async-sqlalchemy/>`_ Database testing fixtures using the SQLAlchemy asyncio API Jun 11, 2021 4 - Beta pytest (>=6.0.0)
|
||||
`pytest-atomic <https://pypi.org/project/pytest-atomic/>`_ Skip rest of tests if previous test failed. Nov 24, 2018 4 - Beta N/A
|
||||
`pytest-attrib <https://pypi.org/project/pytest-attrib/>`_ pytest plugin to select tests based on attributes similar to the nose-attrib plugin May 24, 2016 4 - Beta N/A
|
||||
`pytest-austin <https://pypi.org/project/pytest-austin/>`_ Austin plugin for pytest Oct 11, 2020 4 - Beta N/A
|
||||
@@ -63,6 +66,7 @@ name
|
||||
`pytest-auto-parametrize <https://pypi.org/project/pytest-auto-parametrize/>`_ pytest plugin: avoid repeating arguments in parametrize Oct 02, 2016 3 - Alpha N/A
|
||||
`pytest-avoidance <https://pypi.org/project/pytest-avoidance/>`_ Makes pytest skip tests that don not need rerunning May 23, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-aws <https://pypi.org/project/pytest-aws/>`_ pytest plugin for testing AWS resource configurations Oct 04, 2017 4 - Beta N/A
|
||||
`pytest-aws-config <https://pypi.org/project/pytest-aws-config/>`_ Protect your AWS credentials in unit tests May 28, 2021 N/A N/A
|
||||
`pytest-axe <https://pypi.org/project/pytest-axe/>`_ pytest plugin for axe-selenium-python Nov 12, 2018 N/A pytest (>=3.0.0)
|
||||
`pytest-azurepipelines <https://pypi.org/project/pytest-azurepipelines/>`_ Formatting PyTest output for Azure Pipelines UI Jul 23, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-bandit <https://pypi.org/project/pytest-bandit/>`_ A bandit plugin for pytest Feb 23, 2021 4 - Beta pytest (>=3.5.0)
|
||||
@@ -75,11 +79,12 @@ name
|
||||
`pytest-beds <https://pypi.org/project/pytest-beds/>`_ Fixtures for testing Google Appengine (GAE) apps Jun 07, 2016 4 - Beta N/A
|
||||
`pytest-bench <https://pypi.org/project/pytest-bench/>`_ Benchmark utility that plugs into pytest. Jul 21, 2014 3 - Alpha N/A
|
||||
`pytest-benchmark <https://pypi.org/project/pytest-benchmark/>`_ A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer. Apr 17, 2021 5 - Production/Stable pytest (>=3.8)
|
||||
`pytest-bigchaindb <https://pypi.org/project/pytest-bigchaindb/>`_ A BigchainDB plugin for pytest. Apr 17, 2021 4 - Beta N/A
|
||||
`pytest-bg-process <https://pypi.org/project/pytest-bg-process/>`_ A simple plugin to use with pytest May 28, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-bigchaindb <https://pypi.org/project/pytest-bigchaindb/>`_ A BigchainDB plugin for pytest. May 28, 2021 4 - Beta N/A
|
||||
`pytest-black <https://pypi.org/project/pytest-black/>`_ A pytest plugin to enable format checking with black Oct 05, 2020 4 - Beta N/A
|
||||
`pytest-black-multipy <https://pypi.org/project/pytest-black-multipy/>`_ Allow '--black' on older Pythons Jan 14, 2021 5 - Production/Stable pytest (!=3.7.3,>=3.5) ; extra == 'testing'
|
||||
`pytest-blame <https://pypi.org/project/pytest-blame/>`_ A pytest plugin helps developers to debug by providing useful commits history. May 04, 2019 N/A pytest (>=4.4.0)
|
||||
`pytest-blender <https://pypi.org/project/pytest-blender/>`_ Blender Pytest plugin. Feb 15, 2021 N/A pytest (==6.2.1) ; extra == 'dev'
|
||||
`pytest-blender <https://pypi.org/project/pytest-blender/>`_ Blender Pytest plugin. Jun 02, 2021 N/A pytest (==6.2.1) ; extra == 'dev'
|
||||
`pytest-blink1 <https://pypi.org/project/pytest-blink1/>`_ Pytest plugin to emit notifications via the Blink(1) RGB LED Jan 07, 2018 4 - Beta N/A
|
||||
`pytest-blockage <https://pypi.org/project/pytest-blockage/>`_ Disable network requests during a test run. Feb 13, 2019 N/A pytest
|
||||
`pytest-blocker <https://pypi.org/project/pytest-blocker/>`_ pytest plugin to mark a test as blocker and skip all other tests Sep 07, 2015 4 - Beta N/A
|
||||
@@ -103,53 +108,55 @@ name
|
||||
`pytest-canonical-data <https://pypi.org/project/pytest-canonical-data/>`_ A plugin which allows to compare results with canonical results, based on previous runs May 08, 2020 2 - Pre-Alpha pytest (>=3.5.0)
|
||||
`pytest-caprng <https://pypi.org/project/pytest-caprng/>`_ A plugin that replays pRNG state on failure. May 02, 2018 4 - Beta N/A
|
||||
`pytest-capture-deprecatedwarnings <https://pypi.org/project/pytest-capture-deprecatedwarnings/>`_ pytest plugin to capture all deprecatedwarnings and put them in one file Apr 30, 2019 N/A N/A
|
||||
`pytest-cases <https://pypi.org/project/pytest-cases/>`_ Separate test code from test cases in pytest. Apr 12, 2021 5 - Production/Stable N/A
|
||||
`pytest-cases <https://pypi.org/project/pytest-cases/>`_ Separate test code from test cases in pytest. Jun 03, 2021 5 - Production/Stable N/A
|
||||
`pytest-cassandra <https://pypi.org/project/pytest-cassandra/>`_ Cassandra CCM Test Fixtures for pytest Nov 04, 2017 1 - Planning N/A
|
||||
`pytest-catchlog <https://pypi.org/project/pytest-catchlog/>`_ py.test plugin to catch log messages. This is a fork of pytest-capturelog. Jan 24, 2016 4 - Beta pytest (>=2.6)
|
||||
`pytest-catch-server <https://pypi.org/project/pytest-catch-server/>`_ Pytest plugin with server for catching HTTP requests. Dec 12, 2019 5 - Production/Stable N/A
|
||||
`pytest-celery <https://pypi.org/project/pytest-celery/>`_ pytest-celery a shim pytest plugin to enable celery.contrib.pytest Aug 05, 2020 N/A N/A
|
||||
`pytest-celery <https://pypi.org/project/pytest-celery/>`_ pytest-celery a shim pytest plugin to enable celery.contrib.pytest May 06, 2021 N/A N/A
|
||||
`pytest-chalice <https://pypi.org/project/pytest-chalice/>`_ A set of py.test fixtures for AWS Chalice Jul 01, 2020 4 - Beta N/A
|
||||
`pytest-change-report <https://pypi.org/project/pytest-change-report/>`_ turn . into √,turn F into x Sep 14, 2020 N/A pytest
|
||||
`pytest-chdir <https://pypi.org/project/pytest-chdir/>`_ A pytest fixture for changing current working directory Jan 28, 2020 N/A pytest (>=5.0.0,<6.0.0)
|
||||
`pytest-check <https://pypi.org/project/pytest-check/>`_ A pytest plugin that allows multiple failures per test. Dec 27, 2020 5 - Production/Stable N/A
|
||||
`pytest-checkdocs <https://pypi.org/project/pytest-checkdocs/>`_ check the README when running tests Apr 18, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing'
|
||||
`pytest-checkdocs <https://pypi.org/project/pytest-checkdocs/>`_ check the README when running tests Apr 30, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing'
|
||||
`pytest-checkipdb <https://pypi.org/project/pytest-checkipdb/>`_ plugin to check if there are ipdb debugs left Jul 22, 2020 5 - Production/Stable pytest (>=2.9.2)
|
||||
`pytest-check-links <https://pypi.org/project/pytest-check-links/>`_ Check links in files Jul 29, 2020 N/A pytest (>=4.6)
|
||||
`pytest-check-mk <https://pypi.org/project/pytest-check-mk/>`_ pytest plugin to test Check_MK checks Nov 19, 2015 4 - Beta pytest
|
||||
`pytest-circleci <https://pypi.org/project/pytest-circleci/>`_ py.test plugin for CircleCI May 03, 2019 N/A N/A
|
||||
`pytest-circleci-parallelized <https://pypi.org/project/pytest-circleci-parallelized/>`_ Parallelize pytest across CircleCI workers. Mar 26, 2019 N/A N/A
|
||||
`pytest-ckan <https://pypi.org/project/pytest-ckan/>`_ Backport of CKAN 2.9 pytest plugin and fixtures to CAKN 2.8 Apr 28, 2020 4 - Beta pytest
|
||||
`pytest-clarity <https://pypi.org/project/pytest-clarity/>`_ A plugin providing an alternative, colourful diff output for failing assertions. Jan 23, 2020 3 - Alpha N/A
|
||||
`pytest-clarity <https://pypi.org/project/pytest-clarity/>`_ A plugin providing an alternative, colourful diff output for failing assertions. Jun 11, 2021 N/A N/A
|
||||
`pytest-cldf <https://pypi.org/project/pytest-cldf/>`_ Easy quality control for CLDF datasets using pytest May 06, 2019 N/A N/A
|
||||
`pytest-click <https://pypi.org/project/pytest-click/>`_ Py.test plugin for Click Aug 29, 2020 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-clld <https://pypi.org/project/pytest-clld/>`_ May 06, 2020 N/A pytest (>=3.6)
|
||||
`pytest-cloud <https://pypi.org/project/pytest-cloud/>`_ Distributed tests planner plugin for pytest testing framework. Oct 05, 2020 6 - Mature N/A
|
||||
`pytest-cloudflare-worker <https://pypi.org/project/pytest-cloudflare-worker/>`_ pytest plugin for testing cloudflare workers Mar 30, 2021 4 - Beta pytest (>=6.0.0)
|
||||
`pytest-cobra <https://pypi.org/project/pytest-cobra/>`_ PyTest plugin for testing Smart Contracts for Ethereum blockchain. Jun 29, 2019 3 - Alpha pytest (<4.0.0,>=3.7.1)
|
||||
`pytest-codeblocks <https://pypi.org/project/pytest-codeblocks/>`_ Test code blocks in your READMEs May 25, 2021 4 - Beta pytest (>=6)
|
||||
`pytest-codecheckers <https://pypi.org/project/pytest-codecheckers/>`_ pytest plugin to add source code sanity checks (pep8 and friends) Feb 13, 2010 N/A N/A
|
||||
`pytest-codecov <https://pypi.org/project/pytest-codecov/>`_ Pytest plugin for uploading pytest-cov results to codecov.io May 05, 2021 4 - Beta pytest (>=4.6.0)
|
||||
`pytest-codegen <https://pypi.org/project/pytest-codegen/>`_ Automatically create pytest test signatures Aug 23, 2020 2 - Pre-Alpha N/A
|
||||
`pytest-codestyle <https://pypi.org/project/pytest-codestyle/>`_ pytest plugin to run pycodestyle Mar 23, 2020 3 - Alpha N/A
|
||||
`pytest-collect-formatter <https://pypi.org/project/pytest-collect-formatter/>`_ Formatter for pytest collect output Mar 29, 2021 5 - Production/Stable N/A
|
||||
`pytest-collect-formatter2 <https://pypi.org/project/pytest-collect-formatter2/>`_ Formatter for pytest collect output Apr 11, 2021 5 - Production/Stable N/A
|
||||
`pytest-collect-formatter2 <https://pypi.org/project/pytest-collect-formatter2/>`_ Formatter for pytest collect output May 31, 2021 5 - Production/Stable N/A
|
||||
`pytest-colordots <https://pypi.org/project/pytest-colordots/>`_ Colorizes the progress indicators Oct 06, 2017 5 - Production/Stable N/A
|
||||
`pytest-commander <https://pypi.org/project/pytest-commander/>`_ An interactive GUI test runner for PyTest Jan 31, 2021 N/A pytest (>=5.0.0)
|
||||
`pytest-commander <https://pypi.org/project/pytest-commander/>`_ An interactive GUI test runner for PyTest Jun 11, 2021 N/A pytest (<7.0.0,>=6.2.4)
|
||||
`pytest-common-subject <https://pypi.org/project/pytest-common-subject/>`_ pytest framework for testing different aspects of a common method Nov 12, 2020 N/A pytest (>=3.6,<7)
|
||||
`pytest-concurrent <https://pypi.org/project/pytest-concurrent/>`_ Concurrently execute test cases with multithread, multiprocess and gevent Jan 12, 2019 4 - Beta pytest (>=3.1.1)
|
||||
`pytest-config <https://pypi.org/project/pytest-config/>`_ Base configurations and utilities for developing your Python project test suite with pytest. Nov 07, 2014 5 - Production/Stable N/A
|
||||
`pytest-confluence-report <https://pypi.org/project/pytest-confluence-report/>`_ Package stands for pytest plugin to upload results into Confluence page. Nov 06, 2020 N/A N/A
|
||||
`pytest-console-scripts <https://pypi.org/project/pytest-console-scripts/>`_ Pytest plugin for testing console scripts Nov 20, 2020 4 - Beta N/A
|
||||
`pytest-console-scripts <https://pypi.org/project/pytest-console-scripts/>`_ Pytest plugin for testing console scripts Apr 26, 2021 4 - Beta N/A
|
||||
`pytest-consul <https://pypi.org/project/pytest-consul/>`_ pytest plugin with fixtures for testing consul aware apps Nov 24, 2018 3 - Alpha pytest
|
||||
`pytest-contextfixture <https://pypi.org/project/pytest-contextfixture/>`_ Define pytest fixtures as context managers. Mar 12, 2013 4 - Beta N/A
|
||||
`pytest-contexts <https://pypi.org/project/pytest-contexts/>`_ A plugin to run tests written with the Contexts framework using pytest Jul 23, 2018 4 - Beta N/A
|
||||
`pytest-cookies <https://pypi.org/project/pytest-cookies/>`_ The pytest plugin for your Cookiecutter templates. 🍪 Feb 14, 2020 5 - Production/Stable pytest (<6.0.0,>=3.3.0)
|
||||
`pytest-contexts <https://pypi.org/project/pytest-contexts/>`_ A plugin to run tests written with the Contexts framework using pytest May 19, 2021 4 - Beta N/A
|
||||
`pytest-cookies <https://pypi.org/project/pytest-cookies/>`_ The pytest plugin for your Cookiecutter templates. 🍪 May 24, 2021 5 - Production/Stable pytest (>=3.3.0)
|
||||
`pytest-couchdbkit <https://pypi.org/project/pytest-couchdbkit/>`_ py.test extension for per-test couchdb databases using couchdbkit Apr 17, 2012 N/A N/A
|
||||
`pytest-count <https://pypi.org/project/pytest-count/>`_ count erros and send email Jan 12, 2018 4 - Beta N/A
|
||||
`pytest-cov <https://pypi.org/project/pytest-cov/>`_ Pytest plugin for measuring coverage. Jan 20, 2021 5 - Production/Stable pytest (>=4.6)
|
||||
`pytest-cov <https://pypi.org/project/pytest-cov/>`_ Pytest plugin for measuring coverage. Jun 01, 2021 5 - Production/Stable pytest (>=4.6)
|
||||
`pytest-cover <https://pypi.org/project/pytest-cover/>`_ Pytest plugin for measuring coverage. Forked from `pytest-cov`. Aug 01, 2015 5 - Production/Stable N/A
|
||||
`pytest-coverage <https://pypi.org/project/pytest-coverage/>`_ Jun 17, 2015 N/A N/A
|
||||
`pytest-coverage-context <https://pypi.org/project/pytest-coverage-context/>`_ Coverage dynamic context support for PyTest, including sub-processes Jan 04, 2021 4 - Beta pytest (>=6.1.0)
|
||||
`pytest-cov-exclude <https://pypi.org/project/pytest-cov-exclude/>`_ Pytest plugin for excluding tests based on coverage data Apr 29, 2016 4 - Beta pytest (>=2.8.0,<2.9.0); extra == 'dev'
|
||||
`pytest-cpp <https://pypi.org/project/pytest-cpp/>`_ Use pytest's runner to discover and execute C++ tests Dec 10, 2020 4 - Beta pytest (!=5.4.0,!=5.4.1)
|
||||
`pytest-cpp <https://pypi.org/project/pytest-cpp/>`_ Use pytest's runner to discover and execute C++ tests Jun 04, 2021 5 - Production/Stable pytest (!=5.4.0,!=5.4.1)
|
||||
`pytest-cram <https://pypi.org/project/pytest-cram/>`_ Run cram tests with pytest. Aug 08, 2020 N/A N/A
|
||||
`pytest-crate <https://pypi.org/project/pytest-crate/>`_ Manages CrateDB instances during your integration tests May 28, 2019 3 - Alpha pytest (>=4.0)
|
||||
`pytest-cricri <https://pypi.org/project/pytest-cricri/>`_ A Cricri plugin for pytest. Jan 27, 2018 N/A pytest
|
||||
@@ -178,10 +185,11 @@ name
|
||||
`pytest-datatest <https://pypi.org/project/pytest-datatest/>`_ A pytest plugin for test driven data-wrangling (this is the development version of datatest's pytest integration). Oct 15, 2020 4 - Beta pytest (>=3.3)
|
||||
`pytest-db <https://pypi.org/project/pytest-db/>`_ Session scope fixture "db" for mysql query or change Dec 04, 2019 N/A N/A
|
||||
`pytest-dbfixtures <https://pypi.org/project/pytest-dbfixtures/>`_ Databases fixtures plugin for py.test. Dec 07, 2016 4 - Beta N/A
|
||||
`pytest-dbt-adapter <https://pypi.org/project/pytest-dbt-adapter/>`_ A pytest plugin for testing dbt adapter plugins Jan 07, 2021 N/A pytest (<7,>=6)
|
||||
`pytest-dbt-adapter <https://pypi.org/project/pytest-dbt-adapter/>`_ A pytest plugin for testing dbt adapter plugins Jun 07, 2021 N/A pytest (<7,>=6)
|
||||
`pytest-dbus-notification <https://pypi.org/project/pytest-dbus-notification/>`_ D-BUS notifications for pytest results. Mar 05, 2014 5 - Production/Stable N/A
|
||||
`pytest-deadfixtures <https://pypi.org/project/pytest-deadfixtures/>`_ A simple plugin to list unused fixtures in pytest Jul 23, 2020 5 - Production/Stable N/A
|
||||
`pytest-deepcov <https://pypi.org/project/pytest-deepcov/>`_ deepcov Mar 30, 2021 N/A N/A
|
||||
`pytest-demo-plugin <https://pypi.org/project/pytest-demo-plugin/>`_ pytest示例插件 May 15, 2021 N/A N/A
|
||||
`pytest-dependency <https://pypi.org/project/pytest-dependency/>`_ Manage dependencies of tests Feb 14, 2020 4 - Beta N/A
|
||||
`pytest-depends <https://pypi.org/project/pytest-depends/>`_ Tests that depend on other tests Apr 05, 2020 5 - Production/Stable pytest (>=3)
|
||||
`pytest-deprecate <https://pypi.org/project/pytest-deprecate/>`_ Mark tests as testing a deprecated feature with a warning note. Jul 01, 2019 N/A N/A
|
||||
@@ -192,11 +200,10 @@ name
|
||||
`pytest-dicom <https://pypi.org/project/pytest-dicom/>`_ pytest plugin to provide DICOM fixtures Dec 19, 2018 3 - Alpha pytest
|
||||
`pytest-dictsdiff <https://pypi.org/project/pytest-dictsdiff/>`_ Jul 26, 2019 N/A N/A
|
||||
`pytest-diff <https://pypi.org/project/pytest-diff/>`_ A simple plugin to use with pytest Mar 30, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-diffeo <https://pypi.org/project/pytest-diffeo/>`_ Common py.test support for Diffeo packages Apr 08, 2016 3 - Alpha N/A
|
||||
`pytest-disable <https://pypi.org/project/pytest-disable/>`_ pytest plugin to disable a test and skip it from testrun Sep 10, 2015 4 - Beta N/A
|
||||
`pytest-disable-plugin <https://pypi.org/project/pytest-disable-plugin/>`_ Disable plugins per test Feb 28, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-discord <https://pypi.org/project/pytest-discord/>`_ A pytest plugin to notify test results to a Discord channel. Mar 20, 2021 3 - Alpha pytest (!=6.0.0,<7,>=3.3.2)
|
||||
`pytest-django <https://pypi.org/project/pytest-django/>`_ A Django plugin for pytest. Apr 10, 2021 5 - Production/Stable pytest (>=5.4.0)
|
||||
`pytest-django <https://pypi.org/project/pytest-django/>`_ A Django plugin for pytest. Jun 06, 2021 5 - Production/Stable pytest (>=5.4.0)
|
||||
`pytest-django-ahead <https://pypi.org/project/pytest-django-ahead/>`_ A Django plugin for pytest. Oct 27, 2016 5 - Production/Stable pytest (>=2.9)
|
||||
`pytest-djangoapp <https://pypi.org/project/pytest-djangoapp/>`_ Nice pytest plugin to help you with Django pluggable application testing. Apr 10, 2021 4 - Beta N/A
|
||||
`pytest-django-cache-xdist <https://pypi.org/project/pytest-django-cache-xdist/>`_ A djangocachexdist plugin for pytest May 12, 2020 4 - Beta N/A
|
||||
@@ -216,7 +223,7 @@ name
|
||||
`pytest-django-testing-postgresql <https://pypi.org/project/pytest-django-testing-postgresql/>`_ Use a temporary PostgreSQL database with pytest-django Dec 05, 2019 3 - Alpha N/A
|
||||
`pytest-doc <https://pypi.org/project/pytest-doc/>`_ A documentation plugin for py.test. Jun 28, 2015 5 - Production/Stable N/A
|
||||
`pytest-docgen <https://pypi.org/project/pytest-docgen/>`_ An RST Documentation Generator for pytest-based test suites Apr 17, 2020 N/A N/A
|
||||
`pytest-docker <https://pypi.org/project/pytest-docker/>`_ Simple pytest fixtures for Docker and docker-compose based tests Sep 22, 2020 N/A pytest (<7.0,>=4.0)
|
||||
`pytest-docker <https://pypi.org/project/pytest-docker/>`_ Simple pytest fixtures for Docker and docker-compose based tests Jun 14, 2021 N/A pytest (<7.0,>=4.0)
|
||||
`pytest-docker-butla <https://pypi.org/project/pytest-docker-butla/>`_ Jun 16, 2019 3 - Alpha N/A
|
||||
`pytest-dockerc <https://pypi.org/project/pytest-dockerc/>`_ Run, manage and stop Docker Compose project from Docker API Oct 09, 2020 5 - Production/Stable pytest (>=3.0)
|
||||
`pytest-docker-compose <https://pypi.org/project/pytest-docker-compose/>`_ Manages Docker containers during your integration tests Jan 26, 2021 5 - Production/Stable pytest (>=3.3)
|
||||
@@ -227,7 +234,7 @@ name
|
||||
`pytest-docker-postgresql <https://pypi.org/project/pytest-docker-postgresql/>`_ A simple plugin to use with pytest Sep 24, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-docker-py <https://pypi.org/project/pytest-docker-py/>`_ Easy to use, simple to extend, pytest plugin that minimally leverages docker-py. Nov 27, 2018 N/A pytest (==4.0.0)
|
||||
`pytest-docker-registry-fixtures <https://pypi.org/project/pytest-docker-registry-fixtures/>`_ Pytest fixtures for testing with docker registries. Mar 04, 2021 4 - Beta pytest
|
||||
`pytest-docker-tools <https://pypi.org/project/pytest-docker-tools/>`_ Docker integration tests for pytest Mar 26, 2021 4 - Beta pytest (>=6.0.1,<7.0.0)
|
||||
`pytest-docker-tools <https://pypi.org/project/pytest-docker-tools/>`_ Docker integration tests for pytest Jun 03, 2021 4 - Beta pytest (>=6.0.1,<7.0.0)
|
||||
`pytest-docs <https://pypi.org/project/pytest-docs/>`_ Documentation tool for pytest Nov 11, 2018 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-docstyle <https://pypi.org/project/pytest-docstyle/>`_ pytest plugin to run pydocstyle Mar 23, 2020 3 - Alpha N/A
|
||||
`pytest-doctest-custom <https://pypi.org/project/pytest-doctest-custom/>`_ A py.test plugin for customizing string representations of doctest results. Jul 25, 2016 4 - Beta N/A
|
||||
@@ -242,21 +249,27 @@ name
|
||||
`pytest-drivings <https://pypi.org/project/pytest-drivings/>`_ Tool to allow webdriver automation to be ran locally or remotely Jan 13, 2021 N/A N/A
|
||||
`pytest-drop-dup-tests <https://pypi.org/project/pytest-drop-dup-tests/>`_ A Pytest plugin to drop duplicated tests during collection May 23, 2020 4 - Beta pytest (>=2.7)
|
||||
`pytest-dump2json <https://pypi.org/project/pytest-dump2json/>`_ A pytest plugin for dumping test results to json. Jun 29, 2015 N/A N/A
|
||||
`pytest-duration-insights <https://pypi.org/project/pytest-duration-insights/>`_ Jun 25, 2021 N/A N/A
|
||||
`pytest-dynamicrerun <https://pypi.org/project/pytest-dynamicrerun/>`_ A pytest plugin to rerun tests dynamically based off of test outcome and output. Aug 15, 2020 4 - Beta N/A
|
||||
`pytest-dynamodb <https://pypi.org/project/pytest-dynamodb/>`_ DynamoDB fixtures for pytest Feb 20, 2020 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-dynamodb <https://pypi.org/project/pytest-dynamodb/>`_ DynamoDB fixtures for pytest Jun 03, 2021 5 - Production/Stable pytest
|
||||
`pytest-easy-addoption <https://pypi.org/project/pytest-easy-addoption/>`_ pytest-easy-addoption: Easy way to work with pytest addoption Jan 22, 2020 N/A N/A
|
||||
`pytest-easy-api <https://pypi.org/project/pytest-easy-api/>`_ Simple API testing with pytest Mar 26, 2018 N/A N/A
|
||||
`pytest-easyMPI <https://pypi.org/project/pytest-easyMPI/>`_ Package that supports mpi tests in pytest Oct 21, 2020 N/A N/A
|
||||
`pytest-easyread <https://pypi.org/project/pytest-easyread/>`_ pytest plugin that makes terminal printouts of the reports easier to read Nov 17, 2017 N/A N/A
|
||||
`pytest-easy-server <https://pypi.org/project/pytest-easy-server/>`_ Pytest plugin for easy testing against servers Apr 05, 2021 4 - Beta pytest (<5.0.0,>=4.3.1) ; python_version < "3.5"
|
||||
`pytest-easy-server <https://pypi.org/project/pytest-easy-server/>`_ Pytest plugin for easy testing against servers May 01, 2021 4 - Beta pytest (<5.0.0,>=4.3.1) ; python_version < "3.5"
|
||||
`pytest-ec2 <https://pypi.org/project/pytest-ec2/>`_ Pytest execution on EC2 instance Oct 22, 2019 3 - Alpha N/A
|
||||
`pytest-echo <https://pypi.org/project/pytest-echo/>`_ pytest plugin with mechanisms for echoing environment variables, package version and generic attributes Jan 08, 2020 5 - Production/Stable N/A
|
||||
`pytest-elasticsearch <https://pypi.org/project/pytest-elasticsearch/>`_ Elasticsearch process and client fixtures for py.test. Feb 19, 2020 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-elasticsearch <https://pypi.org/project/pytest-elasticsearch/>`_ Elasticsearch fixtures and fixture factories for Pytest. May 12, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-elements <https://pypi.org/project/pytest-elements/>`_ Tool to help automate user interfaces Jan 13, 2021 N/A pytest (>=5.4,<6.0)
|
||||
`pytest-elk-reporter <https://pypi.org/project/pytest-elk-reporter/>`_ A simple plugin to use with pytest Jan 24, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-email <https://pypi.org/project/pytest-email/>`_ Send execution result email Jul 08, 2020 N/A pytest
|
||||
`pytest-embedded <https://pypi.org/project/pytest-embedded/>`_ pytest embedded plugin Jun 16, 2021 N/A pytest (>=6.2.0)
|
||||
`pytest-embedded-idf <https://pypi.org/project/pytest-embedded-idf/>`_ pytest embedded plugin for esp-idf project Jun 16, 2021 N/A N/A
|
||||
`pytest-embedded-qemu-idf <https://pypi.org/project/pytest-embedded-qemu-idf/>`_ pytest embedded plugin for esp-idf project by qemu, not target chip Jun 16, 2021 N/A N/A
|
||||
`pytest-embedded-serial <https://pypi.org/project/pytest-embedded-serial/>`_ pytest embedded plugin for testing serial ports Jun 16, 2021 N/A N/A
|
||||
`pytest-embedded-serial-esp <https://pypi.org/project/pytest-embedded-serial-esp/>`_ pytest embedded plugin for testing espressif boards via serial ports Jun 16, 2021 N/A N/A
|
||||
`pytest-emoji <https://pypi.org/project/pytest-emoji/>`_ A pytest plugin that adds emojis to your test result report Feb 19, 2019 4 - Beta pytest (>=4.2.1)
|
||||
`pytest-emoji-output <https://pypi.org/project/pytest-emoji-output/>`_ Pytest plugin to represent test output with emoji support Oct 03, 2020 4 - Beta N/A
|
||||
`pytest-emoji-output <https://pypi.org/project/pytest-emoji-output/>`_ Pytest plugin to represent test output with emoji support Jun 06, 2021 4 - Beta pytest (==6.0.1)
|
||||
`pytest-enabler <https://pypi.org/project/pytest-enabler/>`_ Enable installed pytest plugins Jan 19, 2021 5 - Production/Stable pytest (!=3.7.3,>=3.5) ; extra == 'testing'
|
||||
`pytest-enhancements <https://pypi.org/project/pytest-enhancements/>`_ Improvements for pytest (rejected upstream) Oct 30, 2019 4 - Beta N/A
|
||||
`pytest-env <https://pypi.org/project/pytest-env/>`_ py.test plugin that allows you to add environment variables. Jun 16, 2017 4 - Beta N/A
|
||||
@@ -277,6 +290,7 @@ name
|
||||
`pytest-expect <https://pypi.org/project/pytest-expect/>`_ py.test plugin to store test expectations and mark tests based on them Apr 21, 2016 4 - Beta N/A
|
||||
`pytest-expecter <https://pypi.org/project/pytest-expecter/>`_ Better testing with expecter and pytest. Jul 08, 2020 5 - Production/Stable N/A
|
||||
`pytest-expectr <https://pypi.org/project/pytest-expectr/>`_ This plugin is used to expect multiple assert using pytest framework. Oct 05, 2018 N/A pytest (>=2.4.2)
|
||||
`pytest-explicit <https://pypi.org/project/pytest-explicit/>`_ A Pytest plugin to ignore certain marked tests by default Jun 15, 2021 5 - Production/Stable pytest
|
||||
`pytest-exploratory <https://pypi.org/project/pytest-exploratory/>`_ Interactive console for pytest. Jan 20, 2021 N/A pytest (>=5.3)
|
||||
`pytest-external-blockers <https://pypi.org/project/pytest-external-blockers/>`_ a special outcome for tests that are blocked for external reasons Oct 04, 2016 N/A N/A
|
||||
`pytest-extra-durations <https://pypi.org/project/pytest-extra-durations/>`_ A pytest plugin to get durations on a per-function basis and per module basis. Apr 21, 2020 4 - Beta pytest (>=3.5.0)
|
||||
@@ -310,19 +324,20 @@ name
|
||||
`pytest-fixtures <https://pypi.org/project/pytest-fixtures/>`_ Common fixtures for pytest May 01, 2019 5 - Production/Stable N/A
|
||||
`pytest-fixture-tools <https://pypi.org/project/pytest-fixture-tools/>`_ Plugin for pytest which provides tools for fixtures Aug 18, 2020 6 - Mature pytest
|
||||
`pytest-flake8 <https://pypi.org/project/pytest-flake8/>`_ pytest plugin to check FLAKE8 requirements Dec 16, 2020 4 - Beta pytest (>=3.5)
|
||||
`pytest-flake8dir <https://pypi.org/project/pytest-flake8dir/>`_ A pytest fixture for testing flake8 plugins. Mar 18, 2021 5 - Production/Stable pytest
|
||||
`pytest-flake8dir <https://pypi.org/project/pytest-flake8dir/>`_ A pytest fixture for testing flake8 plugins. May 10, 2021 5 - Production/Stable pytest
|
||||
`pytest-flakefinder <https://pypi.org/project/pytest-flakefinder/>`_ Runs tests multiple times to expose flakiness. Jul 28, 2020 4 - Beta pytest (>=2.7.1)
|
||||
`pytest-flakes <https://pypi.org/project/pytest-flakes/>`_ pytest plugin to check source code with pyflakes Nov 28, 2020 5 - Production/Stable N/A
|
||||
`pytest-flaptastic <https://pypi.org/project/pytest-flaptastic/>`_ Flaptastic py.test plugin Mar 17, 2019 N/A N/A
|
||||
`pytest-flask <https://pypi.org/project/pytest-flask/>`_ A set of py.test fixtures to test Flask applications. Feb 27, 2021 5 - Production/Stable pytest (>=5.2)
|
||||
`pytest-flask-sqlalchemy <https://pypi.org/project/pytest-flask-sqlalchemy/>`_ A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions. Apr 04, 2019 4 - Beta pytest (>=3.2.1)
|
||||
`pytest-flask-sqlalchemy-transactions <https://pypi.org/project/pytest-flask-sqlalchemy-transactions/>`_ Run tests in transactions using pytest, Flask, and SQLalchemy. Aug 02, 2018 4 - Beta pytest (>=3.2.1)
|
||||
`pytest-flyte <https://pypi.org/project/pytest-flyte/>`_ Pytest fixtures for simplifying Flyte integration testing May 03, 2021 N/A pytest
|
||||
`pytest-focus <https://pypi.org/project/pytest-focus/>`_ A pytest plugin that alerts user of failed test cases with screen notifications May 04, 2019 4 - Beta pytest
|
||||
`pytest-forcefail <https://pypi.org/project/pytest-forcefail/>`_ py.test plugin to make the test failing regardless of pytest.mark.xfail May 15, 2018 4 - Beta N/A
|
||||
`pytest-forward-compatability <https://pypi.org/project/pytest-forward-compatability/>`_ A name to avoid typosquating pytest-foward-compatibility Sep 06, 2020 N/A N/A
|
||||
`pytest-forward-compatibility <https://pypi.org/project/pytest-forward-compatibility/>`_ A pytest plugin to shim pytest commandline options for fowards compatibility Sep 29, 2020 N/A N/A
|
||||
`pytest-freezegun <https://pypi.org/project/pytest-freezegun/>`_ Wrap tests with fixtures in freeze_time Jul 19, 2020 4 - Beta pytest (>=3.0.0)
|
||||
`pytest-freeze-reqs <https://pypi.org/project/pytest-freeze-reqs/>`_ Check if requirement files are frozen Nov 14, 2019 N/A N/A
|
||||
`pytest-freeze-reqs <https://pypi.org/project/pytest-freeze-reqs/>`_ Check if requirement files are frozen Apr 29, 2021 N/A N/A
|
||||
`pytest-func-cov <https://pypi.org/project/pytest-func-cov/>`_ Pytest plugin for measuring function coverage Apr 15, 2021 3 - Alpha pytest (>=5)
|
||||
`pytest-funparam <https://pypi.org/project/pytest-funparam/>`_ An alternative way to parametrize test cases Apr 23, 2021 4 - Beta pytest (>=4.6.0)
|
||||
`pytest-fxa <https://pypi.org/project/pytest-fxa/>`_ pytest plugin for Firefox Accounts Aug 28, 2018 5 - Production/Stable N/A
|
||||
@@ -332,7 +347,7 @@ name
|
||||
`pytest-gevent <https://pypi.org/project/pytest-gevent/>`_ Ensure that gevent is properly patched when invoking pytest Feb 25, 2020 N/A pytest
|
||||
`pytest-gherkin <https://pypi.org/project/pytest-gherkin/>`_ A flexible framework for executing BDD gherkin tests Jul 27, 2019 3 - Alpha pytest (>=5.0.0)
|
||||
`pytest-ghostinspector <https://pypi.org/project/pytest-ghostinspector/>`_ For finding/executing Ghost Inspector tests May 17, 2016 3 - Alpha N/A
|
||||
`pytest-girder <https://pypi.org/project/pytest-girder/>`_ A set of pytest fixtures for testing Girder applications. Apr 19, 2021 N/A N/A
|
||||
`pytest-girder <https://pypi.org/project/pytest-girder/>`_ A set of pytest fixtures for testing Girder applications. Jun 08, 2021 N/A N/A
|
||||
`pytest-git <https://pypi.org/project/pytest-git/>`_ Git repository fixture for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-gitcov <https://pypi.org/project/pytest-gitcov/>`_ Pytest plugin for reporting on coverage of the last git commit. Jan 11, 2020 2 - Pre-Alpha N/A
|
||||
`pytest-git-fixtures <https://pypi.org/project/pytest-git-fixtures/>`_ Pytest fixtures for testing with git. Mar 11, 2021 4 - Beta pytest
|
||||
@@ -351,31 +366,31 @@ name
|
||||
`pytest-helm-charts <https://pypi.org/project/pytest-helm-charts/>`_ A plugin to provide different types and configs of Kubernetes clusters that can be used for testing. Dec 22, 2020 4 - Beta pytest (>=6.1.2,<7.0.0)
|
||||
`pytest-helper <https://pypi.org/project/pytest-helper/>`_ Functions to help in using the pytest testing framework May 31, 2019 5 - Production/Stable N/A
|
||||
`pytest-helpers <https://pypi.org/project/pytest-helpers/>`_ pytest helpers May 17, 2020 N/A pytest
|
||||
`pytest-helpers-namespace <https://pypi.org/project/pytest-helpers-namespace/>`_ Pytest Helpers Namespace Plugin Mar 24, 2021 5 - Production/Stable pytest (>=6.1.1)
|
||||
`pytest-helpers-namespace <https://pypi.org/project/pytest-helpers-namespace/>`_ Pytest Helpers Namespace Plugin Apr 29, 2021 5 - Production/Stable pytest (>=6.0.0)
|
||||
`pytest-hidecaptured <https://pypi.org/project/pytest-hidecaptured/>`_ Hide captured output May 04, 2018 4 - Beta pytest (>=2.8.5)
|
||||
`pytest-historic <https://pypi.org/project/pytest-historic/>`_ Custom report to display pytest historical execution records Apr 08, 2020 N/A pytest
|
||||
`pytest-historic-hook <https://pypi.org/project/pytest-historic-hook/>`_ Custom listener to store execution results into MYSQL DB, which is used for pytest-historic report Apr 08, 2020 N/A pytest
|
||||
`pytest-homeassistant <https://pypi.org/project/pytest-homeassistant/>`_ A pytest plugin for use with homeassistant custom components. Aug 12, 2020 4 - Beta N/A
|
||||
`pytest-homeassistant-custom-component <https://pypi.org/project/pytest-homeassistant-custom-component/>`_ Experimental package to automatically extract test plugins for Home Assistant custom components Apr 16, 2021 3 - Alpha pytest (==6.2.2)
|
||||
`pytest-homeassistant-custom-component <https://pypi.org/project/pytest-homeassistant-custom-component/>`_ Experimental package to automatically extract test plugins for Home Assistant custom components Jun 04, 2021 3 - Alpha pytest (==6.2.4)
|
||||
`pytest-honors <https://pypi.org/project/pytest-honors/>`_ Report on tests that honor constraints, and guard against regressions Mar 06, 2020 4 - Beta N/A
|
||||
`pytest-hoverfly <https://pypi.org/project/pytest-hoverfly/>`_ Simplify working with Hoverfly from pytest Mar 04, 2021 N/A pytest (>=5.0)
|
||||
`pytest-hoverfly <https://pypi.org/project/pytest-hoverfly/>`_ Simplify working with Hoverfly from pytest Jun 11, 2021 N/A pytest (>=5.0)
|
||||
`pytest-hoverfly-wrapper <https://pypi.org/project/pytest-hoverfly-wrapper/>`_ Integrates the Hoverfly HTTP proxy into Pytest Jan 31, 2021 4 - Beta N/A
|
||||
`pytest-html <https://pypi.org/project/pytest-html/>`_ pytest plugin for generating HTML reports Dec 13, 2020 5 - Production/Stable pytest (!=6.0.0,>=5.0)
|
||||
`pytest-html-lee <https://pypi.org/project/pytest-html-lee/>`_ optimized pytest plugin for generating HTML reports Jun 30, 2020 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-html-profiling <https://pypi.org/project/pytest-html-profiling/>`_ Pytest plugin for generating HTML reports with per-test profiling and optionally call graph visualizations. Based on pytest-html by Dave Hunt. Feb 11, 2020 5 - Production/Stable pytest (>=3.0)
|
||||
`pytest-html-reporter <https://pypi.org/project/pytest-html-reporter/>`_ Generates a static html report based on pytest framework Apr 20, 2021 N/A N/A
|
||||
`pytest-html-reporter <https://pypi.org/project/pytest-html-reporter/>`_ Generates a static html report based on pytest framework Apr 25, 2021 N/A N/A
|
||||
`pytest-html-thread <https://pypi.org/project/pytest-html-thread/>`_ pytest plugin for generating HTML reports Dec 29, 2020 5 - Production/Stable N/A
|
||||
`pytest-http <https://pypi.org/project/pytest-http/>`_ Fixture "http" for http requests Dec 05, 2019 N/A N/A
|
||||
`pytest-httpbin <https://pypi.org/project/pytest-httpbin/>`_ Easily test your HTTP library against a local copy of httpbin Feb 11, 2019 5 - Production/Stable N/A
|
||||
`pytest-http-mocker <https://pypi.org/project/pytest-http-mocker/>`_ Pytest plugin for http mocking (via https://github.com/vilus/mocker) Oct 20, 2019 N/A N/A
|
||||
`pytest-httpretty <https://pypi.org/project/pytest-httpretty/>`_ A thin wrapper of HTTPretty for pytest Feb 16, 2014 3 - Alpha N/A
|
||||
`pytest-httpserver <https://pypi.org/project/pytest-httpserver/>`_ pytest-httpserver is a httpserver for pytest Mar 16, 2021 3 - Alpha pytest ; extra == 'dev'
|
||||
`pytest-httpx <https://pypi.org/project/pytest-httpx/>`_ Send responses to httpx. Mar 01, 2021 5 - Production/Stable pytest (==6.*)
|
||||
`pytest-httpx-blockage <https://pypi.org/project/pytest-httpx-blockage/>`_ Disable httpx requests during a test run Apr 09, 2021 N/A pytest (>=6.2.2)
|
||||
`pytest-httpx <https://pypi.org/project/pytest-httpx/>`_ Send responses to httpx. Apr 27, 2021 5 - Production/Stable pytest (==6.*)
|
||||
`pytest-httpx-blockage <https://pypi.org/project/pytest-httpx-blockage/>`_ Disable httpx requests during a test run Apr 28, 2021 N/A pytest (>=6.2.3)
|
||||
`pytest-hue <https://pypi.org/project/pytest-hue/>`_ Visualise PyTest status via your Phillips Hue lights May 09, 2019 N/A N/A
|
||||
`pytest-hylang <https://pypi.org/project/pytest-hylang/>`_ Pytest plugin to allow running tests written in hylang Mar 28, 2021 N/A pytest
|
||||
`pytest-hypo-25 <https://pypi.org/project/pytest-hypo-25/>`_ help hypo module for pytest Jan 12, 2020 3 - Alpha N/A
|
||||
`pytest-ibutsu <https://pypi.org/project/pytest-ibutsu/>`_ A plugin to sent pytest results to an Ibutsu server Mar 09, 2021 4 - Beta pytest
|
||||
`pytest-ibutsu <https://pypi.org/project/pytest-ibutsu/>`_ A plugin to sent pytest results to an Ibutsu server Jun 16, 2021 4 - Beta pytest
|
||||
`pytest-icdiff <https://pypi.org/project/pytest-icdiff/>`_ use icdiff for better error messages in pytest assertions Apr 08, 2020 4 - Beta N/A
|
||||
`pytest-idapro <https://pypi.org/project/pytest-idapro/>`_ A pytest plugin for idapython. Allows a pytest setup to run tests outside and inside IDA in an automated manner by runnig pytest inside IDA and by mocking idapython api Nov 03, 2018 N/A N/A
|
||||
`pytest-ignore-flaky <https://pypi.org/project/pytest-ignore-flaky/>`_ ignore failures from flaky tests (pytest plugin) Apr 23, 2021 5 - Production/Stable N/A
|
||||
@@ -385,19 +400,20 @@ name
|
||||
`pytest-info-collector <https://pypi.org/project/pytest-info-collector/>`_ pytest plugin to collect information from tests May 26, 2019 3 - Alpha N/A
|
||||
`pytest-informative-node <https://pypi.org/project/pytest-informative-node/>`_ display more node ininformation. Apr 25, 2019 4 - Beta N/A
|
||||
`pytest-infrastructure <https://pypi.org/project/pytest-infrastructure/>`_ pytest stack validation prior to testing executing Apr 12, 2020 4 - Beta N/A
|
||||
`pytest-inmanta <https://pypi.org/project/pytest-inmanta/>`_ A py.test plugin providing fixtures to simplify inmanta modules testing. Apr 09, 2021 5 - Production/Stable N/A
|
||||
`pytest-inmanta-extensions <https://pypi.org/project/pytest-inmanta-extensions/>`_ Inmanta tests package Mar 17, 2021 5 - Production/Stable N/A
|
||||
`pytest-inmanta <https://pypi.org/project/pytest-inmanta/>`_ A py.test plugin providing fixtures to simplify inmanta modules testing. Jun 18, 2021 5 - Production/Stable N/A
|
||||
`pytest-inmanta-extensions <https://pypi.org/project/pytest-inmanta-extensions/>`_ Inmanta tests package May 27, 2021 5 - Production/Stable N/A
|
||||
`pytest-Inomaly <https://pypi.org/project/pytest-Inomaly/>`_ A simple image diff plugin for pytest Feb 13, 2018 4 - Beta N/A
|
||||
`pytest-insta <https://pypi.org/project/pytest-insta/>`_ A practical snapshot testing plugin for pytest Apr 07, 2021 N/A pytest (>=6.0.2,<7.0.0)
|
||||
`pytest-instafail <https://pypi.org/project/pytest-instafail/>`_ pytest plugin to show failures instantly Jun 14, 2020 4 - Beta pytest (>=2.9)
|
||||
`pytest-instrument <https://pypi.org/project/pytest-instrument/>`_ pytest plugin to instrument tests Apr 05, 2020 5 - Production/Stable pytest (>=5.1.0)
|
||||
`pytest-integration <https://pypi.org/project/pytest-integration/>`_ Organizing pytests by integration or not Apr 16, 2020 N/A N/A
|
||||
`pytest-interactive <https://pypi.org/project/pytest-interactive/>`_ A pytest plugin for console based interactive test selection just after the collection phase Nov 30, 2017 3 - Alpha N/A
|
||||
`pytest-invenio <https://pypi.org/project/pytest-invenio/>`_ Pytest fixtures for Invenio. Dec 17, 2020 5 - Production/Stable pytest (<7,>=6)
|
||||
`pytest-intercept-remote <https://pypi.org/project/pytest-intercept-remote/>`_ Pytest plugin for intercepting outgoing connection requests during pytest run. May 24, 2021 4 - Beta pytest (>=4.6)
|
||||
`pytest-invenio <https://pypi.org/project/pytest-invenio/>`_ Pytest fixtures for Invenio. May 11, 2021 5 - Production/Stable pytest (<7,>=6)
|
||||
`pytest-involve <https://pypi.org/project/pytest-involve/>`_ Run tests covering a specific file or changeset Feb 02, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-ipdb <https://pypi.org/project/pytest-ipdb/>`_ A py.test plug-in to enable drop to ipdb debugger on test failure. Sep 02, 2014 2 - Pre-Alpha N/A
|
||||
`pytest-ipynb <https://pypi.org/project/pytest-ipynb/>`_ THIS PROJECT IS ABANDONED Jan 29, 2019 3 - Alpha N/A
|
||||
`pytest-isort <https://pypi.org/project/pytest-isort/>`_ py.test plugin to check import ordering using isort Jan 13, 2021 5 - Production/Stable N/A
|
||||
`pytest-isort <https://pypi.org/project/pytest-isort/>`_ py.test plugin to check import ordering using isort Apr 27, 2021 5 - Production/Stable N/A
|
||||
`pytest-it <https://pypi.org/project/pytest-it/>`_ Pytest plugin to display test reports as a plaintext spec, inspired by Rspec: https://github.com/mattduck/pytest-it. Jan 22, 2020 4 - Beta N/A
|
||||
`pytest-iterassert <https://pypi.org/project/pytest-iterassert/>`_ Nicer list and iterable assertion messages for pytest May 11, 2020 3 - Alpha N/A
|
||||
`pytest-jasmine <https://pypi.org/project/pytest-jasmine/>`_ Run jasmine tests from your pytest test suite Nov 04, 2017 1 - Planning N/A
|
||||
@@ -408,7 +424,7 @@ name
|
||||
`pytest-joke <https://pypi.org/project/pytest-joke/>`_ Test failures are better served with humor. Oct 08, 2019 4 - Beta pytest (>=4.2.1)
|
||||
`pytest-json <https://pypi.org/project/pytest-json/>`_ Generate JSON test reports Jan 18, 2016 4 - Beta N/A
|
||||
`pytest-jsonlint <https://pypi.org/project/pytest-jsonlint/>`_ UNKNOWN Aug 04, 2016 N/A N/A
|
||||
`pytest-json-report <https://pypi.org/project/pytest-json-report/>`_ A pytest plugin to report test results as JSON files Oct 23, 2020 4 - Beta pytest (>=4.2.0)
|
||||
`pytest-json-report <https://pypi.org/project/pytest-json-report/>`_ A pytest plugin to report test results as JSON files Jun 18, 2021 4 - Beta pytest (>=3.8.0)
|
||||
`pytest-kafka <https://pypi.org/project/pytest-kafka/>`_ Zookeeper, Kafka server, and Kafka consumer fixtures for Pytest Nov 01, 2019 N/A pytest
|
||||
`pytest-kind <https://pypi.org/project/pytest-kind/>`_ Kubernetes test support with KIND for pytest Jan 24, 2021 5 - Production/Stable N/A
|
||||
`pytest-kivy <https://pypi.org/project/pytest-kivy/>`_ Kivy GUI tests fixtures using pytest Mar 20, 2021 4 - Beta pytest (>=3.6)
|
||||
@@ -424,10 +440,11 @@ name
|
||||
`pytest-leaks <https://pypi.org/project/pytest-leaks/>`_ A pytest plugin to trace resource leaks. Nov 27, 2019 1 - Planning N/A
|
||||
`pytest-level <https://pypi.org/project/pytest-level/>`_ Select tests of a given level or lower Oct 21, 2019 N/A pytest
|
||||
`pytest-libfaketime <https://pypi.org/project/pytest-libfaketime/>`_ A python-libfaketime plugin for pytest. Dec 22, 2018 4 - Beta pytest (>=3.0.0)
|
||||
`pytest-libiio <https://pypi.org/project/pytest-libiio/>`_ A pytest plugin to manage interfacing with libiio contexts Jan 09, 2021 4 - Beta N/A
|
||||
`pytest-libiio <https://pypi.org/project/pytest-libiio/>`_ A pytest plugin to manage interfacing with libiio contexts Jun 15, 2021 4 - Beta N/A
|
||||
`pytest-libnotify <https://pypi.org/project/pytest-libnotify/>`_ Pytest plugin that shows notifications about the test run Apr 02, 2021 3 - Alpha pytest
|
||||
`pytest-ligo <https://pypi.org/project/pytest-ligo/>`_ Jan 16, 2020 4 - Beta N/A
|
||||
`pytest-lineno <https://pypi.org/project/pytest-lineno/>`_ A pytest plugin to show the line numbers of test functions Dec 04, 2020 N/A pytest
|
||||
`pytest-line-profiler <https://pypi.org/project/pytest-line-profiler/>`_ Profile code executed by pytest May 03, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-lisa <https://pypi.org/project/pytest-lisa/>`_ Pytest plugin for organizing tests. Jan 21, 2021 3 - Alpha pytest (>=6.1.2,<7.0.0)
|
||||
`pytest-listener <https://pypi.org/project/pytest-listener/>`_ A simple network listener May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-litf <https://pypi.org/project/pytest-litf/>`_ A pytest plugin that stream output in LITF format Jan 18, 2021 4 - Beta pytest (>=3.1.1)
|
||||
@@ -435,9 +452,10 @@ name
|
||||
`pytest-localftpserver <https://pypi.org/project/pytest-localftpserver/>`_ A PyTest plugin which provides an FTP fixture for your tests Jan 27, 2021 5 - Production/Stable pytest
|
||||
`pytest-localserver <https://pypi.org/project/pytest-localserver/>`_ py.test plugin to test server connections locally. Nov 14, 2018 4 - Beta N/A
|
||||
`pytest-localstack <https://pypi.org/project/pytest-localstack/>`_ Pytest plugin for AWS integration tests Aug 22, 2019 4 - Beta pytest (>=3.3.0)
|
||||
`pytest-lockable <https://pypi.org/project/pytest-lockable/>`_ lockable resource plugin for pytest Apr 14, 2021 3 - Alpha pytest
|
||||
`pytest-lockable <https://pypi.org/project/pytest-lockable/>`_ lockable resource plugin for pytest Jun 08, 2021 5 - Production/Stable pytest
|
||||
`pytest-locker <https://pypi.org/project/pytest-locker/>`_ Used to lock object during testing. Essentially changing assertions from being hard coded to asserting that nothing changed Feb 25, 2021 N/A pytest (>=5.4)
|
||||
`pytest-logbook <https://pypi.org/project/pytest-logbook/>`_ py.test plugin to capture logbook log messages Nov 23, 2015 5 - Production/Stable pytest (>=2.8)
|
||||
`pytest-logdog <https://pypi.org/project/pytest-logdog/>`_ Pytest plugin to test logging Jun 15, 2021 1 - Planning pytest (>=6.2.0)
|
||||
`pytest-logfest <https://pypi.org/project/pytest-logfest/>`_ Pytest plugin providing three logger fixtures with basic or full writing to log files Jul 21, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-logger <https://pypi.org/project/pytest-logger/>`_ Plugin configuring handlers for loggers from Python logging module. Jul 25, 2019 4 - Beta pytest (>=3.2)
|
||||
`pytest-logging <https://pypi.org/project/pytest-logging/>`_ Configures logging and allows tweaking the log level with a py.test flag Nov 04, 2015 4 - Beta N/A
|
||||
@@ -455,7 +473,7 @@ name
|
||||
`pytest-matrix <https://pypi.org/project/pytest-matrix/>`_ Provide tools for generating tests from combinations of fixtures. Jun 24, 2020 5 - Production/Stable pytest (>=5.4.3,<6.0.0)
|
||||
`pytest-mccabe <https://pypi.org/project/pytest-mccabe/>`_ pytest plugin to run the mccabe code complexity checker. Jul 22, 2020 3 - Alpha pytest (>=5.4.0)
|
||||
`pytest-md <https://pypi.org/project/pytest-md/>`_ Plugin for generating Markdown reports for pytest results Jul 11, 2019 3 - Alpha pytest (>=4.2.1)
|
||||
`pytest-md-report <https://pypi.org/project/pytest-md-report/>`_ A pytest plugin to make a test results report with Markdown table format. Aug 14, 2020 4 - Beta pytest (!=6.0.0,<7,>=3.3.2)
|
||||
`pytest-md-report <https://pypi.org/project/pytest-md-report/>`_ A pytest plugin to make a test results report with Markdown table format. May 04, 2021 4 - Beta pytest (!=6.0.0,<7,>=3.3.2)
|
||||
`pytest-memprof <https://pypi.org/project/pytest-memprof/>`_ Estimates memory consumption of test functions Mar 29, 2019 4 - Beta N/A
|
||||
`pytest-menu <https://pypi.org/project/pytest-menu/>`_ A pytest plugin for console based interactive test selection just after the collection phase Oct 04, 2017 3 - Alpha pytest (>=2.4.2)
|
||||
`pytest-mercurial <https://pypi.org/project/pytest-mercurial/>`_ pytest plugin to write integration tests for projects using Mercurial Python internals Nov 21, 2020 1 - Planning N/A
|
||||
@@ -467,18 +485,18 @@ name
|
||||
`pytest-missing-fixtures <https://pypi.org/project/pytest-missing-fixtures/>`_ Pytest plugin that creates missing fixtures Oct 14, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-ml <https://pypi.org/project/pytest-ml/>`_ Test your machine learning! May 04, 2019 4 - Beta N/A
|
||||
`pytest-mocha <https://pypi.org/project/pytest-mocha/>`_ pytest plugin to display test execution output like a mochajs Apr 02, 2020 4 - Beta pytest (>=5.4.0)
|
||||
`pytest-mock <https://pypi.org/project/pytest-mock/>`_ Thin-wrapper around the mock package for easier use with pytest Apr 24, 2021 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-mock <https://pypi.org/project/pytest-mock/>`_ Thin-wrapper around the mock package for easier use with pytest May 06, 2021 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-mock-api <https://pypi.org/project/pytest-mock-api/>`_ A mock API server with configurable routes and responses available as a fixture. Feb 13, 2019 1 - Planning pytest (>=4.0.0)
|
||||
`pytest-mock-helper <https://pypi.org/project/pytest-mock-helper/>`_ Help you mock HTTP call and generate mock code Jan 24, 2018 N/A pytest
|
||||
`pytest-mockito <https://pypi.org/project/pytest-mockito/>`_ Base fixtures for mockito Jul 11, 2018 4 - Beta N/A
|
||||
`pytest-mockredis <https://pypi.org/project/pytest-mockredis/>`_ An in-memory mock of a Redis server that runs in a separate thread. This is to be used for unit-tests that require a Redis database. Jan 02, 2018 2 - Pre-Alpha N/A
|
||||
`pytest-mock-resources <https://pypi.org/project/pytest-mock-resources/>`_ A pytest plugin for easily instantiating reproducible mock resources. Feb 17, 2021 N/A pytest (>=1.0)
|
||||
`pytest-mock-resources <https://pypi.org/project/pytest-mock-resources/>`_ A pytest plugin for easily instantiating reproducible mock resources. Jun 02, 2021 N/A pytest (>=1.0)
|
||||
`pytest-mock-server <https://pypi.org/project/pytest-mock-server/>`_ Mock server plugin for pytest Apr 06, 2020 4 - Beta N/A
|
||||
`pytest-mockservers <https://pypi.org/project/pytest-mockservers/>`_ A set of fixtures to test your requests to HTTP/UDP servers Mar 31, 2020 N/A pytest (>=4.3.0)
|
||||
`pytest-modifyjunit <https://pypi.org/project/pytest-modifyjunit/>`_ Utility for adding additional properties to junit xml for IDM QE Jan 10, 2019 N/A N/A
|
||||
`pytest-modifyscope <https://pypi.org/project/pytest-modifyscope/>`_ pytest plugin to modify fixture scope Apr 12, 2020 N/A pytest
|
||||
`pytest-molecule <https://pypi.org/project/pytest-molecule/>`_ PyTest Molecule Plugin :: discover and run molecule tests Jan 25, 2021 5 - Production/Stable N/A
|
||||
`pytest-mongo <https://pypi.org/project/pytest-mongo/>`_ MongoDB process and client fixtures plugin for py.test. Jan 12, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-mongo <https://pypi.org/project/pytest-mongo/>`_ MongoDB process and client fixtures plugin for Pytest. Jun 07, 2021 5 - Production/Stable pytest
|
||||
`pytest-mongodb <https://pypi.org/project/pytest-mongodb/>`_ pytest plugin for MongoDB fixtures Dec 07, 2019 5 - Production/Stable pytest (>=2.5.2)
|
||||
`pytest-monitor <https://pypi.org/project/pytest-monitor/>`_ Pytest plugin for analyzing resource usage. Apr 21, 2021 5 - Production/Stable pytest
|
||||
`pytest-monkeyplus <https://pypi.org/project/pytest-monkeyplus/>`_ pytest's monkeypatch subclass with extra functionalities Sep 18, 2012 5 - Production/Stable N/A
|
||||
@@ -488,18 +506,20 @@ name
|
||||
`pytest-mpi <https://pypi.org/project/pytest-mpi/>`_ pytest plugin to collect information from tests Mar 14, 2021 3 - Alpha pytest
|
||||
`pytest-mpl <https://pypi.org/project/pytest-mpl/>`_ pytest plugin to help with testing figures output from Matplotlib Nov 05, 2020 4 - Beta pytest
|
||||
`pytest-mproc <https://pypi.org/project/pytest-mproc/>`_ low-startup-overhead, scalable, distributed-testing pytest plugin Mar 07, 2021 4 - Beta pytest
|
||||
`pytest-multi-check <https://pypi.org/project/pytest-multi-check/>`_ Pytest-плагин, реализует возможность мульти проверок и мягких проверок Jun 03, 2021 N/A pytest
|
||||
`pytest-multihost <https://pypi.org/project/pytest-multihost/>`_ Utility for writing multi-host tests for pytest Apr 07, 2020 4 - Beta N/A
|
||||
`pytest-multilog <https://pypi.org/project/pytest-multilog/>`_ Multi-process logs handling and other helpers for pytest Nov 15, 2020 N/A N/A
|
||||
`pytest-multilog <https://pypi.org/project/pytest-multilog/>`_ Multi-process logs handling and other helpers for pytest Jun 10, 2021 N/A N/A
|
||||
`pytest-mutagen <https://pypi.org/project/pytest-mutagen/>`_ Add the mutation testing feature to pytest Jul 24, 2020 N/A pytest (>=5.4)
|
||||
`pytest-mypy <https://pypi.org/project/pytest-mypy/>`_ Mypy static type checker plugin for Pytest Mar 21, 2021 4 - Beta pytest (>=3.5)
|
||||
`pytest-mypyd <https://pypi.org/project/pytest-mypyd/>`_ Mypy static type checker plugin for Pytest Aug 20, 2019 4 - Beta pytest (<4.7,>=2.8) ; python_version < "3.5"
|
||||
`pytest-mypy-plugins <https://pypi.org/project/pytest-mypy-plugins/>`_ pytest plugin for writing tests for mypy plugins Oct 26, 2020 3 - Alpha pytest (>=6.0.0)
|
||||
`pytest-mypy-plugins <https://pypi.org/project/pytest-mypy-plugins/>`_ pytest plugin for writing tests for mypy plugins May 22, 2021 3 - Alpha pytest (>=6.0.0)
|
||||
`pytest-mypy-plugins-shim <https://pypi.org/project/pytest-mypy-plugins-shim/>`_ Substitute for "pytest-mypy-plugins" for Python implementations which aren't supported by mypy. Apr 12, 2021 N/A N/A
|
||||
`pytest-mypy-testing <https://pypi.org/project/pytest-mypy-testing/>`_ Pytest plugin to check mypy output. Apr 24, 2020 N/A pytest
|
||||
`pytest-mysql <https://pypi.org/project/pytest-mysql/>`_ MySQL process and client fixtures for pytest Jul 21, 2020 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-mypy-testing <https://pypi.org/project/pytest-mypy-testing/>`_ Pytest plugin to check mypy output. Jun 13, 2021 N/A pytest
|
||||
`pytest-mysql <https://pypi.org/project/pytest-mysql/>`_ MySQL process and client fixtures for pytest Jun 01, 2021 5 - Production/Stable pytest
|
||||
`pytest-needle <https://pypi.org/project/pytest-needle/>`_ pytest plugin for visual testing websites using selenium Dec 10, 2018 4 - Beta pytest (<5.0.0,>=3.0.0)
|
||||
`pytest-neo <https://pypi.org/project/pytest-neo/>`_ pytest-neo is a plugin for pytest that shows tests like screen of Matrix. Apr 23, 2019 3 - Alpha pytest (>=3.7.2)
|
||||
`pytest-network <https://pypi.org/project/pytest-network/>`_ A simple plugin to disable network on socket level. May 07, 2020 N/A N/A
|
||||
`pytest-never-sleep <https://pypi.org/project/pytest-never-sleep/>`_ pytest plugin helps to avoid adding tests without mock `time.sleep` May 05, 2021 3 - Alpha pytest (>=3.5.1)
|
||||
`pytest-nginx <https://pypi.org/project/pytest-nginx/>`_ nginx fixture for pytest Aug 12, 2017 5 - Production/Stable N/A
|
||||
`pytest-nginx-iplweb <https://pypi.org/project/pytest-nginx-iplweb/>`_ nginx fixture for pytest - iplweb temporary fork Mar 01, 2019 5 - Production/Stable N/A
|
||||
`pytest-ngrok <https://pypi.org/project/pytest-ngrok/>`_ Jan 22, 2020 3 - Alpha N/A
|
||||
@@ -524,11 +544,11 @@ name
|
||||
`pytest-oot <https://pypi.org/project/pytest-oot/>`_ Run object-oriented tests in a simple format Sep 18, 2016 4 - Beta N/A
|
||||
`pytest-openfiles <https://pypi.org/project/pytest-openfiles/>`_ Pytest plugin for detecting inadvertent open file handles Apr 16, 2020 3 - Alpha pytest (>=4.6)
|
||||
`pytest-opentmi <https://pypi.org/project/pytest-opentmi/>`_ pytest plugin for publish results to opentmi Feb 26, 2021 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-operator <https://pypi.org/project/pytest-operator/>`_ Fixtures for Operators Mar 29, 2021 N/A N/A
|
||||
`pytest-operator <https://pypi.org/project/pytest-operator/>`_ Fixtures for Operators Jun 03, 2021 N/A N/A
|
||||
`pytest-optional <https://pypi.org/project/pytest-optional/>`_ include/exclude values of fixtures in pytest Oct 07, 2015 N/A N/A
|
||||
`pytest-optional-tests <https://pypi.org/project/pytest-optional-tests/>`_ Easy declaration of optional tests (i.e., that are not run by default) Jul 09, 2019 4 - Beta pytest (>=4.5.0)
|
||||
`pytest-orchestration <https://pypi.org/project/pytest-orchestration/>`_ A pytest plugin for orchestrating tests Jul 18, 2019 N/A N/A
|
||||
`pytest-order <https://pypi.org/project/pytest-order/>`_ pytest plugin to run your tests in a specific order Apr 11, 2021 4 - Beta pytest (>=3.7)
|
||||
`pytest-order <https://pypi.org/project/pytest-order/>`_ pytest plugin to run your tests in a specific order May 30, 2021 4 - Beta pytest (>=5.0)
|
||||
`pytest-ordering <https://pypi.org/project/pytest-ordering/>`_ pytest plugin to run your tests in a specific order Nov 14, 2018 4 - Beta pytest
|
||||
`pytest-osxnotify <https://pypi.org/project/pytest-osxnotify/>`_ OS X notifications for py.test results. May 15, 2015 N/A N/A
|
||||
`pytest-pact <https://pypi.org/project/pytest-pact/>`_ A simple plugin to use with pytest Jan 07, 2019 4 - Beta N/A
|
||||
@@ -547,6 +567,7 @@ name
|
||||
`pytest-pep257 <https://pypi.org/project/pytest-pep257/>`_ py.test plugin for pep257 Jul 09, 2016 N/A N/A
|
||||
`pytest-pep8 <https://pypi.org/project/pytest-pep8/>`_ pytest plugin to check PEP8 requirements Apr 27, 2014 N/A N/A
|
||||
`pytest-percent <https://pypi.org/project/pytest-percent/>`_ Change the exit code of pytest test sessions when a required percent of tests pass. May 21, 2020 N/A pytest (>=5.2.0)
|
||||
`pytest-perf <https://pypi.org/project/pytest-perf/>`_ pytest-perf Jun 26, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing'
|
||||
`pytest-performance <https://pypi.org/project/pytest-performance/>`_ A simple plugin to ensure the execution of critical sections of code has not been impacted Sep 11, 2020 5 - Production/Stable pytest (>=3.7.0)
|
||||
`pytest-persistence <https://pypi.org/project/pytest-persistence/>`_ Pytest tool for persistent objects Mar 28, 2021 N/A N/A
|
||||
`pytest-pgsql <https://pypi.org/project/pytest-pgsql/>`_ Pytest plugins and helpers for tests using a Postgres database. May 13, 2020 5 - Production/Stable pytest (>=3.0.0)
|
||||
@@ -561,7 +582,7 @@ name
|
||||
`pytest-platform-markers <https://pypi.org/project/pytest-platform-markers/>`_ Markers for pytest to skip tests on specific platforms Sep 09, 2019 4 - Beta pytest (>=3.6.0)
|
||||
`pytest-play <https://pypi.org/project/pytest-play/>`_ pytest plugin that let you automate actions and assertions with test metrics reporting executing plain YAML files Jun 12, 2019 5 - Production/Stable N/A
|
||||
`pytest-playbook <https://pypi.org/project/pytest-playbook/>`_ Pytest plugin for reading playbooks. Jan 21, 2021 3 - Alpha pytest (>=6.1.2,<7.0.0)
|
||||
`pytest-playwright <https://pypi.org/project/pytest-playwright/>`_ A pytest wrapper with fixtures for Playwright to automate web browsers Apr 01, 2021 N/A pytest
|
||||
`pytest-playwright <https://pypi.org/project/pytest-playwright/>`_ A pytest wrapper with fixtures for Playwright to automate web browsers Jun 07, 2021 N/A pytest
|
||||
`pytest-plt <https://pypi.org/project/pytest-plt/>`_ Fixtures for quickly making Matplotlib plots in tests Aug 17, 2020 5 - Production/Stable pytest
|
||||
`pytest-plugin-helpers <https://pypi.org/project/pytest-plugin-helpers/>`_ A plugin to help developing and testing other plugins Nov 23, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-plus <https://pypi.org/project/pytest-plus/>`_ PyTest Plus Plugin :: extends pytest functionality Mar 19, 2020 5 - Production/Stable pytest (>=3.50)
|
||||
@@ -573,13 +594,13 @@ name
|
||||
`pytest-ponyorm <https://pypi.org/project/pytest-ponyorm/>`_ PonyORM in Pytest Oct 31, 2018 N/A pytest (>=3.1.1)
|
||||
`pytest-poo <https://pypi.org/project/pytest-poo/>`_ Visualize your crappy tests Mar 25, 2021 5 - Production/Stable pytest (>=2.3.4)
|
||||
`pytest-poo-fail <https://pypi.org/project/pytest-poo-fail/>`_ Visualize your failed tests with poo Feb 12, 2015 5 - Production/Stable N/A
|
||||
`pytest-pop <https://pypi.org/project/pytest-pop/>`_ A pytest plugin to help with testing pop projects Aug 13, 2020 5 - Production/Stable pytest (>=5.4.0)
|
||||
`pytest-pop <https://pypi.org/project/pytest-pop/>`_ A pytest plugin to help with testing pop projects May 25, 2021 5 - Production/Stable pytest
|
||||
`pytest-portion <https://pypi.org/project/pytest-portion/>`_ Select a portion of the collected tests Jan 28, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-postgres <https://pypi.org/project/pytest-postgres/>`_ Run PostgreSQL in Docker container in Pytest. Mar 22, 2020 N/A pytest
|
||||
`pytest-postgresql <https://pypi.org/project/pytest-postgresql/>`_ Postgresql fixtures and fixture factories for Pytest. Feb 23, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-postgresql <https://pypi.org/project/pytest-postgresql/>`_ Postgresql fixtures and fixture factories for Pytest. Jun 01, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-power <https://pypi.org/project/pytest-power/>`_ pytest plugin with powerful fixtures Dec 31, 2020 N/A pytest (>=5.4)
|
||||
`pytest-pride <https://pypi.org/project/pytest-pride/>`_ Minitest-style test colors Apr 02, 2016 3 - Alpha N/A
|
||||
`pytest-print <https://pypi.org/project/pytest-print/>`_ pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not stdout) Oct 23, 2020 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-print <https://pypi.org/project/pytest-print/>`_ pytest-print adds the printer fixture you can use to print messages to the user (directly to the pytest runner, not stdout) Jun 17, 2021 5 - Production/Stable pytest (>=6)
|
||||
`pytest-profiling <https://pypi.org/project/pytest-profiling/>`_ Profiling plugin for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-progress <https://pypi.org/project/pytest-progress/>`_ pytest plugin for instant test progress status Oct 06, 2020 5 - Production/Stable N/A
|
||||
`pytest-prometheus <https://pypi.org/project/pytest-prometheus/>`_ Report test pass / failures to a Prometheus PushGateway Oct 03, 2017 N/A N/A
|
||||
@@ -600,95 +621,98 @@ name
|
||||
`pytest-pyramid-server <https://pypi.org/project/pytest-pyramid-server/>`_ Pyramid server fixture for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-pytestrail <https://pypi.org/project/pytest-pytestrail/>`_ Pytest plugin for interaction with TestRail Aug 27, 2020 4 - Beta pytest (>=3.8.0)
|
||||
`pytest-pythonpath <https://pypi.org/project/pytest-pythonpath/>`_ pytest plugin for adding to the PYTHONPATH from command line or configs. Aug 22, 2018 5 - Production/Stable N/A
|
||||
`pytest-pytorch <https://pypi.org/project/pytest-pytorch/>`_ pytest plugin for a better developer experience when working with the PyTorch test suite Apr 21, 2021 4 - Beta pytest
|
||||
`pytest-pytorch <https://pypi.org/project/pytest-pytorch/>`_ pytest plugin for a better developer experience when working with the PyTorch test suite May 25, 2021 4 - Beta pytest
|
||||
`pytest-qatouch <https://pypi.org/project/pytest-qatouch/>`_ Pytest plugin for uploading test results to your QA Touch Testrun. Jun 26, 2021 4 - Beta pytest (>=6.2.0)
|
||||
`pytest-qml <https://pypi.org/project/pytest-qml/>`_ Run QML Tests with pytest Dec 02, 2020 4 - Beta pytest (>=6.0.0)
|
||||
`pytest-qt <https://pypi.org/project/pytest-qt/>`_ pytest support for PyQt and PySide applications Dec 07, 2019 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-qt <https://pypi.org/project/pytest-qt/>`_ pytest support for PyQt and PySide applications Jun 13, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-qt-app <https://pypi.org/project/pytest-qt-app/>`_ QT app fixture for py.test Dec 23, 2015 5 - Production/Stable N/A
|
||||
`pytest-quarantine <https://pypi.org/project/pytest-quarantine/>`_ A plugin for pytest to manage expected test failures Nov 24, 2019 5 - Production/Stable pytest (>=4.6)
|
||||
`pytest-quickcheck <https://pypi.org/project/pytest-quickcheck/>`_ pytest plugin to generate random data inspired by QuickCheck Nov 15, 2020 4 - Beta pytest (<6.0.0,>=4.0)
|
||||
`pytest-rabbitmq <https://pypi.org/project/pytest-rabbitmq/>`_ RabbitMQ process and client fixtures for pytest Jan 11, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-rabbitmq <https://pypi.org/project/pytest-rabbitmq/>`_ RabbitMQ process and client fixtures for pytest Jun 02, 2021 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-race <https://pypi.org/project/pytest-race/>`_ Race conditions tester for pytest Nov 21, 2016 4 - Beta N/A
|
||||
`pytest-rage <https://pypi.org/project/pytest-rage/>`_ pytest plugin to implement PEP712 Oct 21, 2011 3 - Alpha N/A
|
||||
`pytest-raises <https://pypi.org/project/pytest-raises/>`_ An implementation of pytest.raises as a pytest.mark fixture Apr 23, 2020 N/A pytest (>=3.2.2)
|
||||
`pytest-raisesregexp <https://pypi.org/project/pytest-raisesregexp/>`_ Simple pytest plugin to look for regex in Exceptions Dec 18, 2015 N/A N/A
|
||||
`pytest-raisin <https://pypi.org/project/pytest-raisin/>`_ Plugin enabling the use of exception instances with pytest.raises Jun 25, 2020 N/A pytest
|
||||
`pytest-random <https://pypi.org/project/pytest-random/>`_ py.test plugin to randomize tests Apr 28, 2013 3 - Alpha N/A
|
||||
`pytest-randomly <https://pypi.org/project/pytest-randomly/>`_ Pytest plugin to randomly order tests and control random.seed. Apr 11, 2021 5 - Production/Stable pytest
|
||||
`pytest-randomly <https://pypi.org/project/pytest-randomly/>`_ Pytest plugin to randomly order tests and control random.seed. May 10, 2021 5 - Production/Stable pytest
|
||||
`pytest-randomness <https://pypi.org/project/pytest-randomness/>`_ Pytest plugin about random seed management May 30, 2019 3 - Alpha N/A
|
||||
`pytest-random-num <https://pypi.org/project/pytest-random-num/>`_ Randomise the order in which pytest tests are run with some control over the randomness Oct 19, 2020 5 - Production/Stable N/A
|
||||
`pytest-random-order <https://pypi.org/project/pytest-random-order/>`_ Randomise the order in which pytest tests are run with some control over the randomness Nov 30, 2018 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-readme <https://pypi.org/project/pytest-readme/>`_ Test your README.md file Dec 28, 2014 5 - Production/Stable N/A
|
||||
`pytest-reana <https://pypi.org/project/pytest-reana/>`_ Pytest fixtures for REANA. Nov 24, 2020 3 - Alpha N/A
|
||||
`pytest-reana <https://pypi.org/project/pytest-reana/>`_ Pytest fixtures for REANA. Jun 07, 2021 3 - Alpha N/A
|
||||
`pytest-recording <https://pypi.org/project/pytest-recording/>`_ A pytest plugin that allows you recording of network interactions via VCR.py Nov 25, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-recordings <https://pypi.org/project/pytest-recordings/>`_ Provides pytest plugins for reporting request/response traffic, screenshots, and more to ReportPortal Aug 13, 2020 N/A N/A
|
||||
`pytest-redis <https://pypi.org/project/pytest-redis/>`_ Redis fixtures and fixture factories for Pytest. Oct 15, 2019 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-redis <https://pypi.org/project/pytest-redis/>`_ Redis fixtures and fixture factories for Pytest. May 25, 2021 5 - Production/Stable pytest
|
||||
`pytest-redmine <https://pypi.org/project/pytest-redmine/>`_ Pytest plugin for redmine Mar 19, 2018 1 - Planning N/A
|
||||
`pytest-ref <https://pypi.org/project/pytest-ref/>`_ A plugin to store reference files to ease regression testing Nov 23, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-reference-formatter <https://pypi.org/project/pytest-reference-formatter/>`_ Conveniently run pytest with a dot-formatted test reference. Oct 01, 2019 4 - Beta N/A
|
||||
`pytest-regressions <https://pypi.org/project/pytest-regressions/>`_ Easy to use fixtures to write regression tests. Jan 27, 2021 5 - Production/Stable pytest (>=3.5.0)
|
||||
`pytest-regtest <https://pypi.org/project/pytest-regtest/>`_ pytest plugin for regression tests Sep 16, 2020 N/A N/A
|
||||
`pytest-regtest <https://pypi.org/project/pytest-regtest/>`_ pytest plugin for regression tests Jun 03, 2021 N/A N/A
|
||||
`pytest-relative-order <https://pypi.org/project/pytest-relative-order/>`_ a pytest plugin that sorts tests using "before" and "after" markers May 17, 2021 4 - Beta N/A
|
||||
`pytest-relaxed <https://pypi.org/project/pytest-relaxed/>`_ Relaxed test discovery/organization for pytest Jun 14, 2019 5 - Production/Stable pytest (<5,>=3)
|
||||
`pytest-remfiles <https://pypi.org/project/pytest-remfiles/>`_ Pytest plugin to create a temporary directory with remote files Jul 01, 2019 5 - Production/Stable N/A
|
||||
`pytest-remotedata <https://pypi.org/project/pytest-remotedata/>`_ Pytest plugin for controlling remote data access. Jul 20, 2019 3 - Alpha pytest (>=3.1)
|
||||
`pytest-remote-response <https://pypi.org/project/pytest-remote-response/>`_ Pytest plugin for capturing and mocking connection requests. Jun 23, 2021 3 - Alpha pytest (>=4.6)
|
||||
`pytest-remove-stale-bytecode <https://pypi.org/project/pytest-remove-stale-bytecode/>`_ py.test plugin to remove stale byte code files. Mar 04, 2020 4 - Beta pytest
|
||||
`pytest-reorder <https://pypi.org/project/pytest-reorder/>`_ Reorder tests depending on their paths and names. May 31, 2018 4 - Beta pytest
|
||||
`pytest-repeat <https://pypi.org/project/pytest-repeat/>`_ pytest plugin for repeating tests Oct 31, 2020 5 - Production/Stable pytest (>=3.6)
|
||||
`pytest-replay <https://pypi.org/project/pytest-replay/>`_ Saves previous test runs and allow re-execute previous pytest runs to reproduce crashes or flaky tests Dec 09, 2020 4 - Beta pytest (>=3.0.0)
|
||||
`pytest-replay <https://pypi.org/project/pytest-replay/>`_ Saves previous test runs and allow re-execute previous pytest runs to reproduce crashes or flaky tests Jun 09, 2021 4 - Beta pytest (>=3.0.0)
|
||||
`pytest-repo-health <https://pypi.org/project/pytest-repo-health/>`_ A pytest plugin to report on repository standards conformance Nov 03, 2020 3 - Alpha pytest
|
||||
`pytest-report <https://pypi.org/project/pytest-report/>`_ Creates json report that is compatible with atom.io's linter message format May 11, 2016 4 - Beta N/A
|
||||
`pytest-reporter <https://pypi.org/project/pytest-reporter/>`_ Generate Pytest reports with templates Nov 05, 2020 4 - Beta pytest
|
||||
`pytest-reporter-html1 <https://pypi.org/project/pytest-reporter-html1/>`_ A basic HTML report template for Pytest Nov 02, 2020 4 - Beta N/A
|
||||
`pytest-reporter-html1 <https://pypi.org/project/pytest-reporter-html1/>`_ A basic HTML report template for Pytest Jun 08, 2021 4 - Beta N/A
|
||||
`pytest-reportinfra <https://pypi.org/project/pytest-reportinfra/>`_ Pytest plugin for reportinfra Aug 11, 2019 3 - Alpha N/A
|
||||
`pytest-reporting <https://pypi.org/project/pytest-reporting/>`_ A plugin to report summarized results in a table format Oct 25, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-reportlog <https://pypi.org/project/pytest-reportlog/>`_ Replacement for the --resultlog option, focused in simplicity and extensibility Dec 11, 2020 3 - Alpha pytest (>=5.2)
|
||||
`pytest-report-me <https://pypi.org/project/pytest-report-me/>`_ A pytest plugin to generate report. Dec 31, 2020 N/A pytest
|
||||
`pytest-report-parameters <https://pypi.org/project/pytest-report-parameters/>`_ pytest plugin for adding tests' parameters to junit report Jun 18, 2020 3 - Alpha pytest (>=2.4.2)
|
||||
`pytest-reportportal <https://pypi.org/project/pytest-reportportal/>`_ Agent for Reporting results of tests to the Report Portal Feb 15, 2021 N/A pytest (>=3.0.7)
|
||||
`pytest-reportportal <https://pypi.org/project/pytest-reportportal/>`_ Agent for Reporting results of tests to the Report Portal Jun 18, 2021 N/A pytest (>=3.8.0)
|
||||
`pytest-reqs <https://pypi.org/project/pytest-reqs/>`_ pytest plugin to check pinned requirements May 12, 2019 N/A pytest (>=2.4.2)
|
||||
`pytest-requests <https://pypi.org/project/pytest-requests/>`_ A simple plugin to use with pytest Jun 24, 2019 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-reraise <https://pypi.org/project/pytest-reraise/>`_ Make multi-threaded pytest test cases fail when they should Jun 03, 2020 5 - Production/Stable N/A
|
||||
`pytest-reraise <https://pypi.org/project/pytest-reraise/>`_ Make multi-threaded pytest test cases fail when they should Jun 17, 2021 5 - Production/Stable pytest (>=4.6)
|
||||
`pytest-rerun <https://pypi.org/project/pytest-rerun/>`_ Re-run only changed files in specified branch Jul 08, 2019 N/A pytest (>=3.6)
|
||||
`pytest-rerunfailures <https://pypi.org/project/pytest-rerunfailures/>`_ pytest plugin to re-run tests to eliminate flaky failures Sep 29, 2020 5 - Production/Stable pytest (>=5.0)
|
||||
`pytest-resilient-circuits <https://pypi.org/project/pytest-resilient-circuits/>`_ Resilient Circuits fixtures for PyTest. Apr 15, 2021 N/A N/A
|
||||
`pytest-rerunfailures <https://pypi.org/project/pytest-rerunfailures/>`_ pytest plugin to re-run tests to eliminate flaky failures May 26, 2021 5 - Production/Stable pytest (>=5.3)
|
||||
`pytest-resilient-circuits <https://pypi.org/project/pytest-resilient-circuits/>`_ Resilient Circuits fixtures for PyTest. May 14, 2021 N/A N/A
|
||||
`pytest-resource <https://pypi.org/project/pytest-resource/>`_ Load resource fixture plugin to use with pytest Nov 14, 2018 4 - Beta N/A
|
||||
`pytest-resource-path <https://pypi.org/project/pytest-resource-path/>`_ Provides path for uniform access to test resources in isolated directory Aug 18, 2020 5 - Production/Stable pytest (>=3.5.0)
|
||||
`pytest-resource-path <https://pypi.org/project/pytest-resource-path/>`_ Provides path for uniform access to test resources in isolated directory May 01, 2021 5 - Production/Stable pytest (>=3.5.0)
|
||||
`pytest-responsemock <https://pypi.org/project/pytest-responsemock/>`_ Simplified requests calls mocking for pytest Oct 10, 2020 5 - Production/Stable N/A
|
||||
`pytest-responses <https://pypi.org/project/pytest-responses/>`_ py.test integration for responses Jan 29, 2019 N/A N/A
|
||||
`pytest-restrict <https://pypi.org/project/pytest-restrict/>`_ Pytest plugin to restrict the test types allowed Dec 03, 2020 5 - Production/Stable pytest
|
||||
`pytest-responses <https://pypi.org/project/pytest-responses/>`_ py.test integration for responses Apr 26, 2021 N/A pytest (>=2.5)
|
||||
`pytest-restrict <https://pypi.org/project/pytest-restrict/>`_ Pytest plugin to restrict the test types allowed May 10, 2021 5 - Production/Stable pytest
|
||||
`pytest-rethinkdb <https://pypi.org/project/pytest-rethinkdb/>`_ A RethinkDB plugin for pytest. Jul 24, 2016 4 - Beta N/A
|
||||
`pytest-reverse <https://pypi.org/project/pytest-reverse/>`_ Pytest plugin to reverse test order. Dec 27, 2020 5 - Production/Stable pytest
|
||||
`pytest-reverse <https://pypi.org/project/pytest-reverse/>`_ Pytest plugin to reverse test order. May 10, 2021 5 - Production/Stable pytest
|
||||
`pytest-ringo <https://pypi.org/project/pytest-ringo/>`_ pytest plugin to test webapplications using the Ringo webframework Sep 27, 2017 3 - Alpha N/A
|
||||
`pytest-rng <https://pypi.org/project/pytest-rng/>`_ Fixtures for seeding tests and making randomness reproducible Aug 08, 2019 5 - Production/Stable pytest
|
||||
`pytest-roast <https://pypi.org/project/pytest-roast/>`_ pytest plugin for ROAST configuration override and fixtures Apr 05, 2021 5 - Production/Stable pytest
|
||||
`pytest-roast <https://pypi.org/project/pytest-roast/>`_ pytest plugin for ROAST configuration override and fixtures Apr 30, 2021 5 - Production/Stable pytest
|
||||
`pytest-rocketchat <https://pypi.org/project/pytest-rocketchat/>`_ Pytest to Rocket.Chat reporting plugin Apr 18, 2021 5 - Production/Stable N/A
|
||||
`pytest-rotest <https://pypi.org/project/pytest-rotest/>`_ Pytest integration with rotest Sep 08, 2019 N/A pytest (>=3.5.0)
|
||||
`pytest-rpc <https://pypi.org/project/pytest-rpc/>`_ Extend py.test for RPC OpenStack testing. Feb 22, 2019 4 - Beta pytest (~=3.6)
|
||||
`pytest-rt <https://pypi.org/project/pytest-rt/>`_ pytest data collector plugin for Testgr Mar 03, 2021 N/A N/A
|
||||
`pytest-rts <https://pypi.org/project/pytest-rts/>`_ Coverage-based regression test selection (RTS) plugin for pytest Mar 31, 2021 N/A pytest
|
||||
`pytest-rts <https://pypi.org/project/pytest-rts/>`_ Coverage-based regression test selection (RTS) plugin for pytest May 17, 2021 N/A pytest
|
||||
`pytest-run-changed <https://pypi.org/project/pytest-run-changed/>`_ Pytest plugin that runs changed tests only Apr 02, 2021 3 - Alpha pytest
|
||||
`pytest-runfailed <https://pypi.org/project/pytest-runfailed/>`_ implement a --failed option for pytest Mar 24, 2016 N/A N/A
|
||||
`pytest-runner <https://pypi.org/project/pytest-runner/>`_ Invoke py.test as distutils command with dependency resolution Feb 12, 2021 5 - Production/Stable pytest (!=3.7.3,>=3.5) ; extra == 'testing'
|
||||
`pytest-runner <https://pypi.org/project/pytest-runner/>`_ Invoke py.test as distutils command with dependency resolution May 19, 2021 5 - Production/Stable pytest (>=4.6) ; extra == 'testing'
|
||||
`pytest-salt <https://pypi.org/project/pytest-salt/>`_ Pytest Salt Plugin Jan 27, 2020 4 - Beta N/A
|
||||
`pytest-salt-containers <https://pypi.org/project/pytest-salt-containers/>`_ A Pytest plugin that builds and creates docker containers Nov 09, 2016 4 - Beta N/A
|
||||
`pytest-salt-factories <https://pypi.org/project/pytest-salt-factories/>`_ Pytest Salt Plugin Apr 14, 2021 4 - Beta pytest (>=6.1.1)
|
||||
`pytest-salt-factories <https://pypi.org/project/pytest-salt-factories/>`_ Pytest Salt Plugin Jun 20, 2021 4 - Beta pytest (>=6.0.0)
|
||||
`pytest-salt-from-filenames <https://pypi.org/project/pytest-salt-from-filenames/>`_ Simple PyTest Plugin For Salt's Test Suite Specifically Jan 29, 2019 4 - Beta pytest (>=4.1)
|
||||
`pytest-salt-runtests-bridge <https://pypi.org/project/pytest-salt-runtests-bridge/>`_ Simple PyTest Plugin For Salt's Test Suite Specifically Dec 05, 2019 4 - Beta pytest (>=4.1)
|
||||
`pytest-sanic <https://pypi.org/project/pytest-sanic/>`_ a pytest plugin for Sanic Feb 27, 2021 N/A pytest (>=5.2)
|
||||
`pytest-sanic <https://pypi.org/project/pytest-sanic/>`_ a pytest plugin for Sanic May 20, 2021 N/A pytest (>=5.2)
|
||||
`pytest-sanity <https://pypi.org/project/pytest-sanity/>`_ Dec 07, 2020 N/A N/A
|
||||
`pytest-sa-pg <https://pypi.org/project/pytest-sa-pg/>`_ May 14, 2019 N/A N/A
|
||||
`pytest-sbase <https://pypi.org/project/pytest-sbase/>`_ A complete web automation framework for end-to-end testing. Apr 24, 2021 5 - Production/Stable N/A
|
||||
`pytest-sbase <https://pypi.org/project/pytest-sbase/>`_ A complete web automation framework for end-to-end testing. Jun 21, 2021 5 - Production/Stable N/A
|
||||
`pytest-scenario <https://pypi.org/project/pytest-scenario/>`_ pytest plugin for test scenarios Feb 06, 2017 3 - Alpha N/A
|
||||
`pytest-schema <https://pypi.org/project/pytest-schema/>`_ 👍 Validate return values against a schema-like object in testing Aug 31, 2020 5 - Production/Stable pytest (>=3.5.0)
|
||||
`pytest-securestore <https://pypi.org/project/pytest-securestore/>`_ An encrypted password store for use within pytest cases Jun 19, 2019 4 - Beta N/A
|
||||
`pytest-select <https://pypi.org/project/pytest-select/>`_ A pytest plugin which allows to (de-)select tests from a file. Jan 18, 2019 3 - Alpha pytest (>=3.0)
|
||||
`pytest-selenium <https://pypi.org/project/pytest-selenium/>`_ pytest plugin for Selenium Sep 19, 2020 5 - Production/Stable pytest (>=5.0.0)
|
||||
`pytest-seleniumbase <https://pypi.org/project/pytest-seleniumbase/>`_ A complete web automation framework for end-to-end testing. Apr 24, 2021 5 - Production/Stable N/A
|
||||
`pytest-seleniumbase <https://pypi.org/project/pytest-seleniumbase/>`_ A complete web automation framework for end-to-end testing. Jun 21, 2021 5 - Production/Stable N/A
|
||||
`pytest-selenium-enhancer <https://pypi.org/project/pytest-selenium-enhancer/>`_ pytest plugin for Selenium Nov 26, 2020 5 - Production/Stable N/A
|
||||
`pytest-selenium-pdiff <https://pypi.org/project/pytest-selenium-pdiff/>`_ A pytest package implementing perceptualdiff for Selenium tests. Apr 06, 2017 2 - Pre-Alpha N/A
|
||||
`pytest-send-email <https://pypi.org/project/pytest-send-email/>`_ Send pytest execution result email Dec 04, 2019 N/A N/A
|
||||
`pytest-sentry <https://pypi.org/project/pytest-sentry/>`_ A pytest plugin to send testrun information to Sentry.io Apr 21, 2021 N/A pytest
|
||||
`pytest-server-fixtures <https://pypi.org/project/pytest-server-fixtures/>`_ Extensible server fixures for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-serverless <https://pypi.org/project/pytest-serverless/>`_ Automatically mocks resources from serverless.yml in pytest using moto. Feb 20, 2021 4 - Beta N/A
|
||||
`pytest-serverless <https://pypi.org/project/pytest-serverless/>`_ Automatically mocks resources from serverless.yml in pytest using moto. May 02, 2021 4 - Beta N/A
|
||||
`pytest-services <https://pypi.org/project/pytest-services/>`_ Services plugin for pytest testing framework Oct 30, 2020 6 - Mature N/A
|
||||
`pytest-session2file <https://pypi.org/project/pytest-session2file/>`_ 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. Jan 26, 2021 3 - Alpha pytest
|
||||
`pytest-session-fixture-globalize <https://pypi.org/project/pytest-session-fixture-globalize/>`_ py.test plugin to make session fixtures behave as if written in conftest, even if it is written in some modules May 15, 2018 4 - Beta N/A
|
||||
@@ -700,6 +724,7 @@ name
|
||||
`pytest-sherlock <https://pypi.org/project/pytest-sherlock/>`_ pytest plugin help to find coupled tests Jul 13, 2020 5 - Production/Stable pytest (>=3.5.1)
|
||||
`pytest-shortcuts <https://pypi.org/project/pytest-shortcuts/>`_ Expand command-line shortcuts listed in pytest configuration Oct 29, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-shutil <https://pypi.org/project/pytest-shutil/>`_ A goodie-bag of unix shell and environment tools for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-simplehttpserver <https://pypi.org/project/pytest-simplehttpserver/>`_ Simple pytest fixture to spin up an HTTP server Jun 24, 2021 4 - Beta N/A
|
||||
`pytest-simple-plugin <https://pypi.org/project/pytest-simple-plugin/>`_ Simple pytest plugin Nov 27, 2019 N/A N/A
|
||||
`pytest-simple-settings <https://pypi.org/project/pytest-simple-settings/>`_ simple-settings plugin for pytest Nov 17, 2020 4 - Beta pytest
|
||||
`pytest-single-file-logging <https://pypi.org/project/pytest-single-file-logging/>`_ Allow for multiple processes to log to a single file May 05, 2016 4 - Beta pytest (>=2.8.1)
|
||||
@@ -712,7 +737,7 @@ name
|
||||
`pytest-snail <https://pypi.org/project/pytest-snail/>`_ Plugin for adding a marker to slow running tests. 🐌 Nov 04, 2019 3 - Alpha pytest (>=5.0.1)
|
||||
`pytest-snapci <https://pypi.org/project/pytest-snapci/>`_ py.test plugin for Snap-CI Nov 12, 2015 N/A N/A
|
||||
`pytest-snapshot <https://pypi.org/project/pytest-snapshot/>`_ A plugin to enable snapshot testing with pytest. Apr 20, 2021 4 - Beta pytest (>=3.0.0)
|
||||
`pytest-snmpserver <https://pypi.org/project/pytest-snmpserver/>`_ Sep 14, 2020 N/A N/A
|
||||
`pytest-snmpserver <https://pypi.org/project/pytest-snmpserver/>`_ May 12, 2021 N/A N/A
|
||||
`pytest-socket <https://pypi.org/project/pytest-socket/>`_ Pytest Plugin to disable socket calls during tests Mar 30, 2021 4 - Beta pytest (>=3.6.3)
|
||||
`pytest-soft-assertions <https://pypi.org/project/pytest-soft-assertions/>`_ May 05, 2020 3 - Alpha pytest
|
||||
`pytest-solr <https://pypi.org/project/pytest-solr/>`_ Solr process and client fixtures for py.test. May 11, 2020 3 - Alpha pytest (>=3.0.0)
|
||||
@@ -720,24 +745,25 @@ name
|
||||
`pytest-sourceorder <https://pypi.org/project/pytest-sourceorder/>`_ Test-ordering plugin for pytest Apr 11, 2017 4 - Beta pytest
|
||||
`pytest-spark <https://pypi.org/project/pytest-spark/>`_ pytest plugin to run the tests with support of pyspark. Feb 23, 2020 4 - Beta pytest
|
||||
`pytest-spawner <https://pypi.org/project/pytest-spawner/>`_ py.test plugin to spawn process and communicate with them. Jul 31, 2015 4 - Beta N/A
|
||||
`pytest-spec <https://pypi.org/project/pytest-spec/>`_ Library pytest-spec is a pytest plugin to display test execution output like a SPECIFICATION. Jan 14, 2021 N/A N/A
|
||||
`pytest-spec <https://pypi.org/project/pytest-spec/>`_ Library pytest-spec is a pytest plugin to display test execution output like a SPECIFICATION. May 04, 2021 N/A N/A
|
||||
`pytest-sphinx <https://pypi.org/project/pytest-sphinx/>`_ Doctest plugin for pytest with support for Sphinx-specific doctest-directives Aug 05, 2020 4 - Beta N/A
|
||||
`pytest-spiratest <https://pypi.org/project/pytest-spiratest/>`_ Exports unit tests as test runs in SpiraTest/Team/Plan Feb 12, 2021 N/A N/A
|
||||
`pytest-spiratest <https://pypi.org/project/pytest-spiratest/>`_ Exports unit tests as test runs in SpiraTest/Team/Plan Apr 28, 2021 N/A N/A
|
||||
`pytest-splinter <https://pypi.org/project/pytest-splinter/>`_ Splinter plugin for pytest testing framework Dec 25, 2020 6 - Mature N/A
|
||||
`pytest-split <https://pypi.org/project/pytest-split/>`_ Pytest plugin for splitting test suite based on test execution time Apr 07, 2020 1 - Planning N/A
|
||||
`pytest-split <https://pypi.org/project/pytest-split/>`_ Pytest plugin for splitting test suite based on test execution time Jun 17, 2021 4 - Beta pytest (>=5,<7)
|
||||
`pytest-splitio <https://pypi.org/project/pytest-splitio/>`_ Split.io SDK integration for e2e tests Sep 22, 2020 N/A pytest (<7,>=5.0)
|
||||
`pytest-split-tests <https://pypi.org/project/pytest-split-tests/>`_ A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Forked from Mark Adams' original project pytest-test-groups. May 28, 2019 N/A pytest (>=2.5)
|
||||
`pytest-splunk-addon <https://pypi.org/project/pytest-splunk-addon/>`_ A Dynamic test tool for Splunk Apps and Add-ons Feb 26, 2021 N/A pytest (>5.4.0,<6.1)
|
||||
`pytest-splunk-addon-ui-smartx <https://pypi.org/project/pytest-splunk-addon-ui-smartx/>`_ Library to support testing Splunk Add-on UX Mar 24, 2021 N/A N/A
|
||||
`pytest-split-tests-tresorit <https://pypi.org/project/pytest-split-tests-tresorit/>`_ Feb 22, 2021 1 - Planning N/A
|
||||
`pytest-splunk-addon <https://pypi.org/project/pytest-splunk-addon/>`_ A Dynamic test tool for Splunk Apps and Add-ons Jun 21, 2021 N/A pytest (>5.4.0,<6.3)
|
||||
`pytest-splunk-addon-ui-smartx <https://pypi.org/project/pytest-splunk-addon-ui-smartx/>`_ Library to support testing Splunk Add-on UX Jun 17, 2021 N/A N/A
|
||||
`pytest-splunk-env <https://pypi.org/project/pytest-splunk-env/>`_ pytest fixtures for interaction with Splunk Enterprise and Splunk Cloud Oct 22, 2020 N/A pytest (>=6.1.1,<7.0.0)
|
||||
`pytest-sqitch <https://pypi.org/project/pytest-sqitch/>`_ sqitch for pytest Apr 06, 2020 4 - Beta N/A
|
||||
`pytest-sqlalchemy <https://pypi.org/project/pytest-sqlalchemy/>`_ pytest plugin with sqlalchemy related fixtures Mar 13, 2018 3 - Alpha N/A
|
||||
`pytest-sql-bigquery <https://pypi.org/project/pytest-sql-bigquery/>`_ Yet another SQL-testing framework for BigQuery provided by pytest plugin Dec 19, 2019 N/A pytest
|
||||
`pytest-srcpaths <https://pypi.org/project/pytest-srcpaths/>`_ Add paths to sys.path Feb 18, 2021 N/A N/A
|
||||
`pytest-srcpaths <https://pypi.org/project/pytest-srcpaths/>`_ Add paths to sys.path May 06, 2021 N/A N/A
|
||||
`pytest-ssh <https://pypi.org/project/pytest-ssh/>`_ pytest plugin for ssh command run May 27, 2019 N/A pytest
|
||||
`pytest-start-from <https://pypi.org/project/pytest-start-from/>`_ Start pytest run from a given point Apr 11, 2016 N/A N/A
|
||||
`pytest-statsd <https://pypi.org/project/pytest-statsd/>`_ pytest plugin for reporting to graphite Nov 30, 2018 5 - Production/Stable pytest (>=3.0.0)
|
||||
`pytest-stepfunctions <https://pypi.org/project/pytest-stepfunctions/>`_ A small description Jul 07, 2020 4 - Beta pytest
|
||||
`pytest-stepfunctions <https://pypi.org/project/pytest-stepfunctions/>`_ A small description May 08, 2021 4 - Beta pytest
|
||||
`pytest-steps <https://pypi.org/project/pytest-steps/>`_ Create step-wise / incremental tests in pytest. Apr 25, 2020 5 - Production/Stable N/A
|
||||
`pytest-stepwise <https://pypi.org/project/pytest-stepwise/>`_ Run a test suite one failing test at a time. Dec 01, 2015 4 - Beta N/A
|
||||
`pytest-stoq <https://pypi.org/project/pytest-stoq/>`_ A plugin to pytest stoq Feb 09, 2021 4 - Beta N/A
|
||||
@@ -747,13 +773,13 @@ name
|
||||
`pytest-stub <https://pypi.org/project/pytest-stub/>`_ Stub packages, modules and attributes. Apr 28, 2020 5 - Production/Stable N/A
|
||||
`pytest-stubprocess <https://pypi.org/project/pytest-stubprocess/>`_ Provide stub implementations for subprocesses in Python tests Sep 17, 2018 3 - Alpha pytest (>=3.5.0)
|
||||
`pytest-study <https://pypi.org/project/pytest-study/>`_ A pytest plugin to organize long run tests (named studies) without interfering the regular tests Sep 26, 2017 3 - Alpha pytest (>=2.0)
|
||||
`pytest-subprocess <https://pypi.org/project/pytest-subprocess/>`_ A plugin to fake subprocess for pytest Apr 18, 2021 5 - Production/Stable pytest (>=4.0.0)
|
||||
`pytest-subprocess <https://pypi.org/project/pytest-subprocess/>`_ A plugin to fake subprocess for pytest Jun 18, 2021 5 - Production/Stable pytest (>=4.0.0)
|
||||
`pytest-subtesthack <https://pypi.org/project/pytest-subtesthack/>`_ A hack to explicitly set up and tear down fixtures. Mar 02, 2021 N/A N/A
|
||||
`pytest-subtests <https://pypi.org/project/pytest-subtests/>`_ unittest subTest() support and subtests fixture Dec 13, 2020 4 - Beta pytest (>=5.3.0)
|
||||
`pytest-subtests <https://pypi.org/project/pytest-subtests/>`_ unittest subTest() support and subtests fixture May 29, 2021 4 - Beta pytest (>=5.3.0)
|
||||
`pytest-subunit <https://pypi.org/project/pytest-subunit/>`_ pytest-subunit is a plugin for py.test which outputs testsresult in subunit format. Aug 29, 2017 N/A N/A
|
||||
`pytest-sugar <https://pypi.org/project/pytest-sugar/>`_ pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly). Jul 06, 2020 3 - Alpha N/A
|
||||
`pytest-sugar-bugfix159 <https://pypi.org/project/pytest-sugar-bugfix159/>`_ Workaround for https://github.com/Frozenball/pytest-sugar/issues/159 Nov 07, 2018 5 - Production/Stable pytest (!=3.7.3,>=3.5); extra == 'testing'
|
||||
`pytest-super-check <https://pypi.org/project/pytest-super-check/>`_ Pytest plugin to check your TestCase classes call super in setUp, tearDown, etc. Dec 13, 2020 5 - Production/Stable pytest
|
||||
`pytest-super-check <https://pypi.org/project/pytest-super-check/>`_ Pytest plugin to check your TestCase classes call super in setUp, tearDown, etc. May 10, 2021 5 - Production/Stable pytest
|
||||
`pytest-svn <https://pypi.org/project/pytest-svn/>`_ SVN repository fixture for py.test May 28, 2019 5 - Production/Stable pytest
|
||||
`pytest-symbols <https://pypi.org/project/pytest-symbols/>`_ pytest-symbols is a pytest plugin that adds support for passing test environment symbols into pytest tests. Nov 20, 2017 3 - Alpha N/A
|
||||
`pytest-tap <https://pypi.org/project/pytest-tap/>`_ Test Anything Protocol (TAP) reporting plugin for pytest Nov 07, 2020 5 - Production/Stable pytest (>=3.0)
|
||||
@@ -763,24 +789,25 @@ name
|
||||
`pytest-teamcity-logblock <https://pypi.org/project/pytest-teamcity-logblock/>`_ py.test plugin to introduce block structure in teamcity build log, if output is not captured May 15, 2018 4 - Beta N/A
|
||||
`pytest-telegram <https://pypi.org/project/pytest-telegram/>`_ Pytest to Telegram reporting plugin Dec 10, 2020 5 - Production/Stable N/A
|
||||
`pytest-tempdir <https://pypi.org/project/pytest-tempdir/>`_ Predictable and repeatable tempdir support. Oct 11, 2019 4 - Beta pytest (>=2.8.1)
|
||||
`pytest-terraform <https://pypi.org/project/pytest-terraform/>`_ A pytest plugin for using terraform fixtures Oct 20, 2020 N/A pytest (>=6.0.0,<6.1.0)
|
||||
`pytest-terraform <https://pypi.org/project/pytest-terraform/>`_ A pytest plugin for using terraform fixtures Apr 25, 2021 N/A pytest (>=6.0,<7.0)
|
||||
`pytest-terraform-fixture <https://pypi.org/project/pytest-terraform-fixture/>`_ generate terraform resources to use with pytest Nov 14, 2018 4 - Beta N/A
|
||||
`pytest-testbook <https://pypi.org/project/pytest-testbook/>`_ A plugin to run tests written in Jupyter notebook Dec 11, 2016 3 - Alpha N/A
|
||||
`pytest-testconfig <https://pypi.org/project/pytest-testconfig/>`_ Test configuration plugin for pytest. Jan 11, 2020 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-testdirectory <https://pypi.org/project/pytest-testdirectory/>`_ A py.test plugin providing temporary directories in unit tests. Nov 06, 2018 5 - Production/Stable pytest
|
||||
`pytest-testdox <https://pypi.org/project/pytest-testdox/>`_ A testdox format reporter for pytest Oct 13, 2020 5 - Production/Stable pytest (>=3.7.0)
|
||||
`pytest-test-groups <https://pypi.org/project/pytest-test-groups/>`_ A Pytest plugin for running a subset of your tests by splitting them in to equally sized groups. Oct 25, 2016 5 - Production/Stable N/A
|
||||
`pytest-testinfra <https://pypi.org/project/pytest-testinfra/>`_ Test infrastructures Apr 18, 2021 5 - Production/Stable pytest (!=3.0.2)
|
||||
`pytest-testinfra <https://pypi.org/project/pytest-testinfra/>`_ Test infrastructures Jun 20, 2021 5 - Production/Stable pytest (!=3.0.2)
|
||||
`pytest-testlink-adaptor <https://pypi.org/project/pytest-testlink-adaptor/>`_ pytest reporting plugin for testlink Dec 20, 2018 4 - Beta pytest (>=2.6)
|
||||
`pytest-testmon <https://pypi.org/project/pytest-testmon/>`_ selects tests affected by changed files and methods Mar 18, 2021 4 - Beta N/A
|
||||
`pytest-testmon <https://pypi.org/project/pytest-testmon/>`_ selects tests affected by changed files and methods Apr 28, 2021 4 - Beta N/A
|
||||
`pytest-testobject <https://pypi.org/project/pytest-testobject/>`_ Plugin to use TestObject Suites with Pytest Sep 24, 2019 4 - Beta pytest (>=3.1.1)
|
||||
`pytest-testrail <https://pypi.org/project/pytest-testrail/>`_ pytest plugin for creating TestRail runs and adding results Aug 27, 2020 N/A pytest (>=3.6)
|
||||
`pytest-testrail2 <https://pypi.org/project/pytest-testrail2/>`_ A small example package Nov 17, 2020 N/A pytest (>=5)
|
||||
`pytest-testrail-api <https://pypi.org/project/pytest-testrail-api/>`_ Плагин Pytest, для интеграции с TestRail Apr 23, 2021 N/A pytest (>=5.5)
|
||||
`pytest-testrail-api <https://pypi.org/project/pytest-testrail-api/>`_ Плагин Pytest, для интеграции с TestRail Jun 23, 2021 N/A pytest (>=5.5)
|
||||
`pytest-testrail-client <https://pypi.org/project/pytest-testrail-client/>`_ pytest plugin for Testrail Sep 29, 2020 5 - Production/Stable N/A
|
||||
`pytest-testrail-e2e <https://pypi.org/project/pytest-testrail-e2e/>`_ pytest plugin for creating TestRail runs and adding results Jun 11, 2020 N/A pytest (>=3.6)
|
||||
`pytest-testrail-plugin <https://pypi.org/project/pytest-testrail-plugin/>`_ PyTest plugin for TestRail Apr 21, 2020 3 - Alpha pytest
|
||||
`pytest-testrail-reporter <https://pypi.org/project/pytest-testrail-reporter/>`_ Sep 10, 2018 N/A N/A
|
||||
`pytest-testreport <https://pypi.org/project/pytest-testreport/>`_ Jun 10, 2021 4 - Beta pytest (>=3.5.0)
|
||||
`pytest-testslide <https://pypi.org/project/pytest-testslide/>`_ TestSlide fixture for pytest Jan 07, 2021 5 - Production/Stable pytest (~=6.2)
|
||||
`pytest-test-this <https://pypi.org/project/pytest-test-this/>`_ Plugin for py.test to run relevant tests, based on naively checking if a test contains a reference to the symbol you supply Sep 15, 2019 2 - Pre-Alpha pytest (>=2.3)
|
||||
`pytest-tesults <https://pypi.org/project/pytest-tesults/>`_ Tesults plugin for pytest May 18, 2020 5 - Production/Stable pytest (>=3.5.0)
|
||||
@@ -790,7 +817,8 @@ name
|
||||
`pytest-timeit <https://pypi.org/project/pytest-timeit/>`_ A pytest plugin to time test function runs Oct 13, 2016 4 - Beta N/A
|
||||
`pytest-timeout <https://pypi.org/project/pytest-timeout/>`_ py.test plugin to abort hanging tests Jul 15, 2020 5 - Production/Stable pytest (>=3.6.0)
|
||||
`pytest-timeouts <https://pypi.org/project/pytest-timeouts/>`_ Linux-only Pytest plugin to control durations of various test case execution phases Sep 21, 2019 5 - Production/Stable N/A
|
||||
`pytest-timer <https://pypi.org/project/pytest-timer/>`_ A timer plugin for pytest Dec 13, 2020 N/A N/A
|
||||
`pytest-timer <https://pypi.org/project/pytest-timer/>`_ A timer plugin for pytest Jun 02, 2021 N/A N/A
|
||||
`pytest-timestamper <https://pypi.org/project/pytest-timestamper/>`_ Pytest plugin to add a timestamp prefix to the pytest output Jun 06, 2021 N/A N/A
|
||||
`pytest-tipsi-django <https://pypi.org/project/pytest-tipsi-django/>`_ Oct 14, 2020 4 - Beta pytest (>=6.0.0)
|
||||
`pytest-tipsi-testing <https://pypi.org/project/pytest-tipsi-testing/>`_ Better fixtures management. Various helpers Nov 04, 2020 4 - Beta pytest (>=3.3.0)
|
||||
`pytest-tldr <https://pypi.org/project/pytest-tldr/>`_ A pytest plugin that limits the output to just the things you need. Mar 12, 2021 4 - Beta pytest (>=3.5.0)
|
||||
@@ -821,9 +849,11 @@ name
|
||||
`pytest-unittest-filter <https://pypi.org/project/pytest-unittest-filter/>`_ A pytest plugin for filtering unittest-based test classes Jan 12, 2019 4 - Beta pytest (>=3.1.0)
|
||||
`pytest-unmarked <https://pypi.org/project/pytest-unmarked/>`_ Run only unmarked tests Aug 27, 2019 5 - Production/Stable N/A
|
||||
`pytest-unordered <https://pypi.org/project/pytest-unordered/>`_ Test equality of unordered collections in pytest Mar 28, 2021 4 - Beta N/A
|
||||
`pytest-upload-report <https://pypi.org/project/pytest-upload-report/>`_ pytest-upload-report is a plugin for pytest that upload your test report for test results. Jun 18, 2021 5 - Production/Stable N/A
|
||||
`pytest-vagrant <https://pypi.org/project/pytest-vagrant/>`_ A py.test plugin providing access to vagrant. Mar 23, 2020 5 - Production/Stable pytest
|
||||
`pytest-valgrind <https://pypi.org/project/pytest-valgrind/>`_ Mar 15, 2020 N/A N/A
|
||||
`pytest-valgrind <https://pypi.org/project/pytest-valgrind/>`_ May 19, 2021 N/A N/A
|
||||
`pytest-variables <https://pypi.org/project/pytest-variables/>`_ pytest plugin for providing variables to tests/fixtures Oct 23, 2019 5 - Production/Stable pytest (>=2.4.2)
|
||||
`pytest-variant <https://pypi.org/project/pytest-variant/>`_ Variant support for Pytest Jun 20, 2021 N/A N/A
|
||||
`pytest-vcr <https://pypi.org/project/pytest-vcr/>`_ Plugin for managing VCR.py cassettes Apr 26, 2019 5 - Production/Stable pytest (>=3.6.0)
|
||||
`pytest-vcrpandas <https://pypi.org/project/pytest-vcrpandas/>`_ Test from HTTP interactions to dataframe processed. Jan 12, 2019 4 - Beta pytest
|
||||
`pytest-venv <https://pypi.org/project/pytest-venv/>`_ py.test fixture for creating a virtual environment Aug 04, 2020 4 - Beta pytest
|
||||
@@ -844,9 +874,10 @@ name
|
||||
`pytest-wholenodeid <https://pypi.org/project/pytest-wholenodeid/>`_ pytest addon for displaying the whole node id for failures Aug 26, 2015 4 - Beta pytest (>=2.0)
|
||||
`pytest-winnotify <https://pypi.org/project/pytest-winnotify/>`_ Windows tray notifications for py.test results. Apr 22, 2016 N/A N/A
|
||||
`pytest-workflow <https://pypi.org/project/pytest-workflow/>`_ A pytest plugin for configuring workflow/pipeline tests using YAML files Dec 14, 2020 5 - Production/Stable pytest (>=5.4.0)
|
||||
`pytest-xdist <https://pypi.org/project/pytest-xdist/>`_ pytest xdist plugin for distributed testing and loop-on-failing modes Feb 09, 2021 5 - Production/Stable pytest (>=6.0.0)
|
||||
`pytest-xdist <https://pypi.org/project/pytest-xdist/>`_ pytest xdist plugin for distributed testing and loop-on-failing modes Jun 16, 2021 5 - Production/Stable pytest (>=6.0.0)
|
||||
`pytest-xdist-debug-for-graingert <https://pypi.org/project/pytest-xdist-debug-for-graingert/>`_ pytest xdist plugin for distributed testing and loop-on-failing modes Jul 24, 2019 5 - Production/Stable pytest (>=4.4.0)
|
||||
`pytest-xdist-forked <https://pypi.org/project/pytest-xdist-forked/>`_ forked from pytest-xdist Feb 10, 2020 5 - Production/Stable pytest (>=4.4.0)
|
||||
`pytest-xdist-tracker <https://pypi.org/project/pytest-xdist-tracker/>`_ pytest plugin helps to reproduce failures for particular xdist node May 05, 2021 3 - Alpha pytest (>=3.5.1)
|
||||
`pytest-xfaillist <https://pypi.org/project/pytest-xfaillist/>`_ Maintain a xfaillist in an additional file to avoid merge-conflicts. Mar 07, 2021 N/A pytest (>=6.2.2,<7.0.0)
|
||||
`pytest-xfiles <https://pypi.org/project/pytest-xfiles/>`_ Pytest fixtures providing data read from function, module or package related (x)files. Feb 27, 2018 N/A N/A
|
||||
`pytest-xlog <https://pypi.org/project/pytest-xlog/>`_ Extended logging for test and decorators May 31, 2020 4 - Beta N/A
|
||||
@@ -865,6 +896,6 @@ name
|
||||
`pytest-yuk <https://pypi.org/project/pytest-yuk/>`_ Display tests you are uneasy with, using 🤢/🤮 for pass/fail of tests marked with yuk. Mar 26, 2021 N/A N/A
|
||||
`pytest-zafira <https://pypi.org/project/pytest-zafira/>`_ A Zafira plugin for pytest Sep 18, 2019 5 - Production/Stable pytest (==4.1.1)
|
||||
`pytest-zap <https://pypi.org/project/pytest-zap/>`_ OWASP ZAP plugin for py.test. May 12, 2014 4 - Beta N/A
|
||||
`pytest-zebrunner <https://pypi.org/project/pytest-zebrunner/>`_ Pytest connector for Zebrunner reporting Apr 06, 2021 4 - Beta pytest (>=6.1.1,<7.0.0)
|
||||
`pytest-zebrunner <https://pypi.org/project/pytest-zebrunner/>`_ Pytest connector for Zebrunner reporting May 12, 2021 5 - Production/Stable pytest (>=6.0.0,<7.0.0)
|
||||
`pytest-zigzag <https://pypi.org/project/pytest-zigzag/>`_ Extend py.test for RPC OpenStack testing. Feb 27, 2019 4 - Beta pytest (~=3.6)
|
||||
============================================================================================================== ======================================================================================================================================================================== ============== ===================== ================================================
|
||||
|
||||
@@ -226,6 +226,37 @@ Marks a test function as *expected to fail*.
|
||||
a new release of a library fixes a known bug).
|
||||
|
||||
|
||||
pytest.__version__
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The current pytest version, as a string::
|
||||
|
||||
>>> import pytest
|
||||
>>> pytest.__version__
|
||||
'7.0.0'
|
||||
|
||||
|
||||
.. _`version-tuple`:
|
||||
|
||||
pytest.version_tuple
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 7.0
|
||||
|
||||
The current pytest version, as a tuple::
|
||||
|
||||
>>> import pytest
|
||||
>>> pytest.version_tuple
|
||||
(7, 0, 0)
|
||||
|
||||
For pre-releases, the last component will be a string with the prerelease version::
|
||||
|
||||
>>> import pytest
|
||||
>>> pytest.version_tuple
|
||||
(7, 0, '0rc1')
|
||||
|
||||
|
||||
|
||||
Custom marks
|
||||
~~~~~~~~~~~~
|
||||
|
||||
@@ -615,7 +646,7 @@ tmpdir_factory
|
||||
|
||||
:ref:`tmpdir and tmpdir_factory`
|
||||
|
||||
``tmp_path_factory`` is an instance of :class:`~pytest.TempdirFactory`:
|
||||
``tmpdir_factory`` is an instance of :class:`~pytest.TempdirFactory`:
|
||||
|
||||
.. autoclass:: pytest.TempdirFactory()
|
||||
:members:
|
||||
@@ -787,7 +818,7 @@ CollectReport
|
||||
Config
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: _pytest.config.Config()
|
||||
.. autoclass:: pytest.Config()
|
||||
:members:
|
||||
|
||||
ExceptionInfo
|
||||
@@ -889,14 +920,19 @@ Node
|
||||
Parser
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: _pytest.config.argparsing.Parser()
|
||||
.. autoclass:: pytest.Parser()
|
||||
:members:
|
||||
|
||||
OptionGroup
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: pytest.OptionGroup()
|
||||
:members:
|
||||
|
||||
PytestPluginManager
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: _pytest.config.PytestPluginManager()
|
||||
.. autoclass:: pytest.PytestPluginManager()
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
@@ -42,6 +42,14 @@ filterwarnings = [
|
||||
"default:invalid escape sequence:DeprecationWarning",
|
||||
# ignore use of unregistered marks, because we use many to test the implementation
|
||||
"ignore::_pytest.warning_types.PytestUnknownMarkWarning",
|
||||
# https://github.com/benjaminp/six/issues/341
|
||||
"ignore:_SixMetaPathImporter\\.exec_module\\(\\) not found; falling back to load_module\\(\\):ImportWarning",
|
||||
# https://github.com/benjaminp/six/pull/352
|
||||
"ignore:_SixMetaPathImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning",
|
||||
# https://github.com/pypa/setuptools/pull/2517
|
||||
"ignore:VendorImporter\\.find_spec\\(\\) not found; falling back to find_module\\(\\):ImportWarning",
|
||||
# https://github.com/pytest-dev/execnet/pull/127
|
||||
"ignore:isSet\\(\\) is deprecated, use is_set\\(\\) instead:DeprecationWarning",
|
||||
]
|
||||
pytester_example_dir = "testing/example_scripts"
|
||||
markers = [
|
||||
|
||||
@@ -9,9 +9,8 @@ The appropriate version will be obtained based on the given branch automatically
|
||||
|
||||
After that, it will create a release using the `release` tox environment, and push a new PR.
|
||||
|
||||
**Secret**: currently the secret is defined in the @pytestbot account,
|
||||
which the core maintainers have access to. There we created a new secret named `chatops`
|
||||
with write access to the repository.
|
||||
**Token**: currently the token from the GitHub Actions is used, pushed with
|
||||
`pytest bot <pytestbot@gmail.com>` commit author.
|
||||
"""
|
||||
import argparse
|
||||
import re
|
||||
@@ -47,14 +46,16 @@ def login(token: str) -> Repository:
|
||||
return github.repository(owner, repo)
|
||||
|
||||
|
||||
def prepare_release_pr(base_branch: str, is_major: bool, token: str) -> None:
|
||||
def prepare_release_pr(
|
||||
base_branch: str, is_major: bool, token: str, prerelease: str
|
||||
) -> None:
|
||||
print()
|
||||
print(f"Processing release for branch {Fore.CYAN}{base_branch}")
|
||||
|
||||
check_call(["git", "checkout", f"origin/{base_branch}"])
|
||||
|
||||
try:
|
||||
version = find_next_version(base_branch, is_major)
|
||||
version = find_next_version(base_branch, is_major, prerelease)
|
||||
except InvalidFeatureRelease as e:
|
||||
print(f"{Fore.RED}{e}")
|
||||
raise SystemExit(1)
|
||||
@@ -65,22 +66,16 @@ def prepare_release_pr(base_branch: str, is_major: bool, token: str) -> None:
|
||||
|
||||
run(
|
||||
["git", "config", "user.name", "pytest bot"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
run(
|
||||
["git", "config", "user.email", "pytestbot@gmail.com"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
run(
|
||||
["git", "checkout", "-b", release_branch, f"origin/{base_branch}"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
print(f"Branch {Fore.CYAN}{release_branch}{Fore.RESET} created.")
|
||||
@@ -91,17 +86,13 @@ def prepare_release_pr(base_branch: str, is_major: bool, token: str) -> None:
|
||||
print("Running", " ".join(cmdline))
|
||||
run(
|
||||
cmdline,
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
oauth_url = f"https://{token}:x-oauth-basic@github.com/{SLUG}.git"
|
||||
run(
|
||||
["git", "push", oauth_url, f"HEAD:{release_branch}", "--force"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
print(f"Branch {Fore.CYAN}{release_branch}{Fore.RESET} pushed.")
|
||||
|
||||
@@ -116,7 +107,7 @@ def prepare_release_pr(base_branch: str, is_major: bool, token: str) -> None:
|
||||
print(f"Pull request {Fore.CYAN}{pr.url}{Fore.RESET} created.")
|
||||
|
||||
|
||||
def find_next_version(base_branch: str, is_major: bool) -> str:
|
||||
def find_next_version(base_branch: str, is_major: bool, prerelease: str) -> str:
|
||||
output = check_output(["git", "tag"], encoding="UTF-8")
|
||||
valid_versions = []
|
||||
for v in output.splitlines():
|
||||
@@ -134,11 +125,11 @@ def find_next_version(base_branch: str, is_major: bool) -> str:
|
||||
is_feature_release = features or breaking
|
||||
|
||||
if is_major:
|
||||
return f"{last_version[0]+1}.0.0"
|
||||
return f"{last_version[0]+1}.0.0{prerelease}"
|
||||
elif is_feature_release:
|
||||
return f"{last_version[0]}.{last_version[1] + 1}.0"
|
||||
return f"{last_version[0]}.{last_version[1] + 1}.0{prerelease}"
|
||||
else:
|
||||
return f"{last_version[0]}.{last_version[1]}.{last_version[2] + 1}"
|
||||
return f"{last_version[0]}.{last_version[1]}.{last_version[2] + 1}{prerelease}"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -147,9 +138,13 @@ def main() -> None:
|
||||
parser.add_argument("base_branch")
|
||||
parser.add_argument("token")
|
||||
parser.add_argument("--major", action="store_true", default=False)
|
||||
parser.add_argument("--prerelease", default="")
|
||||
options = parser.parse_args()
|
||||
prepare_release_pr(
|
||||
base_branch=options.base_branch, is_major=options.major, token=options.token
|
||||
base_branch=options.base_branch,
|
||||
is_major=options.major,
|
||||
token=options.token,
|
||||
prerelease=options.prerelease,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,261 +0,0 @@
|
||||
"""
|
||||
This script is part of the pytest release process which is triggered by comments
|
||||
in issues.
|
||||
|
||||
This script is started by the `release-on-comment.yml` workflow, which always executes on
|
||||
`main` and is triggered by two comment related events:
|
||||
|
||||
* https://help.github.com/en/actions/reference/events-that-trigger-workflows#issue-comment-event-issue_comment
|
||||
* https://help.github.com/en/actions/reference/events-that-trigger-workflows#issues-event-issues
|
||||
|
||||
This script receives the payload and a secrets on the command line.
|
||||
|
||||
The payload must contain a comment with a phrase matching this pseudo-regular expression:
|
||||
|
||||
@pytestbot please prepare (major )? release from <branch name>
|
||||
|
||||
Then the appropriate version will be obtained based on the given branch name:
|
||||
|
||||
* a major release from main if "major" appears in the phrase in that position
|
||||
* a feature or bug fix release from main (based if there are features in the current changelog
|
||||
folder)
|
||||
* a bug fix from a maintenance branch
|
||||
|
||||
After that, it will create a release using the `release` tox environment, and push a new PR.
|
||||
|
||||
**Secret**: currently the secret is defined in the @pytestbot account, which the core maintainers
|
||||
have access to. There we created a new secret named `chatops` with write access to the repository.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError
|
||||
from subprocess import check_call
|
||||
from subprocess import check_output
|
||||
from subprocess import run
|
||||
from textwrap import dedent
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
|
||||
from colorama import Fore
|
||||
from colorama import init
|
||||
from github3.repos import Repository
|
||||
|
||||
|
||||
class InvalidFeatureRelease(Exception):
|
||||
pass
|
||||
|
||||
|
||||
SLUG = "pytest-dev/pytest"
|
||||
|
||||
PR_BODY = """\
|
||||
Created automatically from {comment_url}.
|
||||
|
||||
Once all builds pass and it has been **approved** by one or more maintainers, the build
|
||||
can be released by pushing a tag `{version}` to this repository.
|
||||
|
||||
Closes #{issue_number}.
|
||||
"""
|
||||
|
||||
|
||||
def login(token: str) -> Repository:
|
||||
import github3
|
||||
|
||||
github = github3.login(token=token)
|
||||
owner, repo = SLUG.split("/")
|
||||
return github.repository(owner, repo)
|
||||
|
||||
|
||||
def get_comment_data(payload: Dict) -> str:
|
||||
if "comment" in payload:
|
||||
return payload["comment"]
|
||||
else:
|
||||
return payload["issue"]
|
||||
|
||||
|
||||
def validate_and_get_issue_comment_payload(
|
||||
issue_payload_path: Optional[Path],
|
||||
) -> Tuple[str, str, bool]:
|
||||
payload = json.loads(issue_payload_path.read_text(encoding="UTF-8"))
|
||||
body = get_comment_data(payload)["body"]
|
||||
m = re.match(r"@pytestbot please prepare (major )?release from ([-_.\w]+)", body)
|
||||
if m:
|
||||
is_major, base_branch = m.group(1) is not None, m.group(2)
|
||||
else:
|
||||
is_major, base_branch = False, None
|
||||
return payload, base_branch, is_major
|
||||
|
||||
|
||||
def print_and_exit(msg) -> None:
|
||||
print(msg)
|
||||
raise SystemExit(1)
|
||||
|
||||
|
||||
def trigger_release(payload_path: Path, token: str) -> None:
|
||||
payload, base_branch, is_major = validate_and_get_issue_comment_payload(
|
||||
payload_path
|
||||
)
|
||||
if base_branch is None:
|
||||
url = get_comment_data(payload)["html_url"]
|
||||
print_and_exit(
|
||||
f"Comment {Fore.CYAN}{url}{Fore.RESET} did not match the trigger command."
|
||||
)
|
||||
print()
|
||||
print(f"Precessing release for branch {Fore.CYAN}{base_branch}")
|
||||
|
||||
repo = login(token)
|
||||
|
||||
issue_number = payload["issue"]["number"]
|
||||
issue = repo.issue(issue_number)
|
||||
|
||||
check_call(["git", "checkout", f"origin/{base_branch}"])
|
||||
|
||||
try:
|
||||
version = find_next_version(base_branch, is_major)
|
||||
except InvalidFeatureRelease as e:
|
||||
issue.create_comment(str(e))
|
||||
print_and_exit(f"{Fore.RED}{e}")
|
||||
|
||||
error_contents = ""
|
||||
try:
|
||||
print(f"Version: {Fore.CYAN}{version}")
|
||||
|
||||
release_branch = f"release-{version}"
|
||||
|
||||
run(
|
||||
["git", "config", "user.name", "pytest bot"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
run(
|
||||
["git", "config", "user.email", "pytestbot@gmail.com"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
run(
|
||||
["git", "checkout", "-b", release_branch, f"origin/{base_branch}"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
print(f"Branch {Fore.CYAN}{release_branch}{Fore.RESET} created.")
|
||||
|
||||
# important to use tox here because we have changed branches, so dependencies
|
||||
# might have changed as well
|
||||
cmdline = ["tox", "-e", "release", "--", version, "--skip-check-links"]
|
||||
print("Running", " ".join(cmdline))
|
||||
run(
|
||||
cmdline,
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
oauth_url = f"https://{token}:x-oauth-basic@github.com/{SLUG}.git"
|
||||
run(
|
||||
["git", "push", oauth_url, f"HEAD:{release_branch}", "--force"],
|
||||
text=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
print(f"Branch {Fore.CYAN}{release_branch}{Fore.RESET} pushed.")
|
||||
|
||||
body = PR_BODY.format(
|
||||
comment_url=get_comment_data(payload)["html_url"],
|
||||
version=version,
|
||||
issue_number=issue_number,
|
||||
)
|
||||
pr = repo.create_pull(
|
||||
f"Prepare release {version}",
|
||||
base=base_branch,
|
||||
head=release_branch,
|
||||
body=body,
|
||||
)
|
||||
print(f"Pull request {Fore.CYAN}{pr.url}{Fore.RESET} created.")
|
||||
|
||||
comment = issue.create_comment(
|
||||
f"As requested, opened a PR for release `{version}`: #{pr.number}."
|
||||
)
|
||||
print(f"Notified in original comment {Fore.CYAN}{comment.url}{Fore.RESET}.")
|
||||
|
||||
except CalledProcessError as e:
|
||||
error_contents = f"CalledProcessError\noutput:\n{e.output}\nstderr:\n{e.stderr}"
|
||||
except Exception:
|
||||
error_contents = f"Exception:\n{traceback.format_exc()}"
|
||||
|
||||
if error_contents:
|
||||
link = f"https://github.com/{SLUG}/actions/runs/{os.environ['GITHUB_RUN_ID']}"
|
||||
msg = ERROR_COMMENT.format(
|
||||
version=version, base_branch=base_branch, contents=error_contents, link=link
|
||||
)
|
||||
issue.create_comment(msg)
|
||||
print_and_exit(f"{Fore.RED}{error_contents}")
|
||||
else:
|
||||
print(f"{Fore.GREEN}Success.")
|
||||
|
||||
|
||||
ERROR_COMMENT = """\
|
||||
The request to prepare release `{version}` from {base_branch} failed with:
|
||||
|
||||
```
|
||||
{contents}
|
||||
```
|
||||
|
||||
See: {link}.
|
||||
"""
|
||||
|
||||
|
||||
def find_next_version(base_branch: str, is_major: bool) -> str:
|
||||
output = check_output(["git", "tag"], encoding="UTF-8")
|
||||
valid_versions = []
|
||||
for v in output.splitlines():
|
||||
m = re.match(r"\d.\d.\d+$", v.strip())
|
||||
if m:
|
||||
valid_versions.append(tuple(int(x) for x in v.split(".")))
|
||||
|
||||
valid_versions.sort()
|
||||
last_version = valid_versions[-1]
|
||||
|
||||
changelog = Path("changelog")
|
||||
|
||||
features = list(changelog.glob("*.feature.rst"))
|
||||
breaking = list(changelog.glob("*.breaking.rst"))
|
||||
is_feature_release = features or breaking
|
||||
|
||||
if is_feature_release and base_branch != "main":
|
||||
msg = dedent(
|
||||
f"""
|
||||
Found features or breaking changes in `{base_branch}`, and feature releases can only be
|
||||
created from `main`:
|
||||
"""
|
||||
)
|
||||
msg += "\n".join(f"* `{x.name}`" for x in sorted(features + breaking))
|
||||
raise InvalidFeatureRelease(msg)
|
||||
|
||||
if is_major:
|
||||
return f"{last_version[0]+1}.0.0"
|
||||
elif is_feature_release:
|
||||
return f"{last_version[0]}.{last_version[1] + 1}.0"
|
||||
else:
|
||||
return f"{last_version[0]}.{last_version[1]}.{last_version[2] + 1}"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
init(autoreset=True)
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("payload")
|
||||
parser.add_argument("token")
|
||||
options = parser.parse_args()
|
||||
trigger_release(Path(options.payload), options.token)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -100,10 +100,7 @@ def pre_release(version, *, skip_check_links):
|
||||
|
||||
|
||||
def changelog(version, write_out=False):
|
||||
if write_out:
|
||||
addopts = []
|
||||
else:
|
||||
addopts = ["--draft"]
|
||||
addopts = [] if write_out else ["--draft"]
|
||||
check_call(["towncrier", "--yes", "--version", version] + addopts)
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
set -x
|
||||
|
||||
if [ -z "$TOXENV" ]; then
|
||||
# Install coverage.
|
||||
if [[ -z ${TOXENV+x} || -z $TOXENV ]]; then
|
||||
python -m pip install coverage
|
||||
else
|
||||
# Add last TOXENV to $PATH.
|
||||
PATH="$PWD/.tox/${TOXENV##*,}/bin:$PATH"
|
||||
fi
|
||||
|
||||
# Run coverage.
|
||||
python -m coverage xml
|
||||
|
||||
# Download and verify latest Codecov bash uploader.
|
||||
# Set --connect-timeout to work around https://github.com/curl/curl/issues/4461
|
||||
curl -S -L --connect-timeout 5 --retry 6 -s https://codecov.io/bash -o codecov-upload.sh
|
||||
bash codecov-upload.sh -Z -X fix -f coverage.xml "$@"
|
||||
curl --silent --show-error --location --connect-timeout 5 --retry 6 -o codecov https://codecov.io/bash
|
||||
VERSION=$(grep --only-matching 'VERSION=\"[0-9\.]*\"' codecov | cut -d'"' -f2)
|
||||
if command -v sha256sum; then
|
||||
sha256sum --check --strict --ignore-missing --quiet <(curl --silent "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA256SUM")
|
||||
else
|
||||
shasum --algorithm 256 --check --strict --ignore-missing --quiet <(curl --silent "https://raw.githubusercontent.com/codecov/codecov-bash/${VERSION}/SHA256SUM")
|
||||
fi
|
||||
|
||||
# Upload coverage.
|
||||
bash codecov -Z -X fix -f coverage.xml "$@"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
__all__ = ["__version__"]
|
||||
__all__ = ["__version__", "version_tuple"]
|
||||
|
||||
try:
|
||||
from ._version import version as __version__
|
||||
except ImportError:
|
||||
from ._version import version as __version__, version_tuple
|
||||
except ImportError: # pragma: no cover
|
||||
# broken installation, we don't even try
|
||||
# unknown only works because we do poor mans version compare
|
||||
__version__ = "unknown"
|
||||
version_tuple = (0, 0, "unknown") # type:ignore[assignment]
|
||||
|
||||
@@ -48,6 +48,7 @@ from _pytest.pathlib import bestrelpath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing_extensions import Literal
|
||||
from typing_extensions import SupportsIndex
|
||||
from weakref import ReferenceType
|
||||
|
||||
_TracebackStyle = Literal["long", "short", "line", "no", "native", "value", "auto"]
|
||||
@@ -371,14 +372,16 @@ class Traceback(List[TracebackEntry]):
|
||||
return self
|
||||
|
||||
@overload
|
||||
def __getitem__(self, key: int) -> TracebackEntry:
|
||||
def __getitem__(self, key: "SupportsIndex") -> TracebackEntry:
|
||||
...
|
||||
|
||||
@overload
|
||||
def __getitem__(self, key: slice) -> "Traceback":
|
||||
...
|
||||
|
||||
def __getitem__(self, key: Union[int, slice]) -> Union[TracebackEntry, "Traceback"]:
|
||||
def __getitem__(
|
||||
self, key: Union["SupportsIndex", slice]
|
||||
) -> Union[TracebackEntry, "Traceback"]:
|
||||
if isinstance(key, slice):
|
||||
return self.__class__(super().__getitem__(key))
|
||||
else:
|
||||
@@ -422,21 +425,12 @@ class Traceback(List[TracebackEntry]):
|
||||
f = entry.frame
|
||||
loc = f.f_locals
|
||||
for otherloc in values:
|
||||
if f.eval(
|
||||
co_equal,
|
||||
__recursioncache_locals_1=loc,
|
||||
__recursioncache_locals_2=otherloc,
|
||||
):
|
||||
if otherloc == loc:
|
||||
return i
|
||||
values.append(entry.frame.f_locals)
|
||||
return None
|
||||
|
||||
|
||||
co_equal = compile(
|
||||
"__recursioncache_locals_1 == __recursioncache_locals_2", "?", "eval"
|
||||
)
|
||||
|
||||
|
||||
E = TypeVar("E", bound=BaseException, covariant=True)
|
||||
|
||||
|
||||
@@ -734,11 +728,11 @@ class FormattedExcinfo:
|
||||
) -> List[str]:
|
||||
"""Return formatted and marked up source lines."""
|
||||
lines = []
|
||||
if source is not None and line_index < 0:
|
||||
line_index += len(source.lines)
|
||||
if source is None or line_index >= len(source.lines) or line_index < 0:
|
||||
if source is None or line_index >= len(source.lines):
|
||||
source = Source("???")
|
||||
line_index = 0
|
||||
if line_index < 0:
|
||||
line_index += len(source)
|
||||
space_prefix = " "
|
||||
if short:
|
||||
lines.append(space_prefix + source.lines[line_index].strip())
|
||||
|
||||
@@ -180,7 +180,15 @@ def _compare_eq_any(left: Any, right: Any, verbose: int = 0) -> List[str]:
|
||||
if istext(left) and istext(right):
|
||||
explanation = _diff_text(left, right, verbose)
|
||||
else:
|
||||
if type(left) == type(right) and (
|
||||
from _pytest.python_api import ApproxBase
|
||||
|
||||
if isinstance(left, ApproxBase) or isinstance(right, ApproxBase):
|
||||
# Although the common order should be obtained == expected, this ensures both ways
|
||||
approx_side = left if isinstance(left, ApproxBase) else right
|
||||
other_side = right if isinstance(left, ApproxBase) else left
|
||||
|
||||
explanation = approx_side._repr_compare(other_side)
|
||||
elif type(left) == type(right) and (
|
||||
isdatacls(left) or isattrs(left) or isnamedtuple(left)
|
||||
):
|
||||
# Note: unlike dataclasses/attrs, namedtuples compare only the
|
||||
@@ -196,9 +204,11 @@ def _compare_eq_any(left: Any, right: Any, verbose: int = 0) -> List[str]:
|
||||
explanation = _compare_eq_dict(left, right, verbose)
|
||||
elif verbose > 0:
|
||||
explanation = _compare_eq_verbose(left, right)
|
||||
|
||||
if isiterable(left) and isiterable(right):
|
||||
expl = _compare_eq_iterable(left, right, verbose)
|
||||
explanation.extend(expl)
|
||||
|
||||
return explanation
|
||||
|
||||
|
||||
|
||||
@@ -618,14 +618,8 @@ class MultiCapture(Generic[AnyStr]):
|
||||
return self._state == "started"
|
||||
|
||||
def readouterr(self) -> CaptureResult[AnyStr]:
|
||||
if self.out:
|
||||
out = self.out.snap()
|
||||
else:
|
||||
out = ""
|
||||
if self.err:
|
||||
err = self.err.snap()
|
||||
else:
|
||||
err = ""
|
||||
out = self.out.snap() if self.out else ""
|
||||
err = self.err.snap() if self.err else ""
|
||||
return CaptureResult(out, err)
|
||||
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ def get_config(
|
||||
|
||||
def get_plugin_manager() -> "PytestPluginManager":
|
||||
"""Obtain a new instance of the
|
||||
:py:class:`_pytest.config.PytestPluginManager`, with default plugins
|
||||
:py:class:`pytest.PytestPluginManager`, with default plugins
|
||||
already loaded.
|
||||
|
||||
This function can be used by integration with other tools, like hooking
|
||||
@@ -632,6 +632,7 @@ class PytestPluginManager(PluginManager):
|
||||
def consider_preparse(
|
||||
self, args: Sequence[str], *, exclude_only: bool = False
|
||||
) -> None:
|
||||
""":meta private:"""
|
||||
i = 0
|
||||
n = len(args)
|
||||
while i < n:
|
||||
@@ -653,6 +654,7 @@ class PytestPluginManager(PluginManager):
|
||||
self.consider_pluginarg(parg)
|
||||
|
||||
def consider_pluginarg(self, arg: str) -> None:
|
||||
""":meta private:"""
|
||||
if arg.startswith("no:"):
|
||||
name = arg[3:]
|
||||
if name in essential_plugins:
|
||||
@@ -678,12 +680,15 @@ class PytestPluginManager(PluginManager):
|
||||
self.import_plugin(arg, consider_entry_points=True)
|
||||
|
||||
def consider_conftest(self, conftestmodule: types.ModuleType) -> None:
|
||||
""":meta private:"""
|
||||
self.register(conftestmodule, name=conftestmodule.__file__)
|
||||
|
||||
def consider_env(self) -> None:
|
||||
""":meta private:"""
|
||||
self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS"))
|
||||
|
||||
def consider_module(self, mod: types.ModuleType) -> None:
|
||||
""":meta private:"""
|
||||
self._import_plugin_specs(getattr(mod, "pytest_plugins", []))
|
||||
|
||||
def _import_plugin_specs(
|
||||
@@ -841,6 +846,7 @@ class Config:
|
||||
"""Access to configuration values, pluginmanager and plugin hooks.
|
||||
|
||||
:param PytestPluginManager pluginmanager:
|
||||
A pytest PluginManager.
|
||||
|
||||
:param InvocationParams invocation_params:
|
||||
Object containing parameters regarding the :func:`pytest.main`
|
||||
@@ -909,6 +915,7 @@ class Config:
|
||||
self._parser = Parser(
|
||||
usage=f"%(prog)s [options] [{_a}] [{_a}] [...]",
|
||||
processopt=self._processopt,
|
||||
_ispytest=True,
|
||||
)
|
||||
self.pluginmanager = pluginmanager
|
||||
"""The plugin manager handles plugin registration and hook invocation.
|
||||
@@ -1226,8 +1233,8 @@ class Config:
|
||||
|
||||
@hookimpl(hookwrapper=True)
|
||||
def pytest_collection(self) -> Generator[None, None, None]:
|
||||
"""Validate invalid ini keys after collection is done so we take in account
|
||||
options added by late-loading conftest files."""
|
||||
# Validate invalid ini keys after collection is done so we take in account
|
||||
# options added by late-loading conftest files.
|
||||
yield
|
||||
self._validate_config_options()
|
||||
|
||||
@@ -1380,8 +1387,8 @@ class Config:
|
||||
"""Return configuration value from an :ref:`ini file <configfiles>`.
|
||||
|
||||
If the specified name hasn't been registered through a prior
|
||||
:py:func:`parser.addini <_pytest.config.argparsing.Parser.addini>`
|
||||
call (usually from a plugin), a ValueError is raised.
|
||||
:func:`parser.addini <pytest.Parser.addini>` call (usually from a
|
||||
plugin), a ValueError is raised.
|
||||
"""
|
||||
try:
|
||||
return self._inicache[name]
|
||||
@@ -1427,6 +1434,12 @@ class Config:
|
||||
dp = self.inipath.parent
|
||||
input_values = shlex.split(value) if isinstance(value, str) else value
|
||||
return [legacy_path(str(dp / x)) for x in input_values]
|
||||
elif type == "paths":
|
||||
# TODO: This assert is probably not valid in all cases.
|
||||
assert self.inipath is not None
|
||||
dp = self.inipath.parent
|
||||
input_values = shlex.split(value) if isinstance(value, str) else value
|
||||
return [dp / x for x in input_values]
|
||||
elif type == "args":
|
||||
return shlex.split(value) if isinstance(value, str) else value
|
||||
elif type == "linelist":
|
||||
@@ -1605,7 +1618,7 @@ def parse_warning_filter(
|
||||
raise warnings._OptionError(f"too many fields (max 5): {arg!r}")
|
||||
while len(parts) < 5:
|
||||
parts.append("")
|
||||
action_, message, category_, module, lineno_ = [s.strip() for s in parts]
|
||||
action_, message, category_, module, lineno_ = (s.strip() for s in parts)
|
||||
action: str = warnings._getaction(action_) # type: ignore[attr-defined]
|
||||
category: Type[Warning] = warnings._getcategory(category_) # type: ignore[attr-defined]
|
||||
if message and escape:
|
||||
|
||||
@@ -21,6 +21,7 @@ from _pytest.config.exceptions import UsageError
|
||||
from _pytest.deprecated import ARGUMENT_PERCENT_DEFAULT
|
||||
from _pytest.deprecated import ARGUMENT_TYPE_STR
|
||||
from _pytest.deprecated import ARGUMENT_TYPE_STR_CHOICE
|
||||
from _pytest.deprecated import check_ispytest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import NoReturn
|
||||
@@ -43,8 +44,11 @@ class Parser:
|
||||
self,
|
||||
usage: Optional[str] = None,
|
||||
processopt: Optional[Callable[["Argument"], None]] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
self._anonymous = OptionGroup("custom options", parser=self)
|
||||
check_ispytest(_ispytest)
|
||||
self._anonymous = OptionGroup("custom options", parser=self, _ispytest=True)
|
||||
self._groups: List[OptionGroup] = []
|
||||
self._processopt = processopt
|
||||
self._usage = usage
|
||||
@@ -67,14 +71,14 @@ class Parser:
|
||||
:after: Name of another group, used for ordering --help output.
|
||||
|
||||
The returned group object has an ``addoption`` method with the same
|
||||
signature as :py:func:`parser.addoption
|
||||
<_pytest.config.argparsing.Parser.addoption>` but will be shown in the
|
||||
respective group in the output of ``pytest. --help``.
|
||||
signature as :func:`parser.addoption <pytest.Parser.addoption>` but
|
||||
will be shown in the respective group in the output of
|
||||
``pytest. --help``.
|
||||
"""
|
||||
for group in self._groups:
|
||||
if group.name == name:
|
||||
return group
|
||||
group = OptionGroup(name, description, parser=self)
|
||||
group = OptionGroup(name, description, parser=self, _ispytest=True)
|
||||
i = 0
|
||||
for i, grp in enumerate(self._groups):
|
||||
if grp.name == after:
|
||||
@@ -163,22 +167,35 @@ class Parser:
|
||||
name: str,
|
||||
help: str,
|
||||
type: Optional[
|
||||
"Literal['string', 'pathlist', 'args', 'linelist', 'bool']"
|
||||
"Literal['string', 'paths', 'pathlist', 'args', 'linelist', 'bool']"
|
||||
] = None,
|
||||
default=None,
|
||||
) -> None:
|
||||
"""Register an ini-file option.
|
||||
|
||||
:name: Name of the ini-variable.
|
||||
:type: Type of the variable, can be ``string``, ``pathlist``, ``args``,
|
||||
``linelist`` or ``bool``. Defaults to ``string`` if ``None`` or
|
||||
not passed.
|
||||
:default: Default value if no ini-file option exists but is queried.
|
||||
:name:
|
||||
Name of the ini-variable.
|
||||
:type:
|
||||
Type of the variable. Can be:
|
||||
|
||||
* ``string``: a string
|
||||
* ``bool``: a boolean
|
||||
* ``args``: a list of strings, separated as in a shell
|
||||
* ``linelist``: a list of strings, separated by line breaks
|
||||
* ``paths``: a list of :class:`pathlib.Path`, separated as in a shell
|
||||
* ``pathlist``: a list of ``py.path``, separated as in a shell
|
||||
|
||||
.. versionadded:: 6.3
|
||||
The ``paths`` variable type.
|
||||
|
||||
Defaults to ``string`` if ``None`` or not passed.
|
||||
:default:
|
||||
Default value if no ini-file option exists but is queried.
|
||||
|
||||
The value of ini-variables can be retrieved via a call to
|
||||
:py:func:`config.getini(name) <_pytest.config.Config.getini>`.
|
||||
:py:func:`config.getini(name) <pytest.Config.getini>`.
|
||||
"""
|
||||
assert type in (None, "string", "pathlist", "args", "linelist", "bool")
|
||||
assert type in (None, "string", "paths", "pathlist", "args", "linelist", "bool")
|
||||
self._inidict[name] = (help, type, default)
|
||||
self._ininames.append(name)
|
||||
|
||||
@@ -321,9 +338,17 @@ class Argument:
|
||||
|
||||
|
||||
class OptionGroup:
|
||||
"""A group of options shown in its own section."""
|
||||
|
||||
def __init__(
|
||||
self, name: str, description: str = "", parser: Optional[Parser] = None
|
||||
self,
|
||||
name: str,
|
||||
description: str = "",
|
||||
parser: Optional[Parser] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.options: List[Argument] = []
|
||||
@@ -333,9 +358,9 @@ class OptionGroup:
|
||||
"""Add an option to this group.
|
||||
|
||||
If a shortened version of a long option is specified, it will
|
||||
be suppressed in the help. addoption('--twowords', '--two-words')
|
||||
results in help showing '--two-words' only, but --twowords gets
|
||||
accepted **and** the automatic destination is in args.twowords.
|
||||
be suppressed in the help. ``addoption('--twowords', '--two-words')``
|
||||
results in help showing ``--two-words`` only, but ``--twowords`` gets
|
||||
accepted **and** the automatic destination is in ``args.twowords``.
|
||||
"""
|
||||
conflict = set(optnames).intersection(
|
||||
name for opt in self.options for name in opt.names()
|
||||
|
||||
@@ -53,7 +53,7 @@ def pytest_addoption(parser: Parser) -> None:
|
||||
dest="usepdb_cls",
|
||||
metavar="modulename:classname",
|
||||
type=_validate_usepdb_cls,
|
||||
help="start a custom interactive Python debugger on errors. "
|
||||
help="specify a custom interactive Python debugger for use with --pdb."
|
||||
"For example: --pdbcls=IPython.terminal.debugger:TerminalPdb",
|
||||
)
|
||||
group._addoption(
|
||||
|
||||
@@ -101,6 +101,12 @@ HOOK_LEGACY_PATH_ARG = UnformattedWarning(
|
||||
"see https://docs.pytest.org/en/latest/deprecations.html"
|
||||
"#py-path-local-arguments-for-hooks-replaced-with-pathlib-path",
|
||||
)
|
||||
|
||||
WARNS_NONE_ARG = PytestDeprecationWarning(
|
||||
"Passing None to catch any warning has been deprecated, pass no arguments instead:\n"
|
||||
" Replace pytest.warns(None) by simply pytest.warns()."
|
||||
)
|
||||
|
||||
# You want to make some `__init__` or function "private".
|
||||
#
|
||||
# def my_private_function(some, args):
|
||||
|
||||
@@ -145,10 +145,7 @@ def _is_doctest(config: Config, path: Path, parent: Collector) -> bool:
|
||||
if path.suffix in (".txt", ".rst") and parent.session.isinitpath(path):
|
||||
return True
|
||||
globs = config.getoption("doctestglob") or ["test*.txt"]
|
||||
for glob in globs:
|
||||
if fnmatch_ex(glob, path):
|
||||
return True
|
||||
return False
|
||||
return any(fnmatch_ex(glob, path) for glob in globs)
|
||||
|
||||
|
||||
class ReprFailDoctest(TerminalRepr):
|
||||
@@ -322,58 +319,54 @@ class DoctestItem(pytest.Item):
|
||||
elif isinstance(excinfo.value, MultipleDoctestFailures):
|
||||
failures = excinfo.value.failures
|
||||
|
||||
if failures is not None:
|
||||
reprlocation_lines = []
|
||||
for failure in failures:
|
||||
example = failure.example
|
||||
test = failure.test
|
||||
filename = test.filename
|
||||
if test.lineno is None:
|
||||
lineno = None
|
||||
else:
|
||||
lineno = test.lineno + example.lineno + 1
|
||||
message = type(failure).__name__
|
||||
# TODO: ReprFileLocation doesn't expect a None lineno.
|
||||
reprlocation = ReprFileLocation(filename, lineno, message) # type: ignore[arg-type]
|
||||
checker = _get_checker()
|
||||
report_choice = _get_report_choice(
|
||||
self.config.getoption("doctestreport")
|
||||
)
|
||||
if lineno is not None:
|
||||
assert failure.test.docstring is not None
|
||||
lines = failure.test.docstring.splitlines(False)
|
||||
# add line numbers to the left of the error message
|
||||
assert test.lineno is not None
|
||||
lines = [
|
||||
"%03d %s" % (i + test.lineno + 1, x)
|
||||
for (i, x) in enumerate(lines)
|
||||
]
|
||||
# trim docstring error lines to 10
|
||||
lines = lines[max(example.lineno - 9, 0) : example.lineno + 1]
|
||||
else:
|
||||
lines = [
|
||||
"EXAMPLE LOCATION UNKNOWN, not showing all tests of that example"
|
||||
]
|
||||
indent = ">>>"
|
||||
for line in example.source.splitlines():
|
||||
lines.append(f"??? {indent} {line}")
|
||||
indent = "..."
|
||||
if isinstance(failure, doctest.DocTestFailure):
|
||||
lines += checker.output_difference(
|
||||
example, failure.got, report_choice
|
||||
).split("\n")
|
||||
else:
|
||||
inner_excinfo = ExceptionInfo.from_exc_info(failure.exc_info)
|
||||
lines += ["UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value)]
|
||||
lines += [
|
||||
x.strip("\n")
|
||||
for x in traceback.format_exception(*failure.exc_info)
|
||||
]
|
||||
reprlocation_lines.append((reprlocation, lines))
|
||||
return ReprFailDoctest(reprlocation_lines)
|
||||
else:
|
||||
if failures is None:
|
||||
return super().repr_failure(excinfo)
|
||||
|
||||
reprlocation_lines = []
|
||||
for failure in failures:
|
||||
example = failure.example
|
||||
test = failure.test
|
||||
filename = test.filename
|
||||
if test.lineno is None:
|
||||
lineno = None
|
||||
else:
|
||||
lineno = test.lineno + example.lineno + 1
|
||||
message = type(failure).__name__
|
||||
# TODO: ReprFileLocation doesn't expect a None lineno.
|
||||
reprlocation = ReprFileLocation(filename, lineno, message) # type: ignore[arg-type]
|
||||
checker = _get_checker()
|
||||
report_choice = _get_report_choice(self.config.getoption("doctestreport"))
|
||||
if lineno is not None:
|
||||
assert failure.test.docstring is not None
|
||||
lines = failure.test.docstring.splitlines(False)
|
||||
# add line numbers to the left of the error message
|
||||
assert test.lineno is not None
|
||||
lines = [
|
||||
"%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines)
|
||||
]
|
||||
# trim docstring error lines to 10
|
||||
lines = lines[max(example.lineno - 9, 0) : example.lineno + 1]
|
||||
else:
|
||||
lines = [
|
||||
"EXAMPLE LOCATION UNKNOWN, not showing all tests of that example"
|
||||
]
|
||||
indent = ">>>"
|
||||
for line in example.source.splitlines():
|
||||
lines.append(f"??? {indent} {line}")
|
||||
indent = "..."
|
||||
if isinstance(failure, doctest.DocTestFailure):
|
||||
lines += checker.output_difference(
|
||||
example, failure.got, report_choice
|
||||
).split("\n")
|
||||
else:
|
||||
inner_excinfo = ExceptionInfo.from_exc_info(failure.exc_info)
|
||||
lines += ["UNEXPECTED EXCEPTION: %s" % repr(inner_excinfo.value)]
|
||||
lines += [
|
||||
x.strip("\n") for x in traceback.format_exception(*failure.exc_info)
|
||||
]
|
||||
reprlocation_lines.append((reprlocation, lines))
|
||||
return ReprFailDoctest(reprlocation_lines)
|
||||
|
||||
def reportinfo(self):
|
||||
assert self.dtest is not None
|
||||
return legacy_path(self.path), self.dtest.lineno, "[doctest] %s" % self.name
|
||||
@@ -651,10 +644,7 @@ def _init_checker_class() -> Type["doctest.OutputChecker"]:
|
||||
exponent: Optional[str] = w.group("exponent1")
|
||||
if exponent is None:
|
||||
exponent = w.group("exponent2")
|
||||
if fraction is None:
|
||||
precision = 0
|
||||
else:
|
||||
precision = len(fraction)
|
||||
precision = 0 if fraction is None else len(fraction)
|
||||
if exponent is not None:
|
||||
precision -= int(exponent)
|
||||
if float(w.group()) == approx(float(g.group()), abs=10 ** -precision):
|
||||
|
||||
@@ -276,7 +276,7 @@ def get_parametrized_fixture_keys(item: nodes.Item, scopenum: int) -> Iterator[_
|
||||
def reorder_items(items: Sequence[nodes.Item]) -> List[nodes.Item]:
|
||||
argkeys_cache: Dict[int, Dict[nodes.Item, Dict[_Key, None]]] = {}
|
||||
items_by_argkey: Dict[int, Dict[_Key, Deque[nodes.Item]]] = {}
|
||||
for scopenum in range(0, scopenum_function):
|
||||
for scopenum in range(scopenum_function):
|
||||
d: Dict[nodes.Item, Dict[_Key, None]] = {}
|
||||
argkeys_cache[scopenum] = d
|
||||
item_d: Dict[_Key, Deque[nodes.Item]] = defaultdict(deque)
|
||||
@@ -296,7 +296,7 @@ def fix_cache_order(
|
||||
argkeys_cache: Dict[int, Dict[nodes.Item, Dict[_Key, None]]],
|
||||
items_by_argkey: Dict[int, Dict[_Key, "Deque[nodes.Item]"]],
|
||||
) -> None:
|
||||
for scopenum in range(0, scopenum_function):
|
||||
for scopenum in range(scopenum_function):
|
||||
for key in argkeys_cache[scopenum].get(item, []):
|
||||
items_by_argkey[scopenum][key].appendleft(item)
|
||||
|
||||
@@ -377,10 +377,7 @@ def _fill_fixtures_impl(function: "Function") -> None:
|
||||
fm.session._setupstate.setup(function)
|
||||
request._fillfixtures()
|
||||
# Prune out funcargs for jstests.
|
||||
newfuncargs = {}
|
||||
for name in fi.argnames:
|
||||
newfuncargs[name] = function.funcargs[name]
|
||||
function.funcargs = newfuncargs
|
||||
function.funcargs = {name: function.funcargs[name] for name in fi.argnames}
|
||||
else:
|
||||
request._fillfixtures()
|
||||
|
||||
@@ -1382,7 +1379,8 @@ def yield_fixture(
|
||||
|
||||
@fixture(scope="session")
|
||||
def pytestconfig(request: FixtureRequest) -> Config:
|
||||
"""Session-scoped fixture that returns the :class:`_pytest.config.Config` object.
|
||||
"""Session-scoped fixture that returns the session's :class:`pytest.Config`
|
||||
object.
|
||||
|
||||
Example::
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ def pytest_cmdline_parse():
|
||||
|
||||
def showversion(config: Config) -> None:
|
||||
if config.option.version > 1:
|
||||
sys.stderr.write(
|
||||
sys.stdout.write(
|
||||
"This is pytest version {}, imported from {}\n".format(
|
||||
pytest.__version__, pytest.__file__
|
||||
)
|
||||
@@ -135,9 +135,9 @@ def showversion(config: Config) -> None:
|
||||
plugininfo = getpluginversioninfo(config)
|
||||
if plugininfo:
|
||||
for line in plugininfo:
|
||||
sys.stderr.write(line + "\n")
|
||||
sys.stdout.write(line + "\n")
|
||||
else:
|
||||
sys.stderr.write(f"pytest {pytest.__version__}\n")
|
||||
sys.stdout.write(f"pytest {pytest.__version__}\n")
|
||||
|
||||
|
||||
def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
|
||||
|
||||
@@ -56,7 +56,7 @@ def pytest_addhooks(pluginmanager: "PytestPluginManager") -> None:
|
||||
"""Called at plugin registration time to allow adding new hooks via a call to
|
||||
``pluginmanager.add_hookspecs(module_or_class, prefix)``.
|
||||
|
||||
:param _pytest.config.PytestPluginManager pluginmanager: pytest plugin manager.
|
||||
:param pytest.PytestPluginManager pluginmanager: The pytest plugin manager.
|
||||
|
||||
.. note::
|
||||
This hook is incompatible with ``hookwrapper=True``.
|
||||
@@ -70,7 +70,7 @@ def pytest_plugin_registered(
|
||||
"""A new pytest plugin got registered.
|
||||
|
||||
:param plugin: The plugin module or instance.
|
||||
:param _pytest.config.PytestPluginManager manager: pytest plugin manager.
|
||||
:param pytest.PytestPluginManager manager: pytest plugin manager.
|
||||
|
||||
.. note::
|
||||
This hook is incompatible with ``hookwrapper=True``.
|
||||
@@ -88,24 +88,24 @@ def pytest_addoption(parser: "Parser", pluginmanager: "PytestPluginManager") ->
|
||||
files situated at the tests root directory due to how pytest
|
||||
:ref:`discovers plugins during startup <pluginorder>`.
|
||||
|
||||
:param _pytest.config.argparsing.Parser parser:
|
||||
:param pytest.Parser parser:
|
||||
To add command line options, call
|
||||
:py:func:`parser.addoption(...) <_pytest.config.argparsing.Parser.addoption>`.
|
||||
:py:func:`parser.addoption(...) <pytest.Parser.addoption>`.
|
||||
To add ini-file values call :py:func:`parser.addini(...)
|
||||
<_pytest.config.argparsing.Parser.addini>`.
|
||||
<pytest.Parser.addini>`.
|
||||
|
||||
:param _pytest.config.PytestPluginManager pluginmanager:
|
||||
pytest plugin manager, which can be used to install :py:func:`hookspec`'s
|
||||
:param pytest.PytestPluginManager pluginmanager:
|
||||
The pytest plugin manager, which can be used to install :py:func:`hookspec`'s
|
||||
or :py:func:`hookimpl`'s and allow one plugin to call another plugin's hooks
|
||||
to change how command line options are added.
|
||||
|
||||
Options can later be accessed through the
|
||||
:py:class:`config <_pytest.config.Config>` object, respectively:
|
||||
:py:class:`config <pytest.Config>` object, respectively:
|
||||
|
||||
- :py:func:`config.getoption(name) <_pytest.config.Config.getoption>` to
|
||||
- :py:func:`config.getoption(name) <pytest.Config.getoption>` to
|
||||
retrieve the value of a command line option.
|
||||
|
||||
- :py:func:`config.getini(name) <_pytest.config.Config.getini>` to retrieve
|
||||
- :py:func:`config.getini(name) <pytest.Config.getini>` to retrieve
|
||||
a value read from an ini-style file.
|
||||
|
||||
The config object is passed around on many internal objects via the ``.config``
|
||||
@@ -129,7 +129,7 @@ def pytest_configure(config: "Config") -> None:
|
||||
.. note::
|
||||
This hook is incompatible with ``hookwrapper=True``.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
"""
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ def pytest_cmdline_parse(
|
||||
``plugins`` arg when using `pytest.main`_ to perform an in-process
|
||||
test run.
|
||||
|
||||
:param _pytest.config.PytestPluginManager pluginmanager: Pytest plugin manager.
|
||||
:param pytest.PytestPluginManager pluginmanager: The pytest plugin manager.
|
||||
:param List[str] args: List of arguments passed on the command line.
|
||||
"""
|
||||
|
||||
@@ -166,7 +166,7 @@ def pytest_cmdline_preparse(config: "Config", args: List[str]) -> None:
|
||||
.. note::
|
||||
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param List[str] args: Arguments passed on the command line.
|
||||
"""
|
||||
|
||||
@@ -178,7 +178,7 @@ def pytest_cmdline_main(config: "Config") -> Optional[Union["ExitCode", int]]:
|
||||
|
||||
Stops at first non-None result, see :ref:`firstresult`.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
"""
|
||||
|
||||
|
||||
@@ -191,9 +191,9 @@ def pytest_load_initial_conftests(
|
||||
.. note::
|
||||
This hook will not be called for ``conftest.py`` files, only for setuptools plugins.
|
||||
|
||||
:param _pytest.config.Config early_config: The pytest config object.
|
||||
:param pytest.Config early_config: The pytest config object.
|
||||
:param List[str] args: Arguments passed on the command line.
|
||||
:param _pytest.config.argparsing.Parser parser: To add command line options.
|
||||
:param pytest.Parser parser: To add command line options.
|
||||
"""
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ def pytest_collection_modifyitems(
|
||||
the items in-place.
|
||||
|
||||
:param pytest.Session session: The pytest session object.
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param List[pytest.Item] items: List of item objects.
|
||||
"""
|
||||
|
||||
@@ -271,7 +271,7 @@ def pytest_ignore_collect(
|
||||
|
||||
:param pathlib.Path fspath: The path to analyze.
|
||||
:param LEGACY_PATH path: The path to analyze.
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
|
||||
.. versionchanged:: 6.3.0
|
||||
The ``fspath`` parameter was added as a :class:`pathlib.Path`
|
||||
@@ -385,7 +385,7 @@ def pytest_make_parametrize_id(
|
||||
|
||||
Stops at first non-None result, see :ref:`firstresult`.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param val: The parametrized value.
|
||||
:param str argname: The automatic parameter name produced by pytest.
|
||||
"""
|
||||
@@ -609,7 +609,7 @@ def pytest_sessionfinish(
|
||||
def pytest_unconfigure(config: "Config") -> None:
|
||||
"""Called before test process is exited.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
"""
|
||||
|
||||
|
||||
@@ -628,7 +628,7 @@ def pytest_assertrepr_compare(
|
||||
*in* a string will be escaped. Note that all but the first line will
|
||||
be indented slightly, the intention is for the first line to be a summary.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
"""
|
||||
|
||||
|
||||
@@ -677,7 +677,7 @@ def pytest_report_header(
|
||||
) -> Union[str, List[str]]:
|
||||
"""Return a string or list of strings to be displayed as header info for terminal reporting.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param Path startpath: The starting dir.
|
||||
:param LEGACY_PATH startdir: The starting dir.
|
||||
|
||||
@@ -713,7 +713,7 @@ def pytest_report_collectionfinish(
|
||||
|
||||
.. versionadded:: 3.2
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param Path startpath: The starting path.
|
||||
:param LEGACY_PATH startdir: The starting dir.
|
||||
:param items: List of pytest items that are going to be executed; this list should not be modified.
|
||||
@@ -752,7 +752,7 @@ def pytest_report_teststatus(
|
||||
for example ``"rerun", "R", ("RERUN", {"yellow": True})``.
|
||||
|
||||
:param report: The report object whose status is to be returned.
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
|
||||
Stops at first non-None result, see :ref:`firstresult`.
|
||||
"""
|
||||
@@ -767,7 +767,7 @@ def pytest_terminal_summary(
|
||||
|
||||
:param _pytest.terminal.TerminalReporter terminalreporter: The internal terminal reporter object.
|
||||
:param int exitstatus: The exit status that will be reported back to the OS.
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
|
||||
.. versionadded:: 4.2
|
||||
The ``config`` parameter.
|
||||
@@ -857,7 +857,7 @@ def pytest_markeval_namespace(config: "Config") -> Dict[str, Any]:
|
||||
|
||||
.. versionadded:: 6.2
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:returns: A dictionary of additional globals to add.
|
||||
"""
|
||||
|
||||
@@ -909,7 +909,7 @@ def pytest_enter_pdb(config: "Config", pdb: "pdb.Pdb") -> None:
|
||||
Can be used by plugins to take special action just before the python
|
||||
debugger enters interactive mode.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param pdb.Pdb pdb: The Pdb instance.
|
||||
"""
|
||||
|
||||
@@ -920,6 +920,6 @@ def pytest_leave_pdb(config: "Config", pdb: "pdb.Pdb") -> None:
|
||||
Can be used by plugins to take special action just after the python
|
||||
debugger leaves interactive mode.
|
||||
|
||||
:param _pytest.config.Config config: The pytest config object.
|
||||
:param pytest.Config config: The pytest config object.
|
||||
:param pdb.Pdb pdb: The Pdb instance.
|
||||
"""
|
||||
|
||||
@@ -648,39 +648,39 @@ class LogXML:
|
||||
dirname = os.path.dirname(os.path.abspath(self.logfile))
|
||||
if not os.path.isdir(dirname):
|
||||
os.makedirs(dirname)
|
||||
logfile = open(self.logfile, "w", encoding="utf-8")
|
||||
suite_stop_time = timing.time()
|
||||
suite_time_delta = suite_stop_time - self.suite_start_time
|
||||
|
||||
numtests = (
|
||||
self.stats["passed"]
|
||||
+ self.stats["failure"]
|
||||
+ self.stats["skipped"]
|
||||
+ self.stats["error"]
|
||||
- self.cnt_double_fail_tests
|
||||
)
|
||||
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
|
||||
with open(self.logfile, "w", encoding="utf-8") as logfile:
|
||||
suite_stop_time = timing.time()
|
||||
suite_time_delta = suite_stop_time - self.suite_start_time
|
||||
|
||||
suite_node = ET.Element(
|
||||
"testsuite",
|
||||
name=self.suite_name,
|
||||
errors=str(self.stats["error"]),
|
||||
failures=str(self.stats["failure"]),
|
||||
skipped=str(self.stats["skipped"]),
|
||||
tests=str(numtests),
|
||||
time="%.3f" % suite_time_delta,
|
||||
timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(),
|
||||
hostname=platform.node(),
|
||||
)
|
||||
global_properties = self._get_global_properties_node()
|
||||
if global_properties is not None:
|
||||
suite_node.append(global_properties)
|
||||
for node_reporter in self.node_reporters_ordered:
|
||||
suite_node.append(node_reporter.to_xml())
|
||||
testsuites = ET.Element("testsuites")
|
||||
testsuites.append(suite_node)
|
||||
logfile.write(ET.tostring(testsuites, encoding="unicode"))
|
||||
logfile.close()
|
||||
numtests = (
|
||||
self.stats["passed"]
|
||||
+ self.stats["failure"]
|
||||
+ self.stats["skipped"]
|
||||
+ self.stats["error"]
|
||||
- self.cnt_double_fail_tests
|
||||
)
|
||||
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
|
||||
|
||||
suite_node = ET.Element(
|
||||
"testsuite",
|
||||
name=self.suite_name,
|
||||
errors=str(self.stats["error"]),
|
||||
failures=str(self.stats["failure"]),
|
||||
skipped=str(self.stats["skipped"]),
|
||||
tests=str(numtests),
|
||||
time="%.3f" % suite_time_delta,
|
||||
timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(),
|
||||
hostname=platform.node(),
|
||||
)
|
||||
global_properties = self._get_global_properties_node()
|
||||
if global_properties is not None:
|
||||
suite_node.append(global_properties)
|
||||
for node_reporter in self.node_reporters_ordered:
|
||||
suite_node.append(node_reporter.to_xml())
|
||||
testsuites = ET.Element("testsuites")
|
||||
testsuites.append(suite_node)
|
||||
logfile.write(ET.tostring(testsuites, encoding="unicode"))
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter: TerminalReporter) -> None:
|
||||
terminalreporter.write_sep("-", f"generated xml file: {self.logfile}")
|
||||
|
||||
@@ -59,7 +59,7 @@ class ColoredLevelFormatter(logging.Formatter):
|
||||
logging.DEBUG: {"purple"},
|
||||
logging.NOTSET: set(),
|
||||
}
|
||||
LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)")
|
||||
LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*(?:\.\d+)?s)")
|
||||
|
||||
def __init__(self, terminalwriter: TerminalWriter, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -451,7 +451,7 @@ class LogCaptureFixture:
|
||||
|
||||
@contextmanager
|
||||
def at_level(
|
||||
self, level: int, logger: Optional[str] = None
|
||||
self, level: Union[int, str], logger: Optional[str] = None
|
||||
) -> Generator[None, None, None]:
|
||||
"""Context manager that sets the level for capturing of logs. After
|
||||
the end of the 'with' statement the level is restored to its original
|
||||
@@ -626,7 +626,8 @@ class LoggingPlugin:
|
||||
finally:
|
||||
self.log_file_handler.release()
|
||||
if old_stream:
|
||||
old_stream.close()
|
||||
# https://github.com/python/typeshed/pull/5663
|
||||
old_stream.close() # type:ignore[attr-defined]
|
||||
|
||||
def _log_cli_enabled(self):
|
||||
"""Return whether live logging is enabled."""
|
||||
|
||||
@@ -241,10 +241,7 @@ def validate_basetemp(path: str) -> str:
|
||||
"""Return whether query is an ancestor of base."""
|
||||
if base == query:
|
||||
return True
|
||||
for parent in base.parents:
|
||||
if parent == query:
|
||||
return True
|
||||
return False
|
||||
return query in base.parents
|
||||
|
||||
# check if path is an ancestor of cwd
|
||||
if is_ancestor(Path.cwd(), Path(path).absolute()):
|
||||
@@ -487,7 +484,7 @@ class Session(nodes.FSCollector):
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config: Config) -> "Session":
|
||||
session: Session = cls._create(config)
|
||||
session: Session = cls._create(config=config)
|
||||
return session
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
||||
@@ -190,12 +190,12 @@ def deselect_by_keyword(items: "List[Item]", config: Config) -> None:
|
||||
return
|
||||
|
||||
if keywordexpr.startswith("-"):
|
||||
# To be removed in pytest 7.0.0.
|
||||
# To be removed in pytest 8.0.0.
|
||||
warnings.warn(MINUS_K_DASH, stacklevel=2)
|
||||
keywordexpr = "not " + keywordexpr[1:]
|
||||
selectuntil = False
|
||||
if keywordexpr[-1:] == ":":
|
||||
# To be removed in pytest 7.0.0.
|
||||
# To be removed in pytest 8.0.0.
|
||||
warnings.warn(MINUS_K_COLON, stacklevel=2)
|
||||
selectuntil = True
|
||||
keywordexpr = keywordexpr[:-1]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import os
|
||||
import warnings
|
||||
from inspect import signature
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import cast
|
||||
from typing import Iterable
|
||||
from typing import Iterator
|
||||
from typing import List
|
||||
@@ -34,6 +36,7 @@ from _pytest.outcomes import fail
|
||||
from _pytest.pathlib import absolutepath
|
||||
from _pytest.pathlib import commonpath
|
||||
from _pytest.store import Store
|
||||
from _pytest.warning_types import PytestWarning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# Imported here due to circular import.
|
||||
@@ -62,23 +65,33 @@ def iterparentnodeids(nodeid: str) -> Iterator[str]:
|
||||
"testing/code/test_excinfo.py::TestFormattedExcinfo"
|
||||
"testing/code/test_excinfo.py::TestFormattedExcinfo::test_repr_source"
|
||||
|
||||
Note that :: parts are only considered at the last / component.
|
||||
Note that / components are only considered until the first ::.
|
||||
"""
|
||||
pos = 0
|
||||
sep = SEP
|
||||
first_colons: Optional[int] = nodeid.find("::")
|
||||
if first_colons == -1:
|
||||
first_colons = None
|
||||
# The root Session node - always present.
|
||||
yield ""
|
||||
# Eagerly consume SEP parts until first colons.
|
||||
while True:
|
||||
at = nodeid.find(sep, pos)
|
||||
if at == -1 and sep == SEP:
|
||||
sep = "::"
|
||||
elif at == -1:
|
||||
if nodeid:
|
||||
yield nodeid
|
||||
at = nodeid.find(SEP, pos, first_colons)
|
||||
if at == -1:
|
||||
break
|
||||
else:
|
||||
if at:
|
||||
yield nodeid[:at]
|
||||
pos = at + len(sep)
|
||||
if at > 0:
|
||||
yield nodeid[:at]
|
||||
pos = at + len(SEP)
|
||||
# Eagerly consume :: parts.
|
||||
while True:
|
||||
at = nodeid.find("::", pos)
|
||||
if at == -1:
|
||||
break
|
||||
if at > 0:
|
||||
yield nodeid[:at]
|
||||
pos = at + len("::")
|
||||
# The node ID itself.
|
||||
if nodeid:
|
||||
yield nodeid
|
||||
|
||||
|
||||
def _imply_path(
|
||||
@@ -115,7 +128,20 @@ class NodeMeta(type):
|
||||
fail(msg, pytrace=False)
|
||||
|
||||
def _create(self, *k, **kw):
|
||||
return super().__call__(*k, **kw)
|
||||
try:
|
||||
return super().__call__(*k, **kw)
|
||||
except TypeError:
|
||||
sig = signature(getattr(self, "__init__"))
|
||||
known_kw = {k: v for k, v in kw.items() if k in sig.parameters}
|
||||
from .warning_types import PytestDeprecationWarning
|
||||
|
||||
warnings.warn(
|
||||
PytestDeprecationWarning(
|
||||
f"{self} is not using a cooperative constructor and only takes {set(known_kw)}"
|
||||
)
|
||||
)
|
||||
|
||||
return super().__call__(*k, **known_kw)
|
||||
|
||||
|
||||
class Node(metaclass=NodeMeta):
|
||||
@@ -529,26 +555,39 @@ def _check_initialpaths_for_relpath(session: "Session", path: Path) -> Optional[
|
||||
class FSCollector(Collector):
|
||||
def __init__(
|
||||
self,
|
||||
fspath: Optional[LEGACY_PATH],
|
||||
path: Optional[Path],
|
||||
parent=None,
|
||||
fspath: Optional[LEGACY_PATH] = None,
|
||||
path_or_parent: Optional[Union[Path, Node]] = None,
|
||||
path: Optional[Path] = None,
|
||||
name: Optional[str] = None,
|
||||
parent: Optional[Node] = None,
|
||||
config: Optional[Config] = None,
|
||||
session: Optional["Session"] = None,
|
||||
nodeid: Optional[str] = None,
|
||||
) -> None:
|
||||
if path_or_parent:
|
||||
if isinstance(path_or_parent, Node):
|
||||
assert parent is None
|
||||
parent = cast(FSCollector, path_or_parent)
|
||||
elif isinstance(path_or_parent, Path):
|
||||
assert path is None
|
||||
path = path_or_parent
|
||||
|
||||
path, fspath = _imply_path(path, fspath=fspath)
|
||||
name = path.name
|
||||
if parent is not None and parent.path != path:
|
||||
try:
|
||||
rel = path.relative_to(parent.path)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = str(rel)
|
||||
name = name.replace(os.sep, SEP)
|
||||
if name is None:
|
||||
name = path.name
|
||||
if parent is not None and parent.path != path:
|
||||
try:
|
||||
rel = path.relative_to(parent.path)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
name = str(rel)
|
||||
name = name.replace(os.sep, SEP)
|
||||
self.path = path
|
||||
|
||||
session = session or parent.session
|
||||
if session is None:
|
||||
assert parent is not None
|
||||
session = parent.session
|
||||
|
||||
if nodeid is None:
|
||||
try:
|
||||
@@ -560,7 +599,12 @@ class FSCollector(Collector):
|
||||
nodeid = nodeid.replace(os.sep, SEP)
|
||||
|
||||
super().__init__(
|
||||
name, parent, config, session, nodeid=nodeid, fspath=fspath, path=path
|
||||
name=name,
|
||||
parent=parent,
|
||||
config=config,
|
||||
session=session,
|
||||
nodeid=nodeid,
|
||||
path=path,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -600,6 +644,20 @@ class Item(Node):
|
||||
|
||||
nextitem = None
|
||||
|
||||
def __init_subclass__(cls) -> None:
|
||||
problems = ", ".join(
|
||||
base.__name__ for base in cls.__bases__ if issubclass(base, Collector)
|
||||
)
|
||||
if problems:
|
||||
warnings.warn(
|
||||
f"{cls.__name__} is an Item subclass and should not be a collector, "
|
||||
f"however its bases {problems} are collectors.\n"
|
||||
"Please split the Collectors and the Item into separate node types.\n"
|
||||
"Pytest Doc example: https://docs.pytest.org/en/latest/example/nonpython.html\n"
|
||||
"example pull request on a plugin: https://github.com/asmeurer/pytest-flakes/pull/40/",
|
||||
PytestWarning,
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
@@ -607,8 +665,16 @@ class Item(Node):
|
||||
config: Optional[Config] = None,
|
||||
session: Optional["Session"] = None,
|
||||
nodeid: Optional[str] = None,
|
||||
**kw,
|
||||
) -> None:
|
||||
super().__init__(name, parent, config, session, nodeid=nodeid)
|
||||
super().__init__(
|
||||
name=name,
|
||||
parent=parent,
|
||||
config=config,
|
||||
session=session,
|
||||
nodeid=nodeid,
|
||||
**kw,
|
||||
)
|
||||
self._report_sections: List[Tuple[str, str, str]] = []
|
||||
|
||||
#: A list of tuples (name, value) that holds user defined properties
|
||||
|
||||
@@ -954,7 +954,7 @@ class Pytester:
|
||||
) -> Optional[Union[Collector, Item]]:
|
||||
"""Return the collection node of a file.
|
||||
|
||||
:param _pytest.config.Config config:
|
||||
:param pytest.Config config:
|
||||
A pytest config.
|
||||
See :py:meth:`parseconfig` and :py:meth:`parseconfigure` for creating it.
|
||||
:param os.PathLike[str] arg:
|
||||
@@ -1186,7 +1186,7 @@ class Pytester:
|
||||
This invokes the pytest bootstrapping code in _pytest.config to create
|
||||
a new :py:class:`_pytest.core.PluginManager` and call the
|
||||
pytest_cmdline_parse hook to create a new
|
||||
:py:class:`_pytest.config.Config` instance.
|
||||
:py:class:`pytest.Config` instance.
|
||||
|
||||
If :py:attr:`plugins` has been populated they should be plugin modules
|
||||
to be registered with the PluginManager.
|
||||
@@ -1206,7 +1206,7 @@ class Pytester:
|
||||
def parseconfigure(self, *args: Union[str, "os.PathLike[str]"]) -> Config:
|
||||
"""Return a new pytest configured Config instance.
|
||||
|
||||
Returns a new :py:class:`_pytest.config.Config` instance like
|
||||
Returns a new :py:class:`pytest.Config` instance like
|
||||
:py:meth:`parseconfig`, but also calls the pytest_configure hook.
|
||||
"""
|
||||
config = self.parseconfig(*args)
|
||||
|
||||
@@ -970,7 +970,7 @@ class Metafunc:
|
||||
#: Access to the underlying :class:`_pytest.python.FunctionDefinition`.
|
||||
self.definition = definition
|
||||
|
||||
#: Access to the :class:`_pytest.config.Config` object for the test session.
|
||||
#: Access to the :class:`pytest.Config` object for the test session.
|
||||
self.config = config
|
||||
|
||||
#: The module object where the test function is defined in.
|
||||
@@ -1428,15 +1428,15 @@ def _show_fixtures_per_test(config: Config, session: Session) -> None:
|
||||
argname = fixture_def.argname
|
||||
if verbose <= 0 and argname.startswith("_"):
|
||||
return
|
||||
if verbose > 0:
|
||||
bestrel = get_best_relpath(fixture_def.func)
|
||||
funcargspec = f"{argname} -- {bestrel}"
|
||||
else:
|
||||
funcargspec = argname
|
||||
tw.line(funcargspec, green=True)
|
||||
bestrel = get_best_relpath(fixture_def.func)
|
||||
tw.write(f"{argname}", green=True)
|
||||
tw.write(f" -- {bestrel}", yellow=True)
|
||||
tw.write("\n")
|
||||
fixture_doc = inspect.getdoc(fixture_def.func)
|
||||
if fixture_doc:
|
||||
write_docstring(tw, fixture_doc)
|
||||
write_docstring(
|
||||
tw, fixture_doc.split("\n\n")[0] if verbose <= 0 else fixture_doc
|
||||
)
|
||||
else:
|
||||
tw.line(" no docstring available", red=True)
|
||||
|
||||
@@ -1508,18 +1508,17 @@ def _showfixtures_main(config: Config, session: Session) -> None:
|
||||
tw.line()
|
||||
tw.sep("-", f"fixtures defined from {module}")
|
||||
currentmodule = module
|
||||
if verbose <= 0 and argname[0] == "_":
|
||||
if verbose <= 0 and argname.startswith("_"):
|
||||
continue
|
||||
tw.write(argname, green=True)
|
||||
tw.write(f"{argname}", green=True)
|
||||
if fixturedef.scope != "function":
|
||||
tw.write(" [%s scope]" % fixturedef.scope, cyan=True)
|
||||
if verbose > 0:
|
||||
tw.write(" -- %s" % bestrel, yellow=True)
|
||||
tw.write(f" -- {bestrel}", yellow=True)
|
||||
tw.write("\n")
|
||||
loc = getlocation(fixturedef.func, str(curdir))
|
||||
doc = inspect.getdoc(fixturedef.func)
|
||||
if doc:
|
||||
write_docstring(tw, doc)
|
||||
write_docstring(tw, doc.split("\n\n")[0] if verbose <= 0 else doc)
|
||||
else:
|
||||
tw.line(f" {loc}: no docstring available", red=True)
|
||||
tw.line()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import math
|
||||
import pprint
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Mapping
|
||||
from collections.abc import Sized
|
||||
from decimal import Decimal
|
||||
from numbers import Complex
|
||||
@@ -10,9 +8,13 @@ from typing import Any
|
||||
from typing import Callable
|
||||
from typing import cast
|
||||
from typing import Generic
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Mapping
|
||||
from typing import Optional
|
||||
from typing import overload
|
||||
from typing import Pattern
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
from typing import Type
|
||||
from typing import TYPE_CHECKING
|
||||
@@ -38,6 +40,32 @@ def _non_numeric_type_error(value, at: Optional[str]) -> TypeError:
|
||||
)
|
||||
|
||||
|
||||
def _compare_approx(
|
||||
full_object: object,
|
||||
message_data: Sequence[Tuple[str, str, str]],
|
||||
number_of_elements: int,
|
||||
different_ids: Sequence[object],
|
||||
max_abs_diff: float,
|
||||
max_rel_diff: float,
|
||||
) -> List[str]:
|
||||
message_list = list(message_data)
|
||||
message_list.insert(0, ("Index", "Obtained", "Expected"))
|
||||
max_sizes = [0, 0, 0]
|
||||
for index, obtained, expected in message_list:
|
||||
max_sizes[0] = max(max_sizes[0], len(index))
|
||||
max_sizes[1] = max(max_sizes[1], len(obtained))
|
||||
max_sizes[2] = max(max_sizes[2], len(expected))
|
||||
explanation = [
|
||||
f"comparison failed. Mismatched elements: {len(different_ids)} / {number_of_elements}:",
|
||||
f"Max absolute difference: {max_abs_diff}",
|
||||
f"Max relative difference: {max_rel_diff}",
|
||||
] + [
|
||||
f"{indexes:<{max_sizes[0]}} | {obtained:<{max_sizes[1]}} | {expected:<{max_sizes[2]}}"
|
||||
for indexes, obtained, expected in message_list
|
||||
]
|
||||
return explanation
|
||||
|
||||
|
||||
# builtin pytest.approx helper
|
||||
|
||||
|
||||
@@ -60,6 +88,13 @@ class ApproxBase:
|
||||
def __repr__(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def _repr_compare(self, other_side: Any) -> List[str]:
|
||||
return [
|
||||
"comparison failed",
|
||||
f"Obtained: {other_side}",
|
||||
f"Expected: {self}",
|
||||
]
|
||||
|
||||
def __eq__(self, actual) -> bool:
|
||||
return all(
|
||||
a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual)
|
||||
@@ -95,7 +130,7 @@ class ApproxBase:
|
||||
|
||||
def _recursive_list_map(f, x):
|
||||
if isinstance(x, list):
|
||||
return list(_recursive_list_map(f, xi) for xi in x)
|
||||
return [_recursive_list_map(f, xi) for xi in x]
|
||||
else:
|
||||
return f(x)
|
||||
|
||||
@@ -107,6 +142,66 @@ class ApproxNumpy(ApproxBase):
|
||||
list_scalars = _recursive_list_map(self._approx_scalar, self.expected.tolist())
|
||||
return f"approx({list_scalars!r})"
|
||||
|
||||
def _repr_compare(self, other_side: "ndarray") -> List[str]:
|
||||
import itertools
|
||||
import math
|
||||
|
||||
def get_value_from_nested_list(
|
||||
nested_list: List[Any], nd_index: Tuple[Any, ...]
|
||||
) -> Any:
|
||||
"""
|
||||
Helper function to get the value out of a nested list, given an n-dimensional index.
|
||||
This mimics numpy's indexing, but for raw nested python lists.
|
||||
"""
|
||||
value: Any = nested_list
|
||||
for i in nd_index:
|
||||
value = value[i]
|
||||
return value
|
||||
|
||||
np_array_shape = self.expected.shape
|
||||
approx_side_as_list = _recursive_list_map(
|
||||
self._approx_scalar, self.expected.tolist()
|
||||
)
|
||||
|
||||
if np_array_shape != other_side.shape:
|
||||
return [
|
||||
"Impossible to compare arrays with different shapes.",
|
||||
f"Shapes: {np_array_shape} and {other_side.shape}",
|
||||
]
|
||||
|
||||
number_of_elements = self.expected.size
|
||||
max_abs_diff = -math.inf
|
||||
max_rel_diff = -math.inf
|
||||
different_ids = []
|
||||
for index in itertools.product(*(range(i) for i in np_array_shape)):
|
||||
approx_value = get_value_from_nested_list(approx_side_as_list, index)
|
||||
other_value = get_value_from_nested_list(other_side, index)
|
||||
if approx_value != other_value:
|
||||
abs_diff = abs(approx_value.expected - other_value)
|
||||
max_abs_diff = max(max_abs_diff, abs_diff)
|
||||
if other_value == 0.0:
|
||||
max_rel_diff = math.inf
|
||||
else:
|
||||
max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value))
|
||||
different_ids.append(index)
|
||||
|
||||
message_data = [
|
||||
(
|
||||
str(index),
|
||||
str(get_value_from_nested_list(other_side, index)),
|
||||
str(get_value_from_nested_list(approx_side_as_list, index)),
|
||||
)
|
||||
for index in different_ids
|
||||
]
|
||||
return _compare_approx(
|
||||
self.expected,
|
||||
message_data,
|
||||
number_of_elements,
|
||||
different_ids,
|
||||
max_abs_diff,
|
||||
max_rel_diff,
|
||||
)
|
||||
|
||||
def __eq__(self, actual) -> bool:
|
||||
import numpy as np
|
||||
|
||||
@@ -147,6 +242,44 @@ class ApproxMapping(ApproxBase):
|
||||
{k: self._approx_scalar(v) for k, v in self.expected.items()}
|
||||
)
|
||||
|
||||
def _repr_compare(self, other_side: Mapping[object, float]) -> List[str]:
|
||||
import math
|
||||
|
||||
approx_side_as_map = {
|
||||
k: self._approx_scalar(v) for k, v in self.expected.items()
|
||||
}
|
||||
|
||||
number_of_elements = len(approx_side_as_map)
|
||||
max_abs_diff = -math.inf
|
||||
max_rel_diff = -math.inf
|
||||
different_ids = []
|
||||
for (approx_key, approx_value), other_value in zip(
|
||||
approx_side_as_map.items(), other_side.values()
|
||||
):
|
||||
if approx_value != other_value:
|
||||
max_abs_diff = max(
|
||||
max_abs_diff, abs(approx_value.expected - other_value)
|
||||
)
|
||||
max_rel_diff = max(
|
||||
max_rel_diff,
|
||||
abs((approx_value.expected - other_value) / approx_value.expected),
|
||||
)
|
||||
different_ids.append(approx_key)
|
||||
|
||||
message_data = [
|
||||
(str(key), str(other_side[key]), str(approx_side_as_map[key]))
|
||||
for key in different_ids
|
||||
]
|
||||
|
||||
return _compare_approx(
|
||||
self.expected,
|
||||
message_data,
|
||||
number_of_elements,
|
||||
different_ids,
|
||||
max_abs_diff,
|
||||
max_rel_diff,
|
||||
)
|
||||
|
||||
def __eq__(self, actual) -> bool:
|
||||
try:
|
||||
if set(actual.keys()) != set(self.expected.keys()):
|
||||
@@ -179,6 +312,48 @@ class ApproxSequencelike(ApproxBase):
|
||||
seq_type(self._approx_scalar(x) for x in self.expected)
|
||||
)
|
||||
|
||||
def _repr_compare(self, other_side: Sequence[float]) -> List[str]:
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
if len(self.expected) != len(other_side):
|
||||
return [
|
||||
"Impossible to compare lists with different sizes.",
|
||||
f"Lengths: {len(self.expected)} and {len(other_side)}",
|
||||
]
|
||||
|
||||
approx_side_as_map = _recursive_list_map(self._approx_scalar, self.expected)
|
||||
|
||||
number_of_elements = len(approx_side_as_map)
|
||||
max_abs_diff = -math.inf
|
||||
max_rel_diff = -math.inf
|
||||
different_ids = []
|
||||
for i, (approx_value, other_value) in enumerate(
|
||||
zip(approx_side_as_map, other_side)
|
||||
):
|
||||
if approx_value != other_value:
|
||||
abs_diff = abs(approx_value.expected - other_value)
|
||||
max_abs_diff = max(max_abs_diff, abs_diff)
|
||||
if other_value == 0.0:
|
||||
max_rel_diff = np.inf
|
||||
else:
|
||||
max_rel_diff = max(max_rel_diff, abs_diff / abs(other_value))
|
||||
different_ids.append(i)
|
||||
|
||||
message_data = [
|
||||
(str(i), str(other_side[i]), str(approx_side_as_map[i]))
|
||||
for i in different_ids
|
||||
]
|
||||
|
||||
return _compare_approx(
|
||||
self.expected,
|
||||
message_data,
|
||||
number_of_elements,
|
||||
different_ids,
|
||||
max_abs_diff,
|
||||
max_rel_diff,
|
||||
)
|
||||
|
||||
def __eq__(self, actual) -> bool:
|
||||
try:
|
||||
if len(actual) != len(self.expected):
|
||||
@@ -212,7 +387,6 @@ class ApproxScalar(ApproxBase):
|
||||
|
||||
For example, ``1.0 ± 1e-6``, ``(3+4j) ± 5e-6 ∠ ±180°``.
|
||||
"""
|
||||
|
||||
# Don't show a tolerance for values that aren't compared using
|
||||
# tolerances, i.e. non-numerics and infinities. Need to call abs to
|
||||
# handle complex numbers, e.g. (inf + 1j).
|
||||
@@ -466,10 +640,9 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
|
||||
|
||||
- ``unittest.TestCase.assertAlmostEqual(a, b)``: True if ``a`` and ``b``
|
||||
are within an absolute tolerance of ``1e-7``. No relative tolerance is
|
||||
considered and the absolute tolerance cannot be changed, so this function
|
||||
is not appropriate for very large or very small numbers. Also, it's only
|
||||
available in subclasses of ``unittest.TestCase`` and it's ugly because it
|
||||
doesn't follow PEP8. `More information...`__
|
||||
considered , so this function is not appropriate for very large or very
|
||||
small numbers. Also, it's only available in subclasses of ``unittest.TestCase``
|
||||
and it's ugly because it doesn't follow PEP8. `More information...`__
|
||||
|
||||
__ https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertAlmostEqual
|
||||
|
||||
@@ -480,6 +653,14 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:
|
||||
special case that you explicitly specify an absolute tolerance but not a
|
||||
relative tolerance, only the absolute tolerance is considered.
|
||||
|
||||
.. note::
|
||||
|
||||
``approx`` can handle numpy arrays, but we recommend the
|
||||
specialised test helpers in `numpy.testing`__ if you need
|
||||
support for comparisons, NaNs, or ULP-based tolerances.
|
||||
|
||||
__ https://numpy.org/doc/stable/reference/routines.testing.html
|
||||
|
||||
.. warning::
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
|
||||
@@ -17,6 +17,7 @@ from typing import Union
|
||||
|
||||
from _pytest.compat import final
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.deprecated import WARNS_NONE_ARG
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.outcomes import fail
|
||||
|
||||
@@ -83,7 +84,7 @@ def deprecated_call(
|
||||
|
||||
@overload
|
||||
def warns(
|
||||
expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
|
||||
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = ...,
|
||||
*,
|
||||
match: Optional[Union[str, Pattern[str]]] = ...,
|
||||
) -> "WarningsChecker":
|
||||
@@ -92,7 +93,7 @@ def warns(
|
||||
|
||||
@overload
|
||||
def warns(
|
||||
expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
|
||||
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]],
|
||||
func: Callable[..., T],
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
@@ -101,7 +102,7 @@ def warns(
|
||||
|
||||
|
||||
def warns(
|
||||
expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
|
||||
expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
|
||||
*args: Any,
|
||||
match: Optional[Union[str, Pattern[str]]] = None,
|
||||
**kwargs: Any,
|
||||
@@ -232,7 +233,7 @@ class WarningsChecker(WarningsRecorder):
|
||||
self,
|
||||
expected_warning: Optional[
|
||||
Union[Type[Warning], Tuple[Type[Warning], ...]]
|
||||
] = None,
|
||||
] = Warning,
|
||||
match_expr: Optional[Union[str, Pattern[str]]] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
@@ -242,6 +243,7 @@ class WarningsChecker(WarningsRecorder):
|
||||
|
||||
msg = "exceptions must be derived from Warning, not %s"
|
||||
if expected_warning is None:
|
||||
warnings.warn(WARNS_NONE_ARG, stacklevel=4)
|
||||
expected_warning_tup = None
|
||||
elif isinstance(expected_warning, tuple):
|
||||
for exc in expected_warning:
|
||||
|
||||
@@ -669,10 +669,7 @@ class TerminalReporter:
|
||||
skipped = len(self.stats.get("skipped", []))
|
||||
deselected = len(self.stats.get("deselected", []))
|
||||
selected = self._numcollected - errors - skipped - deselected
|
||||
if final:
|
||||
line = "collected "
|
||||
else:
|
||||
line = "collecting "
|
||||
line = "collected " if final else "collecting "
|
||||
line += (
|
||||
str(self._numcollected) + " item" + ("" if self._numcollected == 1 else "s")
|
||||
)
|
||||
|
||||
@@ -61,10 +61,7 @@ def thread_exception_runtest_hook() -> Generator[None, None, None]:
|
||||
with catch_threading_exception() as cm:
|
||||
yield
|
||||
if cm.args:
|
||||
if cm.args.thread is not None:
|
||||
thread_name = cm.args.thread.name
|
||||
else:
|
||||
thread_name = "<unknown>"
|
||||
thread_name = "<unknown>" if cm.args.thread is None else cm.args.thread.name
|
||||
msg = f"Exception in thread {thread_name}\n\n"
|
||||
msg += "".join(
|
||||
traceback.format_exception(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Support for providing temporary directories to test functions."""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
@@ -130,9 +131,9 @@ class TempPathFactory:
|
||||
# Also, to keep things private, fixup any world-readable temp
|
||||
# rootdir's permissions. Historically 0o755 was used, so we can't
|
||||
# just error out on this, at least for a while.
|
||||
if hasattr(os, "getuid"):
|
||||
rootdir_stat = rootdir.stat()
|
||||
if sys.platform != "win32":
|
||||
uid = os.getuid()
|
||||
rootdir_stat = rootdir.stat()
|
||||
# getuid shouldn't fail, but cpython defines such a case.
|
||||
# Let's hope for the best.
|
||||
if uid != -1:
|
||||
|
||||
@@ -2,17 +2,22 @@
|
||||
"""pytest: unit and functional testing with Python."""
|
||||
from . import collect
|
||||
from _pytest import __version__
|
||||
from _pytest import version_tuple
|
||||
from _pytest._code import ExceptionInfo
|
||||
from _pytest.assertion import register_assert_rewrite
|
||||
from _pytest.cacheprovider import Cache
|
||||
from _pytest.capture import CaptureFixture
|
||||
from _pytest.config import cmdline
|
||||
from _pytest.config import Config
|
||||
from _pytest.config import console_main
|
||||
from _pytest.config import ExitCode
|
||||
from _pytest.config import hookimpl
|
||||
from _pytest.config import hookspec
|
||||
from _pytest.config import main
|
||||
from _pytest.config import PytestPluginManager
|
||||
from _pytest.config import UsageError
|
||||
from _pytest.config.argparsing import OptionGroup
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.debugging import pytestPDB as __pytestPDB
|
||||
from _pytest.fixtures import _fillfuncargs
|
||||
from _pytest.fixtures import fixture
|
||||
@@ -77,6 +82,7 @@ __all__ = [
|
||||
"cmdline",
|
||||
"collect",
|
||||
"Collector",
|
||||
"Config",
|
||||
"console_main",
|
||||
"deprecated_call",
|
||||
"exit",
|
||||
@@ -103,8 +109,10 @@ __all__ = [
|
||||
"Metafunc",
|
||||
"Module",
|
||||
"MonkeyPatch",
|
||||
"OptionGroup",
|
||||
"Package",
|
||||
"param",
|
||||
"Parser",
|
||||
"PytestAssertRewriteWarning",
|
||||
"PytestCacheWarning",
|
||||
"PytestCollectionWarning",
|
||||
@@ -112,6 +120,7 @@ __all__ = [
|
||||
"PytestDeprecationWarning",
|
||||
"PytestExperimentalApiWarning",
|
||||
"Pytester",
|
||||
"PytestPluginManager",
|
||||
"PytestUnhandledCoroutineWarning",
|
||||
"PytestUnhandledThreadExceptionWarning",
|
||||
"PytestUnknownMarkWarning",
|
||||
@@ -122,6 +131,7 @@ __all__ = [
|
||||
"Session",
|
||||
"set_trace",
|
||||
"skip",
|
||||
"version_tuple",
|
||||
"TempPathFactory",
|
||||
"Testdir",
|
||||
"TempdirFactory",
|
||||
|
||||
@@ -1173,7 +1173,7 @@ def test_usage_error_code(pytester: Pytester) -> None:
|
||||
assert result.ret == ExitCode.USAGE_ERROR
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning")
|
||||
def test_warn_on_async_function(pytester: Pytester) -> None:
|
||||
# In the below we .close() the coroutine only to avoid
|
||||
# "RuntimeWarning: coroutine 'test_2' was never awaited"
|
||||
@@ -1206,7 +1206,7 @@ def test_warn_on_async_function(pytester: Pytester) -> None:
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledCoroutineWarning")
|
||||
def test_warn_on_async_gen_function(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
test_async="""
|
||||
|
||||
@@ -178,3 +178,15 @@ def test_hookproxy_warnings_for_fspath(tmp_path, hooktype, request):
|
||||
assert l1 < record.lineno < l2
|
||||
|
||||
hooks.pytest_ignore_collect(config=request.config, fspath=tmp_path)
|
||||
|
||||
|
||||
def test_warns_none_is_deprecated():
|
||||
with pytest.warns(
|
||||
PytestDeprecationWarning,
|
||||
match=re.escape(
|
||||
"Passing None to catch any warning has been deprecated, pass no arguments instead:\n "
|
||||
"Replace pytest.warns(None) by simply pytest.warns()."
|
||||
),
|
||||
):
|
||||
with pytest.warns(None): # type: ignore[call-overload]
|
||||
pass
|
||||
|
||||
@@ -18,9 +18,32 @@ def test_coloredlogformatter() -> None:
|
||||
exc_info=None,
|
||||
)
|
||||
|
||||
class ColorConfig:
|
||||
class option:
|
||||
pass
|
||||
tw = TerminalWriter()
|
||||
tw.hasmarkup = True
|
||||
formatter = ColoredLevelFormatter(tw, logfmt)
|
||||
output = formatter.format(record)
|
||||
assert output == (
|
||||
"dummypath 10 \x1b[32mINFO \x1b[0m Test Message"
|
||||
)
|
||||
|
||||
tw.hasmarkup = False
|
||||
formatter = ColoredLevelFormatter(tw, logfmt)
|
||||
output = formatter.format(record)
|
||||
assert output == ("dummypath 10 INFO Test Message")
|
||||
|
||||
|
||||
def test_coloredlogformatter_with_width_precision() -> None:
|
||||
logfmt = "%(filename)-25s %(lineno)4d %(levelname)-8.8s %(message)s"
|
||||
|
||||
record = logging.LogRecord(
|
||||
name="dummy",
|
||||
level=logging.INFO,
|
||||
pathname="dummypath",
|
||||
lineno=10,
|
||||
msg="Test Message",
|
||||
args=(),
|
||||
exc_info=None,
|
||||
)
|
||||
|
||||
tw = TerminalWriter()
|
||||
tw.hasmarkup = True
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
anyio[curio,trio]==3.0.0
|
||||
django==3.2
|
||||
anyio[curio,trio]==3.2.1
|
||||
django==3.2.4
|
||||
pytest-asyncio==0.15.1
|
||||
pytest-bdd==4.0.2
|
||||
pytest-cov==2.11.1
|
||||
pytest-django==4.2.0
|
||||
pytest-cov==2.12.1
|
||||
pytest-django==4.4.0
|
||||
pytest-flakes==4.0.3
|
||||
pytest-html==3.1.1
|
||||
pytest-mock==3.6.0
|
||||
pytest-rerunfailures==9.1.1
|
||||
pytest-mock==3.6.1
|
||||
pytest-rerunfailures==10.0
|
||||
pytest-sugar==0.9.4
|
||||
pytest-trio==0.7.0
|
||||
pytest-twisted==1.13.2
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import operator
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from decimal import Decimal
|
||||
from fractions import Fraction
|
||||
from operator import eq
|
||||
@@ -43,7 +44,236 @@ def mocked_doctest_runner(monkeypatch):
|
||||
return MyDocTestRunner()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temporary_verbosity(config, verbosity=0):
|
||||
original_verbosity = config.getoption("verbose")
|
||||
config.option.verbose = verbosity
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
config.option.verbose = original_verbosity
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def assert_approx_raises_regex(pytestconfig):
|
||||
def do_assert(lhs, rhs, expected_message, verbosity_level=0):
|
||||
import re
|
||||
|
||||
with temporary_verbosity(pytestconfig, verbosity_level):
|
||||
with pytest.raises(AssertionError) as e:
|
||||
assert lhs == approx(rhs)
|
||||
|
||||
nl = "\n"
|
||||
obtained_message = str(e.value).splitlines()[1:]
|
||||
assert len(obtained_message) == len(expected_message), (
|
||||
"Regex message length doesn't match obtained.\n"
|
||||
"Obtained:\n"
|
||||
f"{nl.join(obtained_message)}\n\n"
|
||||
"Expected regex:\n"
|
||||
f"{nl.join(expected_message)}\n\n"
|
||||
)
|
||||
|
||||
for i, (obtained_line, expected_line) in enumerate(
|
||||
zip(obtained_message, expected_message)
|
||||
):
|
||||
regex = re.compile(expected_line)
|
||||
assert regex.match(obtained_line) is not None, (
|
||||
"Unexpected error message:\n"
|
||||
f"{nl.join(obtained_message)}\n\n"
|
||||
"Did not match regex:\n"
|
||||
f"{nl.join(expected_message)}\n\n"
|
||||
f"With verbosity level = {verbosity_level}, on line {i}"
|
||||
)
|
||||
|
||||
return do_assert
|
||||
|
||||
|
||||
SOME_FLOAT = r"[+-]?([0-9]*[.])?[0-9]+\s*"
|
||||
SOME_INT = r"[0-9]+\s*"
|
||||
|
||||
|
||||
class TestApprox:
|
||||
def test_error_messages(self, assert_approx_raises_regex):
|
||||
np = pytest.importorskip("numpy")
|
||||
|
||||
assert_approx_raises_regex(
|
||||
2.0,
|
||||
1.0,
|
||||
[
|
||||
" comparison failed",
|
||||
f" Obtained: {SOME_FLOAT}",
|
||||
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
assert_approx_raises_regex(
|
||||
{"a": 1.0, "b": 1000.0, "c": 1000000.0},
|
||||
{
|
||||
"a": 2.0,
|
||||
"b": 1000.0,
|
||||
"c": 3000000.0,
|
||||
},
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 2 / 3:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index \| Obtained\s+\| Expected ",
|
||||
rf" a \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" c \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
assert_approx_raises_regex(
|
||||
[1.0, 2.0, 3.0, 4.0],
|
||||
[1.0, 3.0, 3.0, 5.0],
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 2 / 4:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index \| Obtained\s+\| Expected ",
|
||||
rf" 1 \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" 3 \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
a = np.linspace(0, 100, 20)
|
||||
b = np.linspace(0, 100, 20)
|
||||
a[10] += 0.5
|
||||
assert_approx_raises_regex(
|
||||
a,
|
||||
b,
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 1 / 20:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index \| Obtained\s+\| Expected",
|
||||
rf" \(10,\) \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
assert_approx_raises_regex(
|
||||
np.array(
|
||||
[
|
||||
[[1.1987311, 12412342.3], [3.214143244, 1423412423415.677]],
|
||||
[[1, 2], [3, 219371297321973]],
|
||||
]
|
||||
),
|
||||
np.array(
|
||||
[
|
||||
[[1.12313, 12412342.3], [3.214143244, 534523542345.677]],
|
||||
[[1, 2], [3, 7]],
|
||||
]
|
||||
),
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 3 / 8:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index\s+\| Obtained\s+\| Expected\s+",
|
||||
rf" \(0, 0, 0\) \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" \(0, 1, 1\) \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" \(1, 1, 1\) \| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
# Specific test for comparison with 0.0 (relative diff will be 'inf')
|
||||
assert_approx_raises_regex(
|
||||
[0.0],
|
||||
[1.0],
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 1 / 1:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
r" Max relative difference: inf",
|
||||
r" Index \| Obtained\s+\| Expected ",
|
||||
rf"\s*0\s*\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
assert_approx_raises_regex(
|
||||
np.array([0.0]),
|
||||
np.array([1.0]),
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 1 / 1:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
r" Max relative difference: inf",
|
||||
r" Index \| Obtained\s+\| Expected ",
|
||||
rf"\s*\(0,\)\s*\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
)
|
||||
|
||||
def test_error_messages_invalid_args(self, assert_approx_raises_regex):
|
||||
np = pytest.importorskip("numpy")
|
||||
with pytest.raises(AssertionError) as e:
|
||||
assert np.array([[1.2, 3.4], [4.0, 5.0]]) == pytest.approx(
|
||||
np.array([[4.0], [5.0]])
|
||||
)
|
||||
message = "\n".join(str(e.value).split("\n")[1:])
|
||||
assert message == "\n".join(
|
||||
[
|
||||
" Impossible to compare arrays with different shapes.",
|
||||
" Shapes: (2, 1) and (2, 2)",
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(AssertionError) as e:
|
||||
assert [1.0, 2.0, 3.0] == pytest.approx([4.0, 5.0])
|
||||
message = "\n".join(str(e.value).split("\n")[1:])
|
||||
assert message == "\n".join(
|
||||
[
|
||||
" Impossible to compare lists with different sizes.",
|
||||
" Lengths: 2 and 3",
|
||||
]
|
||||
)
|
||||
|
||||
def test_error_messages_with_different_verbosity(self, assert_approx_raises_regex):
|
||||
np = pytest.importorskip("numpy")
|
||||
for v in [0, 1, 2]:
|
||||
# Verbosity level doesn't affect the error message for scalars
|
||||
assert_approx_raises_regex(
|
||||
2.0,
|
||||
1.0,
|
||||
[
|
||||
" comparison failed",
|
||||
f" Obtained: {SOME_FLOAT}",
|
||||
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
],
|
||||
verbosity_level=v,
|
||||
)
|
||||
|
||||
a = np.linspace(1, 101, 20)
|
||||
b = np.linspace(2, 102, 20)
|
||||
assert_approx_raises_regex(
|
||||
a,
|
||||
b,
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 20 / 20:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index \| Obtained\s+\| Expected",
|
||||
rf" \(0,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" \(1,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
|
||||
rf" \(2,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}...",
|
||||
"",
|
||||
rf"\s*...Full output truncated \({SOME_INT} lines hidden\), use '-vv' to show",
|
||||
],
|
||||
verbosity_level=0,
|
||||
)
|
||||
|
||||
assert_approx_raises_regex(
|
||||
a,
|
||||
b,
|
||||
[
|
||||
r" comparison failed. Mismatched elements: 20 / 20:",
|
||||
rf" Max absolute difference: {SOME_FLOAT}",
|
||||
rf" Max relative difference: {SOME_FLOAT}",
|
||||
r" Index \| Obtained\s+\| Expected",
|
||||
]
|
||||
+ [
|
||||
rf" \({i},\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}"
|
||||
for i in range(20)
|
||||
],
|
||||
verbosity_level=2,
|
||||
)
|
||||
|
||||
def test_repr_string(self):
|
||||
assert repr(approx(1.0)) == "1.0 ± 1.0e-06"
|
||||
assert repr(approx([1.0, 2.0])) == "approx([1.0 ± 1.0e-06, 2.0 ± 2.0e-06])"
|
||||
|
||||
@@ -1237,7 +1237,7 @@ def test_unorderable_types(pytester: Pytester) -> None:
|
||||
assert result.ret == ExitCode.NO_TESTS_COLLECTED
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestCollectionWarning")
|
||||
def test_dont_collect_non_function_callable(pytester: Pytester) -> None:
|
||||
"""Test for issue https://github.com/pytest-dev/pytest/issues/331
|
||||
|
||||
|
||||
@@ -3334,9 +3334,9 @@ class TestShowFixtures:
|
||||
result = pytester.runpytest("--fixtures")
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"tmp_path_factory [[]session scope[]]",
|
||||
"tmp_path_factory [[]session scope[]] -- *tmpdir.py*",
|
||||
"*for the test session*",
|
||||
"tmp_path",
|
||||
"tmp_path -- *",
|
||||
"*temporary directory*",
|
||||
]
|
||||
)
|
||||
@@ -3367,9 +3367,9 @@ class TestShowFixtures:
|
||||
result = pytester.runpytest("--fixtures", p)
|
||||
result.stdout.fnmatch_lines(
|
||||
"""
|
||||
*tmp_path
|
||||
*tmp_path -- *
|
||||
*fixtures defined from*
|
||||
*arg1*
|
||||
*arg1 -- test_show_fixtures_testmodule.py:6*
|
||||
*hello world*
|
||||
"""
|
||||
)
|
||||
@@ -3429,10 +3429,10 @@ class TestShowFixtures:
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
* fixtures defined from test_show_fixtures_trimmed_doc *
|
||||
arg2
|
||||
arg2 -- test_show_fixtures_trimmed_doc.py:10
|
||||
line1
|
||||
line2
|
||||
arg1
|
||||
arg1 -- test_show_fixtures_trimmed_doc.py:3
|
||||
line1
|
||||
line2
|
||||
"""
|
||||
@@ -3458,7 +3458,7 @@ class TestShowFixtures:
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
* fixtures defined from test_show_fixtures_indented_doc *
|
||||
fixture1
|
||||
fixture1 -- test_show_fixtures_indented_doc.py:3
|
||||
line1
|
||||
indented line
|
||||
"""
|
||||
@@ -3486,7 +3486,7 @@ class TestShowFixtures:
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
* fixtures defined from test_show_fixtures_indented_doc_first_line_unindented *
|
||||
fixture1
|
||||
fixture1 -- test_show_fixtures_indented_doc_first_line_unindented.py:3
|
||||
line1
|
||||
line2
|
||||
indented line
|
||||
@@ -3514,7 +3514,7 @@ class TestShowFixtures:
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
* fixtures defined from test_show_fixtures_indented_in_class *
|
||||
fixture1
|
||||
fixture1 -- test_show_fixtures_indented_in_class.py:4
|
||||
line1
|
||||
line2
|
||||
indented line
|
||||
@@ -3554,11 +3554,11 @@ class TestShowFixtures:
|
||||
result.stdout.fnmatch_lines(
|
||||
"""
|
||||
* fixtures defined from test_a *
|
||||
fix_a
|
||||
fix_a -- test_a.py:4
|
||||
Fixture A
|
||||
|
||||
* fixtures defined from test_b *
|
||||
fix_b
|
||||
fix_b -- test_b.py:4
|
||||
Fixture B
|
||||
"""
|
||||
)
|
||||
@@ -3594,11 +3594,11 @@ class TestShowFixtures:
|
||||
result.stdout.fnmatch_lines(
|
||||
"""
|
||||
* fixtures defined from conftest *
|
||||
arg1
|
||||
arg1 -- conftest.py:3
|
||||
Hello World in conftest.py
|
||||
|
||||
* fixtures defined from test_show_fixtures_with_same_name *
|
||||
arg1
|
||||
arg1 -- test_show_fixtures_with_same_name.py:3
|
||||
Hi from test module
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -448,7 +448,10 @@ class TestMetafunc:
|
||||
enum = pytest.importorskip("enum")
|
||||
e = enum.Enum("Foo", "one, two")
|
||||
result = idmaker(("a", "b"), [pytest.param(e.one, e.two)])
|
||||
assert result == ["Foo.one-Foo.two"]
|
||||
if sys.version_info[:2] >= (3, 10):
|
||||
assert result == ["one-two"]
|
||||
else:
|
||||
assert result == ["Foo.one-Foo.two"]
|
||||
|
||||
def test_idmaker_idfn(self) -> None:
|
||||
"""#351"""
|
||||
|
||||
@@ -29,7 +29,7 @@ def test_fixtures_in_module(pytester: Pytester) -> None:
|
||||
[
|
||||
"*fixtures used by test_arg1*",
|
||||
"*(test_fixtures_in_module.py:9)*",
|
||||
"arg1",
|
||||
"arg1 -- test_fixtures_in_module.py:6",
|
||||
" arg1 docstring",
|
||||
]
|
||||
)
|
||||
@@ -68,17 +68,16 @@ def test_fixtures_in_conftest(pytester: Pytester) -> None:
|
||||
[
|
||||
"*fixtures used by test_arg2*",
|
||||
"*(test_fixtures_in_conftest.py:2)*",
|
||||
"arg2",
|
||||
"arg2 -- conftest.py:6",
|
||||
" arg2 docstring",
|
||||
"*fixtures used by test_arg3*",
|
||||
"*(test_fixtures_in_conftest.py:4)*",
|
||||
"arg1",
|
||||
"arg1 -- conftest.py:3",
|
||||
" arg1 docstring",
|
||||
"arg2",
|
||||
"arg2 -- conftest.py:6",
|
||||
" arg2 docstring",
|
||||
"arg3",
|
||||
"arg3 -- conftest.py:9",
|
||||
" arg3",
|
||||
" docstring",
|
||||
]
|
||||
)
|
||||
|
||||
@@ -112,9 +111,9 @@ def test_should_show_fixtures_used_by_test(pytester: Pytester) -> None:
|
||||
[
|
||||
"*fixtures used by test_args*",
|
||||
"*(test_should_show_fixtures_used_by_test.py:6)*",
|
||||
"arg1",
|
||||
"arg1 -- test_should_show_fixtures_used_by_test.py:3",
|
||||
" arg1 from testmodule",
|
||||
"arg2",
|
||||
"arg2 -- conftest.py:6",
|
||||
" arg2 from conftest",
|
||||
]
|
||||
)
|
||||
@@ -181,3 +180,75 @@ def test_doctest_items(pytester: Pytester) -> None:
|
||||
assert result.ret == 0
|
||||
|
||||
result.stdout.fnmatch_lines(["*collected 2 items*"])
|
||||
|
||||
|
||||
def test_multiline_docstring_in_module(pytester: Pytester) -> None:
|
||||
p = pytester.makepyfile(
|
||||
'''
|
||||
import pytest
|
||||
@pytest.fixture
|
||||
def arg1():
|
||||
"""Docstring content that spans across multiple lines,
|
||||
through second line,
|
||||
and through third line.
|
||||
|
||||
Docstring content that extends into a second paragraph.
|
||||
|
||||
Docstring content that extends into a third paragraph.
|
||||
"""
|
||||
def test_arg1(arg1):
|
||||
pass
|
||||
'''
|
||||
)
|
||||
|
||||
result = pytester.runpytest("--fixtures-per-test", p)
|
||||
assert result.ret == 0
|
||||
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"*fixtures used by test_arg1*",
|
||||
"*(test_multiline_docstring_in_module.py:13)*",
|
||||
"arg1 -- test_multiline_docstring_in_module.py:3",
|
||||
" Docstring content that spans across multiple lines,",
|
||||
" through second line,",
|
||||
" and through third line.",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def test_verbose_include_multiline_docstring(pytester: Pytester) -> None:
|
||||
p = pytester.makepyfile(
|
||||
'''
|
||||
import pytest
|
||||
@pytest.fixture
|
||||
def arg1():
|
||||
"""Docstring content that spans across multiple lines,
|
||||
through second line,
|
||||
and through third line.
|
||||
|
||||
Docstring content that extends into a second paragraph.
|
||||
|
||||
Docstring content that extends into a third paragraph.
|
||||
"""
|
||||
def test_arg1(arg1):
|
||||
pass
|
||||
'''
|
||||
)
|
||||
|
||||
result = pytester.runpytest("--fixtures-per-test", "-v", p)
|
||||
assert result.ret == 0
|
||||
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"*fixtures used by test_arg1*",
|
||||
"*(test_verbose_include_multiline_docstring.py:13)*",
|
||||
"arg1 -- test_verbose_include_multiline_docstring.py:3",
|
||||
" Docstring content that spans across multiple lines,",
|
||||
" through second line,",
|
||||
" and through third line.",
|
||||
" ",
|
||||
" Docstring content that extends into a second paragraph.",
|
||||
" ",
|
||||
" Docstring content that extends into a third paragraph.",
|
||||
]
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Generator
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
@@ -44,52 +44,54 @@ class TestNewAPI:
|
||||
assert cache is not None
|
||||
cache.set("test/broken", [])
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="no chmod on windows")
|
||||
@pytest.fixture
|
||||
def unwritable_cache_dir(self, pytester: Pytester) -> Generator[Path, None, None]:
|
||||
cache_dir = pytester.path.joinpath(".pytest_cache")
|
||||
cache_dir.mkdir()
|
||||
mode = cache_dir.stat().st_mode
|
||||
cache_dir.chmod(0)
|
||||
if os.access(cache_dir, os.W_OK):
|
||||
pytest.skip("Failed to make cache dir unwritable")
|
||||
|
||||
yield cache_dir
|
||||
cache_dir.chmod(mode)
|
||||
|
||||
@pytest.mark.filterwarnings(
|
||||
"ignore:could not create cache path:pytest.PytestWarning"
|
||||
)
|
||||
def test_cache_writefail_permissions(self, pytester: Pytester) -> None:
|
||||
def test_cache_writefail_permissions(
|
||||
self, unwritable_cache_dir: Path, pytester: Pytester
|
||||
) -> None:
|
||||
pytester.makeini("[pytest]")
|
||||
cache_dir = pytester.path.joinpath(".pytest_cache")
|
||||
cache_dir.mkdir()
|
||||
mode = cache_dir.stat().st_mode
|
||||
cache_dir.chmod(0)
|
||||
try:
|
||||
config = pytester.parseconfigure()
|
||||
cache = config.cache
|
||||
assert cache is not None
|
||||
cache.set("test/broken", [])
|
||||
finally:
|
||||
cache_dir.chmod(mode)
|
||||
config = pytester.parseconfigure()
|
||||
cache = config.cache
|
||||
assert cache is not None
|
||||
cache.set("test/broken", [])
|
||||
|
||||
@pytest.mark.skipif(sys.platform.startswith("win"), reason="no chmod on windows")
|
||||
@pytest.mark.filterwarnings("default")
|
||||
def test_cache_failure_warns(
|
||||
self, pytester: Pytester, monkeypatch: MonkeyPatch
|
||||
self,
|
||||
pytester: Pytester,
|
||||
monkeypatch: MonkeyPatch,
|
||||
unwritable_cache_dir: Path,
|
||||
) -> None:
|
||||
monkeypatch.setenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", "1")
|
||||
cache_dir = pytester.path.joinpath(".pytest_cache")
|
||||
cache_dir.mkdir()
|
||||
mode = cache_dir.stat().st_mode
|
||||
cache_dir.chmod(0)
|
||||
try:
|
||||
pytester.makepyfile("def test_error(): raise Exception")
|
||||
result = pytester.runpytest()
|
||||
assert result.ret == 1
|
||||
# warnings from nodeids, lastfailed, and stepwise
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
# Validate location/stacklevel of warning from cacheprovider.
|
||||
"*= warnings summary =*",
|
||||
"*/cacheprovider.py:*",
|
||||
" */cacheprovider.py:*: PytestCacheWarning: could not create cache path "
|
||||
"{}/v/cache/nodeids".format(cache_dir),
|
||||
' config.cache.set("cache/nodeids", sorted(self.cached_nodeids))',
|
||||
"*1 failed, 3 warnings in*",
|
||||
]
|
||||
)
|
||||
finally:
|
||||
cache_dir.chmod(mode)
|
||||
|
||||
pytester.makepyfile("def test_error(): raise Exception")
|
||||
result = pytester.runpytest()
|
||||
assert result.ret == 1
|
||||
# warnings from nodeids, lastfailed, and stepwise
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
# Validate location/stacklevel of warning from cacheprovider.
|
||||
"*= warnings summary =*",
|
||||
"*/cacheprovider.py:*",
|
||||
" */cacheprovider.py:*: PytestCacheWarning: could not create cache path "
|
||||
f"{unwritable_cache_dir}/v/cache/nodeids",
|
||||
' config.cache.set("cache/nodeids", sorted(self.cached_nodeids))',
|
||||
"*1 failed, 3 warnings in*",
|
||||
]
|
||||
)
|
||||
|
||||
def test_config_cache(self, pytester: Pytester) -> None:
|
||||
pytester.makeconftest(
|
||||
|
||||
@@ -1225,7 +1225,7 @@ def test_collect_symlink_dir(pytester: Pytester) -> None:
|
||||
"""A symlinked directory is collected."""
|
||||
dir = pytester.mkdir("dir")
|
||||
dir.joinpath("test_it.py").write_text("def test_it(): pass", "utf-8")
|
||||
pytester.path.joinpath("symlink_dir").symlink_to(dir)
|
||||
symlink_or_skip(pytester.path.joinpath("symlink_dir"), dir)
|
||||
result = pytester.runpytest()
|
||||
result.assert_outcomes(passed=2)
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ class TestParseIni:
|
||||
result = pytester.runpytest()
|
||||
result.stdout.no_fnmatch_line("*PytestConfigWarning*")
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestConfigWarning")
|
||||
def test_disable_warnings_plugin_disables_config_warnings(
|
||||
self, pytester: Pytester
|
||||
) -> None:
|
||||
@@ -595,14 +595,14 @@ class TestConfigAPI:
|
||||
def test_getconftest_pathlist(self, pytester: Pytester, tmp_path: Path) -> None:
|
||||
somepath = tmp_path.joinpath("x", "y", "z")
|
||||
p = tmp_path.joinpath("conftest.py")
|
||||
p.write_text(f"pathlist = ['.', {str(somepath)!r}]")
|
||||
p.write_text(f"mylist = {['.', os.fspath(somepath)]}")
|
||||
config = pytester.parseconfigure(p)
|
||||
assert (
|
||||
config._getconftest_pathlist("notexist", path=tmp_path, rootpath=tmp_path)
|
||||
is None
|
||||
)
|
||||
pl = (
|
||||
config._getconftest_pathlist("pathlist", path=tmp_path, rootpath=tmp_path)
|
||||
config._getconftest_pathlist("mylist", path=tmp_path, rootpath=tmp_path)
|
||||
or []
|
||||
)
|
||||
print(pl)
|
||||
@@ -634,41 +634,37 @@ class TestConfigAPI:
|
||||
assert val == "hello"
|
||||
pytest.raises(ValueError, config.getini, "other")
|
||||
|
||||
def make_conftest_for_pathlist(self, pytester: Pytester) -> None:
|
||||
@pytest.mark.parametrize("config_type", ["ini", "pyproject"])
|
||||
@pytest.mark.parametrize("ini_type", ["paths", "pathlist"])
|
||||
def test_addini_paths(
|
||||
self, pytester: Pytester, config_type: str, ini_type: str
|
||||
) -> None:
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
f"""
|
||||
def pytest_addoption(parser):
|
||||
parser.addini("paths", "my new ini value", type="pathlist")
|
||||
parser.addini("paths", "my new ini value", type="{ini_type}")
|
||||
parser.addini("abc", "abc value")
|
||||
"""
|
||||
)
|
||||
|
||||
def test_addini_pathlist_ini_files(self, pytester: Pytester) -> None:
|
||||
self.make_conftest_for_pathlist(pytester)
|
||||
p = pytester.makeini(
|
||||
if config_type == "ini":
|
||||
inipath = pytester.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
paths=hello world/sub.py
|
||||
"""
|
||||
[pytest]
|
||||
paths=hello world/sub.py
|
||||
"""
|
||||
)
|
||||
self.check_config_pathlist(pytester, p)
|
||||
|
||||
def test_addini_pathlist_pyproject_toml(self, pytester: Pytester) -> None:
|
||||
self.make_conftest_for_pathlist(pytester)
|
||||
p = pytester.makepyprojecttoml(
|
||||
)
|
||||
elif config_type == "pyproject":
|
||||
inipath = pytester.makepyprojecttoml(
|
||||
"""
|
||||
[tool.pytest.ini_options]
|
||||
paths=["hello", "world/sub.py"]
|
||||
"""
|
||||
[tool.pytest.ini_options]
|
||||
paths=["hello", "world/sub.py"]
|
||||
"""
|
||||
)
|
||||
self.check_config_pathlist(pytester, p)
|
||||
|
||||
def check_config_pathlist(self, pytester: Pytester, config_path: Path) -> None:
|
||||
)
|
||||
config = pytester.parseconfig()
|
||||
values = config.getini("paths")
|
||||
assert len(values) == 2
|
||||
assert values[0] == config_path.parent.joinpath("hello")
|
||||
assert values[1] == config_path.parent.joinpath("world/sub.py")
|
||||
assert values[0] == inipath.parent.joinpath("hello")
|
||||
assert values[1] == inipath.parent.joinpath("world/sub.py")
|
||||
pytest.raises(ValueError, config.getini, "other")
|
||||
|
||||
def make_conftest_for_args(self, pytester: Pytester) -> None:
|
||||
@@ -1519,11 +1515,12 @@ class TestOverrideIniArgs:
|
||||
assert result.ret == 0
|
||||
result.stdout.fnmatch_lines(["custom_option:3.0"])
|
||||
|
||||
def test_override_ini_pathlist(self, pytester: Pytester) -> None:
|
||||
@pytest.mark.parametrize("ini_type", ["paths", "pathlist"])
|
||||
def test_override_ini_paths(self, pytester: Pytester, ini_type: str) -> None:
|
||||
pytester.makeconftest(
|
||||
"""
|
||||
f"""
|
||||
def pytest_addoption(parser):
|
||||
parser.addini("paths", "my new ini value", type="pathlist")"""
|
||||
parser.addini("paths", "my new ini value", type="{ini_type}")"""
|
||||
)
|
||||
pytester.makeini(
|
||||
"""
|
||||
@@ -1531,12 +1528,16 @@ class TestOverrideIniArgs:
|
||||
paths=blah.py"""
|
||||
)
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
def test_pathlist(pytestconfig):
|
||||
rf"""
|
||||
def test_overriden(pytestconfig):
|
||||
config_paths = pytestconfig.getini("paths")
|
||||
print(config_paths)
|
||||
for cpf in config_paths:
|
||||
print('\\nuser_path:%s' % cpf.basename)"""
|
||||
if "{ini_type}" == "pathlist":
|
||||
print('\nuser_path:%s' % cpf.basename)
|
||||
else:
|
||||
print('\nuser_path:%s' % cpf.name)
|
||||
"""
|
||||
)
|
||||
result = pytester.runpytest(
|
||||
"--override-ini", "paths=foo/bar1.py foo/bar2.py", "-s"
|
||||
@@ -1755,7 +1756,7 @@ def test_help_and_version_after_argument_error(pytester: Pytester) -> None:
|
||||
assert result.ret == ExitCode.USAGE_ERROR
|
||||
|
||||
result = pytester.runpytest("--version")
|
||||
result.stderr.fnmatch_lines([f"pytest {pytest.__version__}"])
|
||||
result.stdout.fnmatch_lines([f"pytest {pytest.__version__}"])
|
||||
assert result.ret == ExitCode.USAGE_ERROR
|
||||
|
||||
|
||||
|
||||
@@ -7,16 +7,22 @@ def test_version_verbose(pytester: Pytester, pytestconfig, monkeypatch) -> None:
|
||||
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
|
||||
result = pytester.runpytest("--version", "--version")
|
||||
assert result.ret == 0
|
||||
result.stderr.fnmatch_lines([f"*pytest*{pytest.__version__}*imported from*"])
|
||||
result.stdout.fnmatch_lines([f"*pytest*{pytest.__version__}*imported from*"])
|
||||
if pytestconfig.pluginmanager.list_plugin_distinfo():
|
||||
result.stderr.fnmatch_lines(["*setuptools registered plugins:", "*at*"])
|
||||
result.stdout.fnmatch_lines(["*setuptools registered plugins:", "*at*"])
|
||||
|
||||
|
||||
def test_version_less_verbose(pytester: Pytester, pytestconfig, monkeypatch) -> None:
|
||||
monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD")
|
||||
result = pytester.runpytest("--version")
|
||||
assert result.ret == 0
|
||||
result.stderr.fnmatch_lines([f"pytest {pytest.__version__}"])
|
||||
result.stdout.fnmatch_lines([f"pytest {pytest.__version__}"])
|
||||
|
||||
|
||||
def test_versions():
|
||||
"""Regression check for the public version attributes in pytest."""
|
||||
assert isinstance(pytest.__version__, str)
|
||||
assert isinstance(pytest.version_tuple, tuple)
|
||||
|
||||
|
||||
def test_help(pytester: Pytester) -> None:
|
||||
|
||||
@@ -1388,7 +1388,7 @@ def test_runs_twice(pytester: Pytester, run_and_parse: RunAndParse) -> None:
|
||||
|
||||
result, dom = run_and_parse(f, f)
|
||||
result.stdout.no_fnmatch_line("*INTERNALERROR*")
|
||||
first, second = [x["classname"] for x in dom.find_by_tag("testcase")]
|
||||
first, second = (x["classname"] for x in dom.find_by_tag("testcase"))
|
||||
assert first == second
|
||||
|
||||
|
||||
@@ -1406,7 +1406,7 @@ def test_runs_twice_xdist(
|
||||
|
||||
result, dom = run_and_parse(f, "--dist", "each", "--tx", "2*popen")
|
||||
result.stdout.no_fnmatch_line("*INTERNALERROR*")
|
||||
first, second = [x["classname"] for x in dom.find_by_tag("testcase")]
|
||||
first, second = (x["classname"] for x in dom.find_by_tag("testcase"))
|
||||
assert first == second
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from typing import Type
|
||||
|
||||
import pytest
|
||||
from _pytest import nodes
|
||||
from _pytest.compat import legacy_path
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.warning_types import PytestWarning
|
||||
|
||||
@@ -18,11 +19,13 @@ from _pytest.warning_types import PytestWarning
|
||||
("a/b/c", ["", "a", "a/b", "a/b/c"]),
|
||||
("a/bbb/c::D", ["", "a", "a/bbb", "a/bbb/c", "a/bbb/c::D"]),
|
||||
("a/b/c::D::eee", ["", "a", "a/b", "a/b/c", "a/b/c::D", "a/b/c::D::eee"]),
|
||||
# :: considered only at the last component.
|
||||
("::xx", ["", "::xx"]),
|
||||
("a/b/c::D/d::e", ["", "a", "a/b", "a/b/c::D", "a/b/c::D/d", "a/b/c::D/d::e"]),
|
||||
# / only considered until first ::
|
||||
("a/b/c::D/d::e", ["", "a", "a/b", "a/b/c", "a/b/c::D/d", "a/b/c::D/d::e"]),
|
||||
# : alone is not a separator.
|
||||
("a/b::D:e:f::g", ["", "a", "a/b", "a/b::D:e:f", "a/b::D:e:f::g"]),
|
||||
# / not considered if a part of a test name
|
||||
("a/b::c/d::e[/test]", ["", "a", "a/b", "a/b::c/d", "a/b::c/d::e[/test]"]),
|
||||
),
|
||||
)
|
||||
def test_iterparentnodeids(nodeid: str, expected: List[str]) -> None:
|
||||
@@ -37,6 +40,36 @@ def test_node_from_parent_disallowed_arguments() -> None:
|
||||
nodes.Node.from_parent(None, config=None) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_subclassing_both_item_and_collector_deprecated(
|
||||
request, tmp_path: Path
|
||||
) -> None:
|
||||
"""
|
||||
Verifies we warn on diamond inheritance
|
||||
as well as correctly managing legacy inheritance ctors with missing args
|
||||
as found in plugins
|
||||
"""
|
||||
|
||||
with pytest.warns(
|
||||
PytestWarning,
|
||||
match=(
|
||||
"(?m)SoWrong is an Item subclass and should not be a collector, however its bases File are collectors.\n"
|
||||
"Please split the Collectors and the Item into separate node types.\n.*"
|
||||
),
|
||||
):
|
||||
|
||||
class SoWrong(nodes.File, nodes.Item):
|
||||
def __init__(self, fspath, parent):
|
||||
"""Legacy ctor with legacy call # don't wana see"""
|
||||
super().__init__(fspath, parent)
|
||||
|
||||
with pytest.warns(
|
||||
PytestWarning, match=".*SoWrong.* not using a cooperative constructor.*"
|
||||
):
|
||||
SoWrong.from_parent(
|
||||
request.session, fspath=legacy_path(tmp_path / "broken.txt")
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"warn_type, msg", [(DeprecationWarning, "deprecated"), (PytestWarning, "pytest")]
|
||||
)
|
||||
@@ -86,7 +119,7 @@ def test__check_initialpaths_for_relpath() -> None:
|
||||
|
||||
assert nodes._check_initialpaths_for_relpath(session, sub) == "file"
|
||||
|
||||
outside = Path("/outside")
|
||||
outside = Path("/outside-this-does-not-exist")
|
||||
assert nodes._check_initialpaths_for_relpath(session, outside) is None
|
||||
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ from _pytest.pytester import Pytester
|
||||
|
||||
@pytest.fixture
|
||||
def parser() -> parseopt.Parser:
|
||||
return parseopt.Parser()
|
||||
return parseopt.Parser(_ispytest=True)
|
||||
|
||||
|
||||
class TestParser:
|
||||
def test_no_help_by_default(self) -> None:
|
||||
parser = parseopt.Parser(usage="xyz")
|
||||
parser = parseopt.Parser(usage="xyz", _ispytest=True)
|
||||
pytest.raises(UsageError, lambda: parser.parse(["-h"]))
|
||||
|
||||
def test_custom_prog(self, parser: parseopt.Parser) -> None:
|
||||
@@ -90,13 +90,13 @@ class TestParser:
|
||||
assert groups_names == list("132")
|
||||
|
||||
def test_group_addoption(self) -> None:
|
||||
group = parseopt.OptionGroup("hello")
|
||||
group = parseopt.OptionGroup("hello", _ispytest=True)
|
||||
group.addoption("--option1", action="store_true")
|
||||
assert len(group.options) == 1
|
||||
assert isinstance(group.options[0], parseopt.Argument)
|
||||
|
||||
def test_group_addoption_conflict(self) -> None:
|
||||
group = parseopt.OptionGroup("hello again")
|
||||
group = parseopt.OptionGroup("hello again", _ispytest=True)
|
||||
group.addoption("--option1", "--option-1", action="store_true")
|
||||
with pytest.raises(ValueError) as err:
|
||||
group.addoption("--option1", "--option-one", action="store_true")
|
||||
@@ -188,7 +188,7 @@ class TestParser:
|
||||
elif option.type is str:
|
||||
option.default = "world"
|
||||
|
||||
parser = parseopt.Parser(processopt=defaultget)
|
||||
parser = parseopt.Parser(processopt=defaultget, _ispytest=True)
|
||||
parser.addoption("--this", dest="this", type=int, action="store")
|
||||
parser.addoption("--hello", dest="hello", type=str, action="store")
|
||||
parser.addoption("--no", dest="no", action="store_true")
|
||||
|
||||
@@ -744,10 +744,16 @@ def test_run_result_repr() -> None:
|
||||
|
||||
# known exit code
|
||||
r = pytester_mod.RunResult(1, outlines, errlines, duration=0.5)
|
||||
assert (
|
||||
repr(r) == "<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
|
||||
" len(stderr.lines)=4 duration=0.50s>"
|
||||
)
|
||||
if sys.version_info[:2] >= (3, 10):
|
||||
assert repr(r) == (
|
||||
"<RunResult ret=TESTS_FAILED len(stdout.lines)=3"
|
||||
" len(stderr.lines)=4 duration=0.50s>"
|
||||
)
|
||||
else:
|
||||
assert repr(r) == (
|
||||
"<RunResult ret=ExitCode.TESTS_FAILED len(stdout.lines)=3"
|
||||
" len(stderr.lines)=4 duration=0.50s>"
|
||||
)
|
||||
|
||||
# unknown exit code: just the number
|
||||
r = pytester_mod.RunResult(99, outlines, errlines, duration=0.5)
|
||||
|
||||
@@ -27,6 +27,17 @@ def test_recwarn_functional(pytester: Pytester) -> None:
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("")
|
||||
def test_recwarn_captures_deprecation_warning(recwarn: WarningsRecorder) -> None:
|
||||
"""
|
||||
Check that recwarn can capture DeprecationWarning by default
|
||||
without custom filterwarnings (see #8666).
|
||||
"""
|
||||
warnings.warn(DeprecationWarning("some deprecation"))
|
||||
assert len(recwarn) == 1
|
||||
assert recwarn.pop(DeprecationWarning)
|
||||
|
||||
|
||||
class TestWarningsRecorderChecker:
|
||||
def test_recording(self) -> None:
|
||||
rec = WarningsRecorder(_ispytest=True)
|
||||
@@ -298,7 +309,7 @@ class TestWarns:
|
||||
assert str(record[0].message) == "user"
|
||||
|
||||
def test_record_only(self) -> None:
|
||||
with pytest.warns(None) as record:
|
||||
with pytest.warns() as record:
|
||||
warnings.warn("user", UserWarning)
|
||||
warnings.warn("runtime", RuntimeWarning)
|
||||
|
||||
@@ -306,6 +317,18 @@ class TestWarns:
|
||||
assert str(record[0].message) == "user"
|
||||
assert str(record[1].message) == "runtime"
|
||||
|
||||
def test_record_only_none_deprecated_warn(self) -> None:
|
||||
# This should become an error when WARNS_NONE_ARG is removed in Pytest 7.0
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
with pytest.warns(None) as record: # type: ignore[call-overload]
|
||||
warnings.warn("user", UserWarning)
|
||||
warnings.warn("runtime", RuntimeWarning)
|
||||
|
||||
assert len(record) == 2
|
||||
assert str(record[0].message) == "user"
|
||||
assert str(record[1].message) == "runtime"
|
||||
|
||||
def test_record_by_subclass(self) -> None:
|
||||
with pytest.warns(Warning) as record:
|
||||
warnings.warn("user", UserWarning)
|
||||
|
||||
@@ -1143,21 +1143,34 @@ def test_errors_in_xfail_skip_expressions(pytester: Pytester) -> None:
|
||||
pypy_version_info = getattr(sys, "pypy_version_info", None)
|
||||
if pypy_version_info is not None and pypy_version_info < (6,):
|
||||
markline = markline[5:]
|
||||
elif sys.version_info[:2] >= (3, 10):
|
||||
markline = markline[11:]
|
||||
elif sys.version_info >= (3, 8) or hasattr(sys, "pypy_version_info"):
|
||||
markline = markline[4:]
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
|
||||
if sys.version_info[:2] >= (3, 10):
|
||||
expected = [
|
||||
"*ERROR*test_nameerror*",
|
||||
"*evaluating*skipif*condition*",
|
||||
"*asd*",
|
||||
"*ERROR*test_syntax*",
|
||||
"*evaluating*xfail*condition*",
|
||||
" syntax error",
|
||||
markline,
|
||||
"SyntaxError: invalid syntax",
|
||||
"*1 pass*2 errors*",
|
||||
"",
|
||||
"During handling of the above exception, another exception occurred:",
|
||||
]
|
||||
)
|
||||
else:
|
||||
expected = [
|
||||
"*ERROR*test_nameerror*",
|
||||
]
|
||||
|
||||
expected += [
|
||||
"*evaluating*skipif*condition*",
|
||||
"*asd*",
|
||||
"*ERROR*test_syntax*",
|
||||
"*evaluating*xfail*condition*",
|
||||
" syntax error",
|
||||
markline,
|
||||
"SyntaxError: invalid syntax",
|
||||
"*1 pass*2 errors*",
|
||||
]
|
||||
result.stdout.fnmatch_lines(expected)
|
||||
|
||||
|
||||
def test_xfail_skipif_with_globals(pytester: Pytester) -> None:
|
||||
|
||||
@@ -1618,7 +1618,7 @@ def test_terminal_summary(pytester: Pytester) -> None:
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::UserWarning")
|
||||
def test_terminal_summary_warnings_are_displayed(pytester: Pytester) -> None:
|
||||
"""Test that warnings emitted during pytest_terminal_summary are displayed.
|
||||
(#1305).
|
||||
@@ -1655,7 +1655,7 @@ def test_terminal_summary_warnings_are_displayed(pytester: Pytester) -> None:
|
||||
assert stdout.count("=== warnings summary ") == 2
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::UserWarning")
|
||||
def test_terminal_summary_warnings_header_once(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
"""
|
||||
|
||||
@@ -8,7 +8,7 @@ if sys.version_info < (3, 8):
|
||||
pytest.skip("threadexception plugin needs Python>=3.8", allow_module_level=True)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
|
||||
def test_unhandled_thread_exception(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
test_it="""
|
||||
@@ -42,7 +42,7 @@ def test_unhandled_thread_exception(pytester: Pytester) -> None:
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
|
||||
def test_unhandled_thread_exception_in_setup(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
test_it="""
|
||||
@@ -78,7 +78,7 @@ def test_unhandled_thread_exception_in_setup(pytester: Pytester) -> None:
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("default")
|
||||
@pytest.mark.filterwarnings("default::pytest.PytestUnhandledThreadExceptionWarning")
|
||||
def test_unhandled_thread_exception_in_teardown(pytester: Pytester) -> None:
|
||||
pytester.makepyfile(
|
||||
test_it="""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
from typing import cast
|
||||
@@ -400,11 +401,13 @@ class TestRmRf:
|
||||
assert fn.is_file()
|
||||
|
||||
# ignored function
|
||||
with pytest.warns(None) as warninfo:
|
||||
exc_info4 = (None, PermissionError(), None)
|
||||
on_rm_rf_error(os.open, str(fn), exc_info4, start_path=tmp_path)
|
||||
assert fn.is_file()
|
||||
assert not [x.message for x in warninfo]
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
with pytest.warns(None) as warninfo: # type: ignore[call-overload]
|
||||
exc_info4 = (None, PermissionError(), None)
|
||||
on_rm_rf_error(os.open, str(fn), exc_info4, start_path=tmp_path)
|
||||
assert fn.is_file()
|
||||
assert not [x.message for x in warninfo]
|
||||
|
||||
exc_info5 = (None, PermissionError(), None)
|
||||
on_rm_rf_error(os.unlink, str(fn), exc_info5, start_path=tmp_path)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user