Compare commits

...

121 Commits
2.8.4 ... 2.8.7

Author SHA1 Message Date
Ronny Pfannschmidt
3315b3a12f finalize changelog for 2.8.7 2016-01-24 23:23:15 +01:00
Ronny Pfannschmidt
64d7d00218 Prepare 2.8.7 release 2016-01-24 17:59:48 +01:00
Ronny Pfannschmidt
7c747c97ec Merge pull request #1339 from RonnyPfannschmidt/fix-1338
Fix 1338
2016-01-24 17:51:00 +01:00
Ronny Pfannschmidt
56c5db6e12 add requests dependency to tox.ini to ensure all monkeypatch tests run 2016-01-24 12:30:38 +01:00
Ronny Pfannschmidt
2d05f831fe monkeypatch: unnest handling code
this avoid python3 nested exceptions
2016-01-24 12:28:14 +01:00
Ronny Pfannschmidt
cb6181255e changelog 2016-01-24 00:45:59 +01:00
Ronny Pfannschmidt
cd9e30b221 work around python 2/3 difference by using str(exception) 2016-01-24 00:40:27 +01:00
Ronny Pfannschmidt
d028fe1e66 remove unused import 2016-01-23 20:29:54 +01:00
Ronny Pfannschmidt
b825af2e66 pass trough annotated exceptions 2016-01-23 19:31:17 +01:00
Ronny Pfannschmidt
60e9698530 fix issue 1338 2016-01-23 19:12:51 +01:00
Ronny Pfannschmidt
9e6bb74d71 reformat monkeypatch core plugin/its tests 2016-01-23 19:12:51 +01:00
Bruno Oliveira
c8caa87759 Merge branch 'release-2.8.6' 2016-01-22 18:00:01 -02:00
Bruno Oliveira
b7de0401b8 Bump version to 2.8.7.dev1 2016-01-22 17:59:25 -02:00
Bruno Oliveira
01793ed8bc Use a full url to pytest logo on README
So it appers correctly in PyPI
2016-01-22 17:46:28 -02:00
Bruno Oliveira
82d00efa8d 2.8.6 release: version, CHANGELOG
Remove note about expected failing envs in tox, as tox now supports
skipping certain environments based on the platform.
2016-01-21 19:17:53 -02:00
Bruno Oliveira
61c569f960 Merge branch 'junit_stdout_err_on_error' 2016-01-20 19:06:50 -02:00
Bruno Oliveira
dd56d7b7fc Add CHANGELOG and AUTHORS entry for #1334 2016-01-20 19:00:52 -02:00
Bruno Oliveira
4de3d595c9 Merge pull request #1333 from lesteve/fix-practise-typo
Fix practise -> practice typo in documentation
2016-01-20 18:03:15 -02:00
Georgy Dyuldin
b28b3cc271 Add captured stdout to jUnit report on setup error 2016-01-20 20:13:01 +03:00
Loïc Estève
99072ea8c9 Fix practise -> practice typo in documentation 2016-01-20 16:35:27 +01:00
Ronny Pfannschmidt
11a7bcaaa5 Merge pull request #1322 from nicoddemus/missing-hooks-docs
Add a few missing hooks to the docs
2016-01-19 08:12:58 +01:00
Bruno Oliveira
0caee1a673 Add a few missing hooks to the docs 2016-01-18 19:27:35 -02:00
Bruno Oliveira
4c87a6aa09 Merge pull request #1330 from nicoddemus/fix-flakes
Fix flakes
2016-01-18 15:36:20 -02:00
Bruno Oliveira
7b13c4bec0 Fix flakes 2016-01-14 21:01:57 -02:00
Bruno Oliveira
aa8c352c10 Merge pull request #1323 from jeffwidman/patch-1
Change `input` to `test_input` in docs for clarity
2016-01-12 23:28:52 -02:00
Jeff Widman
ee75ecbda0 Change input to test_input in docs for clarity
Using `input` is confusing because it's also the name of a Python built-in function. So we use `test_input` instead. Fix #1321
2016-01-12 17:01:34 -08:00
Ronny Pfannschmidt
b2c0864fbf Merge pull request #1318 from nicoddemus/doctest-unicode-error
Fix decode error in Python 2.7 when docstrings contain a non-ascii character
2016-01-11 08:37:24 +01:00
Florian Bruhin
a80efb038a Merge pull request #1320 from bionikspoon/patch-1
update docs plugin.rst typo
2016-01-11 07:37:46 +01:00
Manu Phatak
5b29f579c5 update docs plugin.rst typo 2016-01-11 00:11:46 -06:00
Bruno Oliveira
808cb8e3ad Merge branch 'stdout-pdb-capture' 2016-01-09 11:46:13 -02:00
Bruno Oliveira
8727503dd4 Add CHANGELOG entry for #1223 2016-01-09 11:45:56 -02:00
foxx
f46de68804 Fixes bug with stdout/stderr capture on pdb 2016-01-09 12:04:26 +00:00
Bruno Oliveira
3c19cfcd9a Fix decode error in Python 2.7 when docstrings contain a non-ascii character
Fix #628
2016-01-08 23:10:02 -02:00
Bruno Oliveira
29b05c8391 Merge pull request #1309 from k4rtik/patch-1
Correct platform name osx -> darwin
2016-01-05 23:29:33 -02:00
Kartik Singhal
26c835eea5 Correct platform name osx -> darwin 2016-01-05 18:43:03 -05:00
Ronny Pfannschmidt
e2603d7050 Merge pull request #1306 from nicoddemus/summary-warnings
pytest warnings emitted during ``pytest_terminal_summary`` are now properly displayed.
2016-01-04 11:16:33 +01:00
Bruno Oliveira
369d9ecaa5 pytest warnings emitted during `pytest_terminal_summary` are now properly displayed.
Fix #1305
2016-01-04 00:07:45 -02:00
Bruno Oliveira
80d6d94635 Merge pull request #1298 from aktech/patch-1
Update copyright in README
2016-01-01 12:06:21 -02:00
AMiT Kumar
63cba1ed0d Update copyright in README 2016-01-01 18:52:56 +05:30
Ronny Pfannschmidt
71ab6b8b05 Merge pull request #1295 from nicoddemus/monkeypatch-perf
Make monkeypatch calls O(1)
2015-12-30 22:21:16 +01:00
Bruno Oliveira
638b3f5e39 Make monkeypatch calls O(1)
Fix #1292
2015-12-29 22:04:35 -02:00
Bruno Oliveira
0ef73ed3e0 Small typo on README 2015-12-28 18:56:14 -02:00
Bruno Oliveira
7cfb750d7f Small wording on README 2015-12-28 18:55:20 -02:00
Bruno Oliveira
70f72229c6 Merge pull request #1291 from ulope/master
Make monkeypatch differentiate ImportError sources
2015-12-28 13:18:25 -02:00
Ulrich Petri
2e02579437 Add CHANGELOG entry for #900 fix 2015-12-28 10:53:38 +01:00
Ulrich Petri
8d49abb0d1 Make monkeypatch differentiate ImportError sources
Previously `monkeypatch` assumed that any `ImportError` was caused by
a mistake in the specified import path. However this assumption is false 
in case the import target itself causes an `ImportError`.

Fixes: #900
2015-12-27 22:44:23 +01:00
Ronny Pfannschmidt
c5631b6567 Merge pull request #1284 from nicoddemus/pyversions-badge
Add badge of supported python versions to README
2015-12-27 16:05:43 +01:00
Ronny Pfannschmidt
522224ee7c Merge pull request #1285 from nicoddemus/readme-changes-logo
Add logo and some readme changes
2015-12-27 15:47:29 +01:00
Bruno Oliveira
015e8e574a Merge pull request #1289 from WoLpH/patch-1
Updated out of date link
2015-12-27 07:22:41 -02:00
Rick van Hattem
87ff7ee232 Updated out of date link 2015-12-27 02:35:02 +01:00
Bruno Oliveira
b5490b289d Add logo and update readme
* Show pytest logo
* Show assertion introspection in the example
* Use separate sections for change-log, docs, license, etc.
2015-12-26 12:47:22 -02:00
Bruno Oliveira
99a5067edb Merge branch 'pyreadline-workaround' 2015-12-25 18:03:25 -02:00
Bruno Oliveira
5afb61ad26 Fix trailing white-space 2015-12-25 17:51:55 -02:00
Bruno Oliveira
fbfab6778c Give proper thanks for the PR in the CHANGELOG 2015-12-25 17:48:03 -02:00
Bruno Oliveira
57bc14caa0 Apply readline workaround during initial conftest loading 2015-12-25 17:46:19 -02:00
Bruno Oliveira
df3f21afb6 Add badge of supported python versions to README 2015-12-25 16:28:50 -02:00
Ronny Pfannschmidt
1a87bb2416 Merge pull request #1280 from nicoddemus/del-index-from-overview
Remove "index" entry from overview.rst
2015-12-25 07:33:15 +01:00
Erik M. Bray
6e170a4a1c * Moved workaround to its own function, mostly for the sake of adding
a more descriptive docstring (the workaround itself is just to import
  readline earlier).  I removed the conditional on targetfd from the
  workaround since it doesn't really matter.

* Added # noqa marker.

* Added changelog entry, and self to authors.
2015-12-24 16:43:34 -05:00
Erik M. Bray
924a9667e1 Make sure readline has been imported before duping any stdio handles--otherwise pyreadline fails to connect to the correct handle for the console's stdout/in. 2015-12-24 14:56:57 -05:00
Bruno Oliveira
319f6310f8 Remove "index" entry from overview.rst
"index" is already displayed in the main docs, repeating it here breaks the reading flow
2015-12-24 16:08:43 -02:00
Bruno Oliveira
cd3a441304 Merge pull request #1277 from peterdemin/patch-1
doc typo
2015-12-24 15:57:01 -02:00
Peter Demin
8180165229 doc typo 2015-12-24 08:56:54 -05:00
Ronny Pfannschmidt
ec5a429c77 junitxml tests: extend with extra items 2015-12-17 22:30:27 +01:00
Ronny Pfannschmidt
713069ebd4 implement review comments for #1266 2015-12-17 22:27:01 +01:00
Ronny Pfannschmidt
8bf7e7cc4b fixes #1259 - take finalized nodes out of the mapping
this allows double node id usage for file based items
2015-12-16 19:09:44 +01:00
Ronny Pfannschmidt
7b20288c2b Merge pull request #1264 from nicoddemus/exception-interact-deprecated
Remove experimental status from pytest_exception_interact
2015-12-16 18:32:58 +01:00
Bruno Oliveira
2b2bec6b97 Remove experimental status from pytest_exception_interact 2015-12-16 14:29:39 -02:00
Bruno Oliveira
7eea6b3b02 Add 2.8.6.dev1 to CHANGELOG 2015-12-11 23:11:36 -02:00
Bruno Oliveira
e87facfb22 Bump master to 2.8.6.dev1 2015-12-11 23:07:30 -02:00
Bruno Oliveira
855b115dab Remove plugins_index generation from HOWTORELEASE 2015-12-11 22:35:44 -02:00
Bruno Oliveira
4263b8b407 Restore regen-doc result 2015-12-11 22:34:16 -02:00
Florian Bruhin
7d150c20cf Regenerate 2.8.5 docs. 2015-12-11 22:28:23 -02:00
Bruno Oliveira
a124163425 Prepare for 2.8.5: bump version, CHANGELOG, announce 2015-12-11 19:20:07 -02:00
Ronny Pfannschmidt
2382546112 Merge pull request #1252 from nicoddemus/optimize-app-veyor
Optimize appveyor build
2015-12-11 16:10:45 +01:00
Bruno Oliveira
946bb08da5 Tyding up the CHANGELOG 2015-12-11 00:36:26 -02:00
Bruno Oliveira
85d1f0404a Merge pull request #1243 from aselus-hub/master
Update python.py
2015-12-11 00:33:46 -02:00
Bruno Oliveira
1d60f61ba8 Optimize appveyor build
- AppVeyor does not run matrix builds in parallel, so creating a matrix with the intent to
  speed up the build will actually result in longer build times, as each matrix will execute
  in a brand new VM.
- tox does not detect 64 bit installations in AppVeyor, it always installs interpreters
  from C:\PythonX.Y, so there's no point to have 64bit builds
- No need for the auxiliary script "install.ps1" because all python versions we are interested
  in are already pre-installed in AppVeyor
2015-12-11 00:20:20 -02:00
aselus-hub
ad05cbe6da fixed meesage. 2015-12-10 15:39:31 -08:00
aselus-hub
1216a27b44 added docstrign to inection collection test. 2015-12-10 15:19:08 -08:00
aselus-hub
2b2240e904 added myself to authors, added changelog entry. 2015-12-10 15:15:09 -08:00
aselus-hub
74f7efd2a3 added line comparison that is pytest-sugar agnostic. 2015-12-10 15:10:55 -08:00
aselus-hub
34db8aed34 added verification that test actually passed. 2015-12-10 15:02:57 -08:00
aselus-hub
af54e09759 nit: fixed newline 2015-12-10 14:46:51 -08:00
aselus-hub
dfaeefd692 added test to verify injection. 2015-12-10 14:45:36 -08:00
Bruno Oliveira
46c85bc352 Merge pull request #1249 from nicoddemus/remove-plugins-index
Remove plugins_index from the docs
2015-12-10 19:11:32 -02:00
Bruno Oliveira
139c97930b Remove plugins_index from the docs
Fix #1229
2015-12-10 19:00:01 -02:00
Ronny Pfannschmidt
9cfee82f9b Merge pull request #1247 from alex/patch-1
Use https for images in readme
2015-12-10 00:02:47 +01:00
Alex Gaynor
c0a5f3df10 Use https for images in readme 2015-12-09 18:01:36 -05:00
Bruno Oliveira
8220c05b01 Merge pull request #1245 from RonnyPfannschmidt/howtorelease
add a reminder of the features branch merge to HOWTORELEASE.rst
2015-12-09 18:34:41 -02:00
Ronny Pfannschmidt
d0f5f6676b add a reminder of the features branch merge to HOWTORELEASE.rst 2015-12-09 21:20:54 +01:00
aselus-hub
ec02f694ef Update python.py
updated dictionary itteration to create a list for generation, so that tests can be added in the generator functions under python3. This works fine as-is in python2 because python 2 already creates a list, whereas python3 returns an itterator. Forcing a list format for the return fixes python3 to work the same way as python2
2015-12-09 11:32:19 -08:00
Ronny Pfannschmidt
1c70827f33 Merge pull request #1241 from nicoddemus/fix-deprecated-call-args
Fix deprecated_call regression introduced in 2.8.4
2015-12-09 06:48:43 +01:00
Bruno Oliveira
1c46462991 Fix deprecated_call regression introduced in 2.8.4
Fix #1238
2015-12-08 22:40:05 -02:00
Ronny Pfannschmidt
ffa572531a Merge pull request #1091 from RonnyPfannschmidt/fix-1074
fix issue 1074 and clean up junitxml
2015-12-07 22:13:16 +01:00
Ronny Pfannschmidt
fde2a6f5fd add changelog entry 2015-12-07 21:58:34 +01:00
Ronny Pfannschmidt
7b7737bf96 handle duplicate test ids via collection and xdist each reporting 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
04e9ae75c8 add xfailing test for double test id failure 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
9ea7826427 Junitxml: correct node reporter attribute names 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
09cc45b0c5 junitxml: correct docstring of make_properties_node 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
0aa54101c9 junitxml: follow Bruno's attribute/method naming hint from the review 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
5eef6a2821 junitxml: fix python3 compat of the tests 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
518c88f149 finalize nodereporters by throwing away the intermediate xml nodes, fixes issue #1074 2015-12-07 21:54:25 +01:00
Ronny Pfannschmidt
5f5a7995b9 reintroduce junitxml report order and debug cleanups 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
0528e5b45f junitxml: intermediate, move testcase generation to NodeReporter 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
9b04958303 junitxml: keep track of custom property insert order
+ review: should we allow the same key multile times
2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
faed54d6c7 junitxml: use node.warn to ensure fslocations 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
1f609f96e6 junitxml: introduce nodereporter and track durations/properties there 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
0664ae137c junitxml: remove debug print 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
d0107c898e junitxml restrucutre stat generation - use node tags 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
9128fec4c4 junitxml: simplify the api used for testing junitml 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
80bcf8d624 junitxml: simplify tests by creating a api wrapper 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
b8df5446c0 junitxml: yapf clean the tests 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
2a31df072b junitxml: reverse the if/else logic for failure appending 2015-12-07 21:54:24 +01:00
Ronny Pfannschmidt
02f5defd89 yapf junitxml 2015-12-07 21:54:24 +01:00
Bruno Oliveira
efb5332023 Merge pull request #1186 from RonnyPfannschmidt/fix-manifest
fix #1185 - ensure MANIFEST.in exactly matches what should go to a sdist
2015-12-07 13:48:39 -02:00
Ronny Pfannschmidt
b9908cc036 Merge pull request #1228 from pytest-dev/pytest-2.8.4
finish the release process of pytest 2.8.4
2015-12-06 20:32:52 +01:00
Ronny Pfannschmidt
c727860241 bump to 2.8.5.dev 2015-12-06 20:31:14 +01:00
Ronny Pfannschmidt
a4a12b8356 Merge pull request #1227 from nicoddemus/warn-deprecated-call
Add a note about how DeprecationWarning and PendingDeprecationWarning are treated differently
2015-12-06 10:52:58 +01:00
Ronny Pfannschmidt
13ae2fe28b adopt review comment of #1186 2015-12-06 10:24:24 +01:00
Ronny Pfannschmidt
141a463fed fix #1185 - ensure MANIFEST.in exactly matches what should go to a sdist 2015-12-06 10:24:24 +01:00
Bruno Oliveira
b48a02fdb1 Add a note about how DeprecationWarning and PendingDeprecationWarning are treated differently
Fix #1026
2015-12-05 13:53:58 -02:00
62 changed files with 1284 additions and 1457 deletions

View File

@@ -31,9 +31,11 @@ Eduardo Schettino
Elizaveta Shashkova
Eric Hunsberger
Eric Siegerman
Erik M. Bray
Florian Bruhin
Floris Bruynooghe
Gabriel Reis
Georgy Dyuldin
Graham Horler
Grig Gheorghiu
Guido Wesdorp
@@ -71,3 +73,5 @@ Eric Hunsberger
Simon Gomizelj
Russel Winder
Ben Webb
Alexei Kozlenok
Cal Leeming

View File

@@ -1,3 +1,54 @@
2.8.7
----------
- fix #1338: use predictable object resolution for monkeypatch
2.8.6
-----
- fix #1259: allow for double nodeids in junitxml,
this was a regression failing plugins combinations
like pytest-pep8 + pytest-flakes
- Workaround for exception that occurs in pyreadline when using
``--pdb`` with standard I/O capture enabled.
Thanks Erik M. Bray for the PR.
- fix #900: Better error message in case the target of a ``monkeypatch`` call
raises an ``ImportError``.
- fix #1292: monkeypatch calls (setattr, setenv, etc.) are now O(1).
Thanks David R. MacIver for the report and Bruno Oliveira for the PR.
- fix #1223: captured stdout and stderr are now properly displayed before
entering pdb when ``--pdb`` is used instead of being thrown away.
Thanks Cal Leeming for the PR.
- fix #1305: pytest warnings emitted during ``pytest_terminal_summary`` are now
properly displayed.
Thanks Ionel Maries Cristian for the report and Bruno Oliveira for the PR.
- fix #628: fixed internal UnicodeDecodeError when doctests contain unicode.
Thanks Jason R. Coombs for the report and Bruno Oliveira for the PR.
- fix #1334: Add captured stdout to jUnit XML report on setup error.
Thanks Georgy Dyuldin for the PR.
2.8.5
-----
- fix #1243: fixed issue where class attributes injected during collection could break pytest.
PR by Alexei Kozlenok, thanks Ronny Pfannschmidt and Bruno Oliveira for the review and help.
- fix #1074: precompute junitxml chunks instead of storing the whole tree in objects
Thanks Bruno Oliveira for the report and Ronny Pfannschmidt for the PR
- fix #1238: fix ``pytest.deprecated_call()`` receiving multiple arguments
(Regression introduced in 2.8.4). Thanks Alex Gaynor for the report and
Bruno Oliveira for the PR.
2.8.4
-----
@@ -17,6 +68,7 @@
- fix the summary printed when no tests did run.
Thanks Florian Bruhin for the PR.
- fix #1185 - ensure MANIFEST.in exactly matches what should go to a sdist
- a number of documentation modernizations wrt good practices.
Thanks Bruno Oliveira for the PR.

View File

@@ -27,10 +27,6 @@ Note: this assumes you have already registered on pypi.
devpi list pytest
or look at failures with "devpi list -f pytest".
There will be some failed environments like e.g. the py33-trial
or py27-pexpect tox environments on Win32 platforms
which is ok (tox does not support skipping on
per-platform basis yet).
7. Regenerate the docs examples using tox, and check for regressions::
@@ -41,8 +37,7 @@ Note: this assumes you have already registered on pypi.
8. Build the docs, you need a virtualenv with py and sphinx
installed::
cd doc/en
python plugins_index/plugins_index.py
cd doc/en
make html
Commit any changes before tagging the release.
@@ -88,3 +83,5 @@ Note: this assumes you have already registered on pypi.
13. **after the release** Bump the version number in ``_pytest/__init__.py``,
to the next Minor release version (i.e. if you released ``pytest-2.8.0``,
set it to ``pytest-2.9.0.dev1``).
14. merge the actual release into the features branch and do a pull request against it

View File

@@ -1,7 +1,34 @@
include CHANGELOG
include README.rst
include setup.py
include tox.ini
include LICENSE
graft doc
include AUTHORS
include README.rst
include CONTRIBUTING.rst
include tox.ini
include setup.py
include .coveragerc
include plugin-test.sh
include requirements-docs.txt
include runtox.py
recursive-include bench *.py
recursive-include extra *.py
graft testing
graft doc
exclude _pytest/impl
graft _pytest/vendored_packages
recursive-exclude * *.pyc *.pyo
exclude appveyor/install.ps1
exclude appveyor.yml
exclude appveyor
exclude ISSUES.txt
exclude HOWTORELEASE.rst

View File

@@ -1,66 +1,99 @@
======
pytest
======
.. image:: http://pytest.org/latest/_static/pytest1.png
:target: http://pytest.org
:align: center
:alt: pytest
The ``pytest`` testing tool makes it easy to write small tests, yet
scales to support complex functional testing.
------
.. image:: http://img.shields.io/pypi/v/pytest.svg
.. image:: https://img.shields.io/pypi/v/pytest.svg
:target: https://pypi.python.org/pypi/pytest
.. image:: http://img.shields.io/coveralls/pytest-dev/pytest/master.svg
.. image:: https://img.shields.io/pypi/pyversions/pytest.svg
:target: https://pypi.python.org/pypi/pytest
.. image:: https://img.shields.io/coveralls/pytest-dev/pytest/master.svg
:target: https://coveralls.io/r/pytest-dev/pytest
.. image:: https://travis-ci.org/pytest-dev/pytest.svg?branch=master
:target: https://travis-ci.org/pytest-dev/pytest
.. image:: https://ci.appveyor.com/api/projects/status/mrgbjaua7t33pg6b?svg=true
:target: https://ci.appveyor.com/project/pytestbot/pytest
Documentation: http://pytest.org/latest/
The ``pytest`` framework makes it easy to write small tests, yet
scales to support complex functional testing for applications and libraries.
Changelog: http://pytest.org/latest/changelog.html
An example of a simple test:
Issues: https://github.com/pytest-dev/pytest/issues
.. code-block:: python
# content of test_sample.py
def func(x):
return x + 1
def test_answer():
assert func(3) == 5
To execute it::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
collected 1 items
test_sample.py F
======= FAILURES ========
_______ test_answer ________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:5: AssertionError
======= 1 failed in 0.12 seconds ========
Due to ``py.test``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <http://pytest.org/latest/getting-started.html#our-first-test-run>`_ for more examples.
Features
--------
- `auto-discovery
<http://pytest.org/latest/goodpractises.html#python-test-discovery>`_
of test modules and functions,
- detailed info on failing `assert statements <http://pytest.org/latest/assert.html>`_ (no need to remember ``self.assert*`` names)
- `modular fixtures <http://pytest.org/latest/fixture.html>`_ for
managing small or parametrized long-lived test resources.
- multi-paradigm support: you can use ``pytest`` to run test suites based
on `unittest <http://pytest.org/latest/unittest.html>`_ (or trial),
`nose <http://pytest.org/latest/nose.html>`_
- single-source compatibility from Python2.6 all the way up to
Python3.5, PyPy-2.3, (jython-2.5 untested)
- Detailed info on failing `assert statements <http://pytest.org/latest/assert.html>`_ (no need to remember ``self.assert*`` names);
- `Auto-discovery
<http://pytest.org/latest/goodpractices.html#python-test-discovery>`_
of test modules and functions;
- `Modular fixtures <http://pytest.org/latest/fixture.html>`_ for
managing small or parametrized long-lived test resources;
- Can run `unittest <http://pytest.org/latest/unittest.html>`_ (or trial),
`nose <http://pytest.org/latest/nose.html>`_ test suites out of the box;
- Python2.6+, Python3.2+, PyPy-2.3, Jython-2.5 (untested);
- Rich plugin architecture, with over 150+ `external plugins <http://pytest.org/latest/plugins.html#installing-external-plugins-searching>`_ and thriving comminity;
- many `external plugins <http://pytest.org/latest/plugins.html#installing-external-plugins-searching>`_.
Documentation
-------------
A simple example for a test:
.. code-block:: python
# content of test_module.py
def test_function():
i = 4
assert i == 3
which can be run with ``py.test test_module.py``. See `getting-started <http://pytest.org/latest/getting-started.html#our-first-test-run>`_ for more examples.
For much more info, including PDF docs, see
http://pytest.org
and report bugs at:
https://github.com/pytest-dev/pytest/issues
and checkout or fork repo at:
https://github.com/pytest-dev/pytest
For full documentation, including installation, tutorials and PDF documents, please see http://pytest.org.
Copyright Holger Krekel and others, 2004-2015
Bugs/Requests
-------------
Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issues>`_ to submit bugs or request features.
Changelog
---------
Consult the `Changelog <http://pytest.org/latest/changelog.html>`_ page for fixes and enhancements of each version.
License
-------
Copyright Holger Krekel and others, 2004-2016.
Licensed under the MIT license.

View File

@@ -1,2 +1,2 @@
#
__version__ = '2.8.4'
__version__ = '2.8.7'

View File

@@ -112,8 +112,8 @@ def pytest_runtest_setup(item):
config=item.config, op=op, left=left, right=right)
for new_expl in hook_result:
if new_expl:
if (sum(len(p) for p in new_expl[1:]) > 80*8
and item.config.option.verbose < 2):
if (sum(len(p) for p in new_expl[1:]) > 80*8 and
item.config.option.verbose < 2):
show_max = 10
truncated_lines = len(new_expl) - show_max
new_expl[show_max:] = [py.builtin._totext(

View File

@@ -140,8 +140,8 @@ def assertrepr_compare(config, op, left, right):
summary = u('%s %s %s') % (ecu(left_repr), op, ecu(right_repr))
issequence = lambda x: (isinstance(x, (list, tuple, Sequence))
and not isinstance(x, basestring))
issequence = lambda x: (isinstance(x, (list, tuple, Sequence)) and
not isinstance(x, basestring))
istext = lambda x: isinstance(x, basestring)
isdict = lambda x: isinstance(x, dict)
isset = lambda x: isinstance(x, (set, frozenset))
@@ -263,8 +263,7 @@ def _compare_eq_sequence(left, right, verbose=False):
explanation += [
u('Right contains more items, first extra item: %s') %
py.io.saferepr(right[len(left)],)]
return explanation # + _diff_text(pprint.pformat(left),
# pprint.pformat(right))
return explanation
def _compare_eq_set(left, right, verbose=False):

View File

@@ -31,6 +31,7 @@ def pytest_addoption(parser):
@pytest.hookimpl(hookwrapper=True)
def pytest_load_initial_conftests(early_config, parser, args):
_readline_workaround()
ns = early_config.known_args_namespace
pluginmanager = early_config.pluginmanager
capman = CaptureManager(ns.capture)
@@ -442,3 +443,30 @@ class DontReadFromInput:
def close(self):
pass
def _readline_workaround():
"""
Ensure readline is imported so that it attaches to the correct stdio
handles on Windows.
Pdb uses readline support where available--when not running from the Python
prompt, the readline module is not imported until running the pdb REPL. If
running py.test with the --pdb option this means the readline module is not
imported until after I/O capture has been started.
This is a problem for pyreadline, which is often used to implement readline
support on Windows, as it does not attach to the correct handles for stdout
and/or stdin if they have been redirected by the FDCapture mechanism. This
workaround ensures that readline is imported before I/O capture is setup so
that it can attach to the actual stdin/out for the console.
See https://github.com/pytest-dev/pytest/pull/1281
"""
if not sys.platform.startswith('win32'):
return
try:
import readline # noqa
except ImportError:
pass

View File

@@ -81,15 +81,15 @@ class DoctestItem(pytest.Item):
reprlocation = ReprFileLocation(filename, lineno, message)
checker = _get_unicode_checker()
REPORT_UDIFF = doctest.REPORT_UDIFF
filelines = py.path.local(filename).readlines(cr=0)
lines = []
if lineno is not None:
i = max(test.lineno, max(0, lineno - 10)) # XXX?
for line in filelines[i:lineno]:
lines.append("%03d %s" % (i+1, line))
i += 1
lines = doctestfailure.test.docstring.splitlines(False)
# add line numbers to the left of the error message
lines = ["%03d %s" % (i + test.lineno + 1, x)
for (i, x) in enumerate(lines)]
# trim docstring error lines to 10
lines = lines[example.lineno - 9:example.lineno + 1]
else:
lines.append('EXAMPLE LOCATION UNKNOWN, not showing all tests of that example')
lines = ['EXAMPLE LOCATION UNKNOWN, not showing all tests of that example']
indent = '>>>'
for line in example.source.splitlines():
lines.append('??? %s %s' % (indent, line))

View File

@@ -282,12 +282,11 @@ def pytest_keyboard_interrupt(excinfo):
""" called for keyboard interrupt. """
def pytest_exception_interact(node, call, report):
""" (experimental, new in 2.4) called when
an exception was raised which can potentially be
"""called when an exception was raised which can potentially be
interactively handled.
This hook is only called if an exception was raised
that is not an internal exception like "skip.Exception".
that is not an internal exception like ``skip.Exception``.
"""
def pytest_enter_pdb():

View File

@@ -1,9 +1,13 @@
""" report test results in JUnit-XML format, for use with Hudson and build integration servers.
"""
report test results in JUnit-XML format,
for use with Jenkins and build integration servers.
Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
Based on initial code from Ross Lawley.
"""
# Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/
# src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
import py
import os
import re
@@ -19,10 +23,10 @@ else:
unicode = str
long = int
class Junit(py.xml.Namespace):
pass
# We need to get the subset of the invalid unicode ranges according to
# XML 1.0 which are valid in this python build. Hence we calculate
# this dynamically instead of hardcoding it. The spec range of valid
@@ -30,21 +34,19 @@ class Junit(py.xml.Namespace):
# | [#x10000-#x10FFFF]
_legal_chars = (0x09, 0x0A, 0x0d)
_legal_ranges = (
(0x20, 0x7E),
(0x80, 0xD7FF),
(0xE000, 0xFFFD),
(0x10000, 0x10FFFF),
(0x20, 0x7E), (0x80, 0xD7FF), (0xE000, 0xFFFD), (0x10000, 0x10FFFF),
)
_legal_xml_re = [unicode("%s-%s") % (unichr(low), unichr(high))
for (low, high) in _legal_ranges
if low < sys.maxunicode]
_legal_xml_re = [
unicode("%s-%s") % (unichr(low), unichr(high))
for (low, high) in _legal_ranges if low < sys.maxunicode
]
_legal_xml_re = [unichr(x) for x in _legal_chars] + _legal_xml_re
illegal_xml_re = re.compile(unicode('[^%s]') %
unicode('').join(_legal_xml_re))
illegal_xml_re = re.compile(unicode('[^%s]') % unicode('').join(_legal_xml_re))
del _legal_chars
del _legal_ranges
del _legal_xml_re
def bin_xml_escape(arg):
def repl(matchobj):
i = ord(matchobj.group())
@@ -52,122 +54,90 @@ def bin_xml_escape(arg):
return unicode('#x%02X') % i
else:
return unicode('#x%04X') % i
return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg)))
@pytest.fixture
def record_xml_property(request):
"""Fixture that adds extra xml properties to the tag for the calling test.
The fixture is callable with (name, value), with value being automatically
xml-encoded.
"""
def inner(name, value):
if hasattr(request.config, "_xml"):
request.config._xml.add_custom_property(name, value)
msg = 'record_xml_property is an experimental feature'
request.config.warn(code='C3', message=msg,
fslocation=request.node.location[:2])
return inner
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group.addoption('--junitxml', '--junit-xml', action="store",
dest="xmlpath", metavar="path", default=None,
help="create junit-xml style report file at given path.")
group.addoption('--junitprefix', '--junit-prefix', action="store",
metavar="str", default=None,
help="prepend prefix to classnames in junit-xml output")
class _NodeReporter(object):
def __init__(self, nodeid, xml):
def pytest_configure(config):
xmlpath = config.option.xmlpath
# prevent opening xmllog on slave nodes (xdist)
if xmlpath and not hasattr(config, 'slaveinput'):
config._xml = LogXML(xmlpath, config.option.junitprefix)
config.pluginmanager.register(config._xml)
self.id = nodeid
self.xml = xml
self.add_stats = self.xml.add_stats
self.duration = 0
self.properties = {}
self.property_insert_order = []
self.nodes = []
self.testcase = None
self.attrs = {}
def pytest_unconfigure(config):
xml = getattr(config, '_xml', None)
if xml:
del config._xml
config.pluginmanager.unregister(xml)
def append(self, node):
self.xml.add_stats(type(node).__name__)
self.nodes.append(node)
def mangle_testnames(names):
names = [x.replace(".py", "") for x in names if x != '()']
names[0] = names[0].replace("/", '.')
return names
def add_property(self, name, value):
name = str(name)
if name not in self.property_insert_order:
self.property_insert_order.append(name)
self.properties[name] = bin_xml_escape(value)
class LogXML(object):
def __init__(self, logfile, prefix):
logfile = os.path.expanduser(os.path.expandvars(logfile))
self.logfile = os.path.normpath(os.path.abspath(logfile))
self.prefix = prefix
self.tests = []
self.tests_by_nodeid = {} # nodeid -> Junit.testcase
self.durations = {} # nodeid -> total duration (setup+call+teardown)
self.passed = self.skipped = 0
self.failed = self.errors = 0
self.custom_properties = {}
def make_properties_node(self):
"""Return a Junit node containing custom properties, if any.
"""
if self.properties:
return Junit.properties([
Junit.property(name=name, value=self.properties[name])
for name in self.property_insert_order
])
return ''
def add_custom_property(self, name, value):
self.custom_properties[str(name)] = bin_xml_escape(str(value))
def _opentestcase(self, report):
names = mangle_testnames(report.nodeid.split("::"))
def record_testreport(self, testreport):
assert not self.testcase
names = mangle_testnames(testreport.nodeid.split("::"))
classnames = names[:-1]
if self.prefix:
classnames.insert(0, self.prefix)
if self.xml.prefix:
classnames.insert(0, self.xml.prefix)
attrs = {
"classname": ".".join(classnames),
"name": bin_xml_escape(names[-1]),
"file": report.location[0],
"time": self.durations.get(report.nodeid, 0),
"file": testreport.location[0],
}
if report.location[1] is not None:
attrs["line"] = report.location[1]
testcase = Junit.testcase(**attrs)
custom_properties = self.pop_custom_properties()
if custom_properties:
testcase.append(custom_properties)
self.tests.append(testcase)
self.tests_by_nodeid[report.nodeid] = testcase
if testreport.location[1] is not None:
attrs["line"] = testreport.location[1]
self.attrs = attrs
def to_xml(self):
testcase = Junit.testcase(time=self.duration, **self.attrs)
testcase.append(self.make_properties_node())
for node in self.nodes:
testcase.append(node)
return testcase
def _add_simple(self, kind, message, data=None):
data = bin_xml_escape(data)
node = kind(data, message=message)
self.append(node)
def _write_captured_output(self, report):
for capname in ('out', 'err'):
allcontent = ""
for name, content in report.get_sections("Captured std%s" %
capname):
capname):
allcontent += content
if allcontent:
tag = getattr(Junit, 'system-'+capname)
tag = getattr(Junit, 'system-' + capname)
self.append(tag(bin_xml_escape(allcontent)))
def append(self, obj):
self.tests[-1].append(obj)
def pop_custom_properties(self):
"""Return a Junit node containing custom properties set for
the current test, if any, and reset the current custom properties.
"""
if self.custom_properties:
result = Junit.properties(
[
Junit.property(name=name, value=value)
for name, value in self.custom_properties.items()
]
)
self.custom_properties.clear()
return result
return None
def append_pass(self, report):
self.passed += 1
self.add_stats('passed')
self._write_captured_output(report)
def append_failure(self, report):
#msg = str(report.longrepr.reprtraceback.extraline)
# msg = str(report.longrepr.reprtraceback.extraline)
if hasattr(report, "wasxfail"):
self.append(
Junit.skipped(message="xfail-marked test passes unexpectedly"))
self.skipped += 1
self._add_simple(
Junit.skipped,
"xfail-marked test passes unexpectedly")
else:
if hasattr(report.longrepr, "reprcrash"):
message = report.longrepr.reprcrash.message
@@ -179,30 +149,27 @@ class LogXML(object):
fail = Junit.failure(message=message)
fail.append(bin_xml_escape(report.longrepr))
self.append(fail)
self.failed += 1
self._write_captured_output(report)
def append_collect_error(self, report):
#msg = str(report.longrepr.reprtraceback.extraline)
# msg = str(report.longrepr.reprtraceback.extraline)
self.append(Junit.error(bin_xml_escape(report.longrepr),
message="collection failure"))
self.errors += 1
def append_collect_skipped(self, report):
#msg = str(report.longrepr.reprtraceback.extraline)
self.append(Junit.skipped(bin_xml_escape(report.longrepr),
message="collection skipped"))
self.skipped += 1
self._add_simple(
Junit.skipped, "collection skipped", report.longrepr)
def append_error(self, report):
self.append(Junit.error(bin_xml_escape(report.longrepr),
message="test setup failure"))
self.errors += 1
self._add_simple(
Junit.error, "test setup failure", report.longrepr)
self._write_captured_output(report)
def append_skipped(self, report):
if hasattr(report, "wasxfail"):
self.append(Junit.skipped(bin_xml_escape(report.wasxfail),
message="expected test failure"))
self._add_simple(
Junit.skipped, "expected test failure", report.wasxfail
)
else:
filename, lineno, skipreason = report.longrepr
if skipreason.startswith("Skipped: "):
@@ -210,11 +177,120 @@ class LogXML(object):
self.append(
Junit.skipped("%s:%s: %s" % (filename, lineno, skipreason),
type="pytest.skip",
message=skipreason
))
self.skipped += 1
message=skipreason))
self._write_captured_output(report)
def finalize(self):
data = self.to_xml().unicode(indent=0)
self.__dict__.clear()
self.to_xml = lambda: py.xml.raw(data)
@pytest.fixture
def record_xml_property(request):
"""Fixture that adds extra xml properties to the tag for the calling test.
The fixture is callable with (name, value), with value being automatically
xml-encoded.
"""
request.node.warn(
code='C3',
message='record_xml_property is an experimental feature',
)
xml = getattr(request.config, "_xml", None)
if xml is not None:
node_reporter = xml.node_reporter(request.node.nodeid)
return node_reporter.add_property
else:
def add_property_noop(name, value):
pass
return add_property_noop
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group.addoption(
'--junitxml', '--junit-xml',
action="store",
dest="xmlpath",
metavar="path",
default=None,
help="create junit-xml style report file at given path.")
group.addoption(
'--junitprefix', '--junit-prefix',
action="store",
metavar="str",
default=None,
help="prepend prefix to classnames in junit-xml output")
def pytest_configure(config):
xmlpath = config.option.xmlpath
# prevent opening xmllog on slave nodes (xdist)
if xmlpath and not hasattr(config, 'slaveinput'):
config._xml = LogXML(xmlpath, config.option.junitprefix)
config.pluginmanager.register(config._xml)
def pytest_unconfigure(config):
xml = getattr(config, '_xml', None)
if xml:
del config._xml
config.pluginmanager.unregister(xml)
def mangle_testnames(names):
names = [x.replace(".py", "") for x in names if x != '()']
names[0] = names[0].replace("/", '.')
return names
class LogXML(object):
def __init__(self, logfile, prefix):
logfile = os.path.expanduser(os.path.expandvars(logfile))
self.logfile = os.path.normpath(os.path.abspath(logfile))
self.prefix = prefix
self.stats = dict.fromkeys([
'error',
'passed',
'failure',
'skipped',
], 0)
self.node_reporters = {} # nodeid -> _NodeReporter
self.node_reporters_ordered = []
def finalize(self, report):
nodeid = getattr(report, 'nodeid', report)
# local hack to handle xdist report order
slavenode = getattr(report, 'node', None)
reporter = self.node_reporters.pop((nodeid, slavenode))
if reporter is not None:
reporter.finalize()
def node_reporter(self, report):
nodeid = getattr(report, 'nodeid', report)
# local hack to handle xdist report order
slavenode = getattr(report, 'node', None)
key = nodeid, slavenode
if key in self.node_reporters:
# TODO: breasks for --dist=each
return self.node_reporters[key]
reporter = _NodeReporter(nodeid, self)
self.node_reporters[key] = reporter
self.node_reporters_ordered.append(reporter)
return reporter
def add_stats(self, key):
if key in self.stats:
self.stats[key] += 1
def _opentestcase(self, report):
reporter = self.node_reporter(report)
reporter.record_testreport(report)
return reporter
def pytest_runtest_logreport(self, report):
"""handle a setup/call/teardown report, generating the appropriate
xml tags as necessary.
@@ -240,47 +316,40 @@ class LogXML(object):
"""
if report.passed:
if report.when == "call": # ignore setup/teardown
self._opentestcase(report)
self.append_pass(report)
reporter = self._opentestcase(report)
reporter.append_pass(report)
elif report.failed:
self._opentestcase(report)
if report.when != "call":
self.append_error(report)
reporter = self._opentestcase(report)
if report.when == "call":
reporter.append_failure(report)
else:
self.append_failure(report)
reporter.append_error(report)
elif report.skipped:
self._opentestcase(report)
self.append_skipped(report)
reporter = self._opentestcase(report)
reporter.append_skipped(report)
self.update_testcase_duration(report)
if report.when == "teardown":
self.finalize(report)
def update_testcase_duration(self, report):
"""accumulates total duration for nodeid from given report and updates
the Junit.testcase with the new total if already created.
"""
total = self.durations.get(report.nodeid, 0.0)
total += getattr(report, 'duration', 0.0)
self.durations[report.nodeid] = total
testcase = self.tests_by_nodeid.get(report.nodeid)
if testcase is not None:
testcase.attr.time = total
reporter = self.node_reporter(report)
reporter.duration += getattr(report, 'duration', 0.0)
def pytest_collectreport(self, report):
if not report.passed:
self._opentestcase(report)
reporter = self._opentestcase(report)
if report.failed:
self.append_collect_error(report)
reporter.append_collect_error(report)
else:
self.append_collect_skipped(report)
reporter.append_collect_skipped(report)
def pytest_internalerror(self, excrepr):
self.errors += 1
data = bin_xml_escape(excrepr)
self.tests.append(
Junit.testcase(
Junit.error(data, message="internal error"),
classname="pytest",
name="internal"))
reporter = self.node_reporter('internal')
reporter.attrs.update(classname="pytest", name='internal')
reporter._add_simple(Junit.error, 'internal error', excrepr)
def pytest_sessionstart(self):
self.suite_start_time = time.time()
@@ -292,19 +361,20 @@ class LogXML(object):
logfile = open(self.logfile, 'w', encoding='utf-8')
suite_stop_time = time.time()
suite_time_delta = suite_stop_time - self.suite_start_time
numtests = self.passed + self.failed
numtests = self.stats['passed'] + self.stats['failure']
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
logfile.write(Junit.testsuite(
self.tests,
[x.to_xml() for x in self.node_reporters_ordered],
name="pytest",
errors=self.errors,
failures=self.failed,
skips=self.skipped,
errors=self.stats['error'],
failures=self.stats['failure'],
skips=self.stats['skipped'],
tests=numtests,
time="%.3f" % suite_time_delta,
).unicode(indent=0))
time="%.3f" % suite_time_delta, ).unicode(indent=0))
logfile.close()
def pytest_terminal_summary(self, terminalreporter):
terminalreporter.write_sep("-", "generated xml file: %s" % (self.logfile))
terminalreporter.write_sep("-",
"generated xml file: %s" % (self.logfile))

View File

@@ -1,8 +1,13 @@
""" monkeypatching and mocking functionality. """
import os, sys
import re
from py.builtin import _basestring
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
def pytest_funcarg__monkeypatch(request):
"""The returned ``monkeypatch`` funcarg provides these
helper methods to modify objects, dictionaries or os.environ::
@@ -26,48 +31,71 @@ def pytest_funcarg__monkeypatch(request):
return mpatch
def resolve(name):
# simplified from zope.dottedname
parts = name.split('.')
used = parts.pop(0)
found = __import__(used)
for part in parts:
used += '.' + part
try:
found = getattr(found, part)
except AttributeError:
pass
else:
continue
# we use explicit un-nesting of the handling block in order
# to avoid nested exceptions on python 3
try:
__import__(used)
except ImportError as ex:
# str is used for py2 vs py3
expected = str(ex).split()[-1]
if expected == used:
raise
else:
raise ImportError(
'import error in %s: %s' % (used, ex)
)
found = annotated_getattr(found, part, used)
return found
def annotated_getattr(obj, name, ann):
try:
obj = getattr(obj, name)
except AttributeError:
raise AttributeError(
'%r object at %s has no attribute %r' % (
type(obj).__name__, ann, name
)
)
return obj
def derive_importpath(import_path, raising):
import pytest
if not isinstance(import_path, _basestring) or "." not in import_path:
raise TypeError("must be absolute import path string, not %r" %
(import_path,))
rest = []
target = import_path
while target:
try:
obj = __import__(target, None, None, "__doc__")
except ImportError:
if "." not in target:
__tracebackhide__ = True
pytest.fail("could not import any sub part: %s" %
import_path)
target, name = target.rsplit(".", 1)
rest.append(name)
else:
assert rest
try:
while len(rest) > 1:
attr = rest.pop()
obj = getattr(obj, attr)
attr = rest[0]
if raising:
getattr(obj, attr)
except AttributeError:
__tracebackhide__ = True
pytest.fail("object %r has no attribute %r" % (obj, attr))
return attr, obj
module, attr = import_path.rsplit('.', 1)
target = resolve(module)
if raising:
annotated_getattr(target, attr, ann=module)
return attr, target
class Notset:
def __repr__(self):
return "<notset>"
notset = Notset()
class monkeypatch:
""" Object keeping a record of setattr/item/env/syspath changes. """
def __init__(self):
self._setattr = []
self._setitem = []
@@ -94,19 +122,19 @@ class monkeypatch:
if value is notset:
if not isinstance(target, _basestring):
raise TypeError("use setattr(target, name, value) or "
"setattr(target, value) with target being a dotted "
"import string")
"setattr(target, value) with target being a dotted "
"import string")
value = name
name, target = derive_importpath(target, raising)
oldval = getattr(target, name, notset)
if raising and oldval is notset:
raise AttributeError("%r has no attribute %r" %(target, name))
raise AttributeError("%r has no attribute %r" % (target, name))
# avoid class descriptors like staticmethod/classmethod
if inspect.isclass(target):
oldval = target.__dict__.get(name, notset)
self._setattr.insert(0, (target, name, oldval))
self._setattr.append((target, name, oldval))
setattr(target, name, value)
def delattr(self, target, name=notset, raising=True):
@@ -132,13 +160,12 @@ class monkeypatch:
if raising:
raise AttributeError(name)
else:
self._setattr.insert(0, (target, name,
getattr(target, name, notset)))
self._setattr.append((target, name, getattr(target, name, notset)))
delattr(target, name)
def setitem(self, dic, name, value):
""" Set dictionary entry ``name`` to value. """
self._setitem.insert(0, (dic, name, dic.get(name, notset)))
self._setitem.append((dic, name, dic.get(name, notset)))
dic[name] = value
def delitem(self, dic, name, raising=True):
@@ -151,7 +178,7 @@ class monkeypatch:
if raising:
raise KeyError(name)
else:
self._setitem.insert(0, (dic, name, dic.get(name, notset)))
self._setitem.append((dic, name, dic.get(name, notset)))
del dic[name]
def setenv(self, name, value, prepend=None):
@@ -203,18 +230,18 @@ class monkeypatch:
calling `undo()` will undo all of the changes made in
both functions.
"""
for obj, name, value in self._setattr:
for obj, name, value in reversed(self._setattr):
if value is not notset:
setattr(obj, name, value)
else:
delattr(obj, name)
self._setattr[:] = []
for dictionary, name, value in self._setitem:
for dictionary, name, value in reversed(self._setitem):
if value is notset:
try:
del dictionary[name]
except KeyError:
pass # was already deleted, so we have the desired state
pass # was already deleted, so we have the desired state
else:
dictionary[name] = value
self._setitem[:] = []

View File

@@ -53,7 +53,9 @@ class PdbInvoke:
def pytest_exception_interact(self, node, call, report):
capman = node.config.pluginmanager.getplugin("capturemanager")
if capman:
capman.suspendcapture(in_=True)
out, err = capman.suspendcapture(in_=True)
sys.stdout.write(out)
sys.stdout.write(err)
_enter_pdb(node, call.excinfo, report)
def pytest_internalerror(self, excrepr, excinfo):

View File

@@ -416,8 +416,8 @@ class PyCollector(PyobjMixin, pytest.Collector):
def istestfunction(self, obj, name):
return (
(self.funcnamefilter(name) or self.isnosetest(obj))
and safe_getattr(obj, "__call__", False) and getfixturemarker(obj) is None
(self.funcnamefilter(name) or self.isnosetest(obj)) and
safe_getattr(obj, "__call__", False) and getfixturemarker(obj) is None
)
def istestclass(self, obj, name):
@@ -451,7 +451,7 @@ class PyCollector(PyobjMixin, pytest.Collector):
seen = {}
l = []
for dic in dicts:
for name, obj in dic.items():
for name, obj in list(dic.items()):
if name in seen:
continue
seen[name] = True
@@ -1765,8 +1765,10 @@ class FixtureLookupError(LookupError):
stack.extend(map(lambda x: x.func, self.fixturestack))
msg = self.msg
if msg is not None:
stack = stack[:-1] # the last fixture raise an error, let's present
# it at the requesting side
# the last fixture raise an error, let's present
# it at the requesting side
stack = stack[:-1]
for function in stack:
fspath, lineno = getfslineno(function)
try:

View File

@@ -42,7 +42,7 @@ def deprecated_call(func, *args, **kwargs):
categories.append(category)
old_warn_explicit(message, category, *args, **kwargs)
def warn(message, category=None, **kwargs):
def warn(message, category=None, *args, **kwargs):
if isinstance(message, Warning):
categories.append(message.__class__)
else:

View File

@@ -364,10 +364,10 @@ class TerminalReporter:
EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, EXIT_USAGEERROR,
EXIT_NOTESTSCOLLECTED)
if exitstatus in summary_exit_codes:
self.config.hook.pytest_terminal_summary(terminalreporter=self)
self.summary_errors()
self.summary_failures()
self.summary_warnings()
self.config.hook.pytest_terminal_summary(terminalreporter=self)
if exitstatus == EXIT_INTERRUPTED:
self._report_keyboardinterrupt()
del self._keyboardinterrupt_memo

View File

@@ -24,9 +24,10 @@ def pytest_pycollect_makeitem(collector, name, obj):
class UnitTestCase(pytest.Class):
nofuncargs = True # marker for fixturemanger.getfixtureinfo()
# to declare that our children do not support funcargs
#
# marker for fixturemanger.getfixtureinfo()
# to declare that our children do not support funcargs
nofuncargs = True
def setup(self):
cls = self.obj
if getattr(cls, '__unittest_skip__', False):

View File

@@ -1,98 +1,19 @@
environment:
matrix:
# Pre-installed Python versions, which Appveyor may upgrade to
# a later point release.
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
TESTENV: "py27"
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "64"
TESTENV: "py27"
- PYTHON: "C:\\Python33"
PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "32"
TESTENV: "py33"
- PYTHON: "C:\\Python33-x64"
PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "64"
TESTENV: "py33"
- PYTHON: "C:\\Python34"
PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "32"
TESTENV: "py34"
- PYTHON: "C:\\Python34-x64"
PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "64"
TESTENV: "py34"
- PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.x" # currently 3.5.0
PYTHON_ARCH: "32"
TESTENV: "py35"
- PYTHON: "C:\\Python35-x64"
PYTHON_VERSION: "3.5.x" # currently 3.5.0
PYTHON_ARCH: "64"
TESTENV: "py35"
# Also test a Python version not pre-installed
# See: https://github.com/ogrisel/python-appveyor-demo/issues/10
- PYTHON: "C:\\Python266"
PYTHON_VERSION: "2.6.6"
PYTHON_ARCH: "32"
TESTENV: "py26"
# xdist testing
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
TESTENV: "py27-xdist"
- PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.x" # currently 3.5.0
PYTHON_ARCH: "32"
TESTENV: "py35-xdist"
install:
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- echo Installed Pythons
- dir c:\Python*
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
# Install Python (from the official .msi of http://python.org) and pip when
# not already installed.
- ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
# Prepend newly installed Python to the PATH of this build (this cannot be
# done from inside the powershell script as it would require to restart
# the parent CMD process).
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
# Install the build dependencies of the project. If some dependencies contain
# compiled extensions and are not provided as pre-built wheel packages,
# pip will build them from source using the MSVC compiler matching the
# target Python version and architecture
- C:\Python27\python -m pip install tox
- C:\Python35\python -m pip install tox
build: false # Not a C# project, build stuff at the test step instead.
test_script:
# Build the compiled extension and run the project tests
- C:\Python27\python -m tox -e %TESTENV%
- 'set TESTENVS=
flakes,
py26,
py27,
py33,
py34,
py27-xdist,
py35-xdist
'
- C:\Python35\python -m tox -e "%TESTENVS%"

View File

@@ -1,180 +0,0 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus and Kyle Kastner
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"
function DownloadPython ($python_version, $platform_suffix) {
$webclient = New-Object System.Net.WebClient
$filename = "python-" + $python_version + $platform_suffix + ".msi"
$url = $BASE_URL + $python_version + "/" + $filename
$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}
# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for($i=0; $i -lt $retry_attempts; $i++){
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}
function InstallPython ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = ""
} else {
$platform_suffix = ".amd64"
}
$msipath = DownloadPython $python_version $platform_suffix
Write-Host "Installing" $msipath "to" $python_home
$install_log = $python_home + ".log"
$install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
$uninstall_args = "/qn /x $msipath"
RunCommand "msiexec.exe" $install_args
if (-not(Test-Path $python_home)) {
Write-Host "Python seems to be installed else-where, reinstalling."
RunCommand "msiexec.exe" $uninstall_args
RunCommand "msiexec.exe" $install_args
}
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function RunCommand ($command, $command_args) {
Write-Host $command $command_args
Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
}
function InstallPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$python_path = $python_home + "\python.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
Write-Host "Executing:" $python_path $GET_PIP_PATH
Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}
function DownloadMiniconda ($python_version, $platform_suffix) {
$webclient = New-Object System.Net.WebClient
if ($python_version -eq "3.4") {
$filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
} else {
$filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
}
$url = $MINICONDA_URL + $filename
$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}
# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for($i=0; $i -lt $retry_attempts; $i++){
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}
function InstallMiniconda ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = "x86"
} else {
$platform_suffix = "x86_64"
}
$filepath = DownloadMiniconda $python_version $platform_suffix
Write-Host "Installing" $filepath "to" $python_home
$install_log = $python_home + ".log"
$args = "/S /D=$python_home"
Write-Host $filepath $args
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallMinicondaPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$conda_path = $python_home + "\Scripts\conda.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$args = "install --yes pip"
Write-Host $conda_path $args
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}
function main () {
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
InstallPip $env:PYTHON
}
main

View File

@@ -4,7 +4,7 @@
<li><a href="{{ pathto('contributing') }}">Contribution Guide</a></li>
<li><a href="https://pypi.python.org/pypi/pytest">pytest @ PyPI</a></li>
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</a></li>
<li><a href="http://pytest.org/latest/plugins_index/index.html">3rd party plugins</a></li>
<li><a href="http://plugincompat.herokuapp.com/">3rd party plugins</a></li>
<li><a href="https://github.com/pytest-dev/pytest/issues">Issue Tracker</a></li>
<li><a href="http://pytest.org/latest/pytest.pdf">PDF Documentation</a>
</ul>

View File

@@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2
release-2.8.6
release-2.8.5
release-2.8.4
release-2.8.3
release-2.8.2

View File

@@ -0,0 +1,39 @@
pytest-2.8.5
============
pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.
This release is supposed to be drop-in compatible to 2.8.4.
See below for the changes and see docs at:
http://pytest.org
As usual, you can upgrade from pypi via::
pip install -U pytest
Thanks to all who contributed to this release, among them:
Alex Gaynor
aselus-hub
Bruno Oliveira
Ronny Pfannschmidt
Happy testing,
The py.test Development Team
2.8.5 (compared to 2.8.4)
-------------------------
- fix #1243: fixed issue where class attributes injected during collection could break pytest.
PR by Alexei Kozlenok, thanks Ronny Pfannschmidt and Bruno Oliveira for the review and help.
- fix #1074: precompute junitxml chunks instead of storing the whole tree in objects
Thanks Bruno Oliveira for the report and Ronny Pfannschmidt for the PR
- fix #1238: fix ``pytest.deprecated_call()`` receiving multiple arguments
(Regression introduced in 2.8.4). Thanks Alex Gaynor for the report and
Bruno Oliveira for the PR.

View File

@@ -0,0 +1,67 @@
pytest-2.8.6
============
pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.
This release is supposed to be drop-in compatible to 2.8.5.
See below for the changes and see docs at:
http://pytest.org
As usual, you can upgrade from pypi via::
pip install -U pytest
Thanks to all who contributed to this release, among them:
AMiT Kumar
Bruno Oliveira
Erik M. Bray
Florian Bruhin
Georgy Dyuldin
Jeff Widman
Kartik Singhal
Loïc Estève
Manu Phatak
Peter Demin
Rick van Hattem
Ronny Pfannschmidt
Ulrich Petri
foxx
Happy testing,
The py.test Development Team
2.8.6 (compared to 2.8.5)
-------------------------
- fix #1259: allow for double nodeids in junitxml,
this was a regression failing plugins combinations
like pytest-pep8 + pytest-flakes
- Workaround for exception that occurs in pyreadline when using
``--pdb`` with standard I/O capture enabled.
Thanks Erik M. Bray for the PR.
- fix #900: Better error message in case the target of a ``monkeypatch`` call
raises an ``ImportError``.
- fix #1292: monkeypatch calls (setattr, setenv, etc.) are now O(1).
Thanks David R. MacIver for the report and Bruno Oliveira for the PR.
- fix #1223: captured stdout and stderr are now properly displayed before
entering pdb when ``--pdb`` is used instead of being thrown away.
Thanks Cal Leeming for the PR.
- fix #1305: pytest warnings emitted during ``pytest_terminal_summary`` are now
properly displayed.
Thanks Ionel Maries Cristian for the report and Bruno Oliveira for the PR.
- fix #628: fixed internal UnicodeDecodeError when doctests contain unicode.
Thanks Jason R. Coombs for the report and Bruno Oliveira for the PR.
- fix #1334: Add captured stdout to jUnit XML report on setup error.
Thanks Georgy Dyuldin for the PR.

View File

@@ -0,0 +1,31 @@
pytest-2.8.7
============
This is a hotfix release to solve a regression
in the builtin monkeypatch plugin that got introduced in 2.8.6.
pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.
This release is supposed to be drop-in compatible to 2.8.5.
See below for the changes and see docs at:
http://pytest.org
As usual, you can upgrade from pypi via::
pip install -U pytest
Thanks to all who contributed to this release, among them:
Ronny Pfannschmidt
Happy testing,
The py.test Development Team
2.8.7 (compared to 2.8.6)
-------------------------
- fix #1338: use predictable object resolution for monkeypatch

View File

@@ -26,7 +26,7 @@ you will see the return value of the function call::
$ py.test test_assert1.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -146,7 +146,7 @@ if you run this module::
$ py.test test_assert2.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -80,7 +80,7 @@ If you then run it with ``--lf``::
$ py.test --lf
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
run-last-failure: rerun last 2 failures
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -121,7 +121,7 @@ of ``FF`` and dots)::
$ py.test --ff
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
run-last-failure: rerun last 2 failures first
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -226,7 +226,7 @@ You can always peek at the content of the cache using the
$ py.test --cache-clear
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -64,7 +64,7 @@ of the failing function and hide the other one::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -16,7 +16,6 @@ Full pytest documentation
plugins
cache
contributing
plugins_index/index
talks
.. only:: html

View File

@@ -46,7 +46,7 @@ then you can just invoke ``py.test`` without command line options::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items

View File

@@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
$ py.test -v -m webtest
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -45,7 +45,7 @@ Or the inverse, running all tests except the webtest ones::
$ py.test -v -m "not webtest"
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -66,7 +66,7 @@ tests based on their module, class, method, or function name::
$ py.test -v test_server.py::TestClass::test_method
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 5 items
@@ -79,7 +79,7 @@ You can also select on the class::
$ py.test -v test_server.py::TestClass
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -92,7 +92,7 @@ Or select multiple nodes::
$ py.test -v test_server.py::TestClass test_server.py::test_send_http
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items
@@ -130,7 +130,7 @@ select tests based on their names::
$ py.test -v -k http # running with the above defined example module
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -144,7 +144,7 @@ And you can also run all tests except the ones that match the keyword::
$ py.test -k "not send_http" -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -160,7 +160,7 @@ Or to select "http" and "quick" tests::
$ py.test -k "http or quick" -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -350,7 +350,7 @@ the test needs::
$ py.test -E stage2
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -362,7 +362,7 @@ and here is one that specifies exactly the environment needed::
$ py.test -E stage1
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -436,7 +436,7 @@ marking platform specific tests with pytest
.. regendoc:wipe
Consider you have a test suite which marks tests for particular platforms,
namely ``pytest.mark.osx``, ``pytest.mark.win32`` etc. and you
namely ``pytest.mark.darwin``, ``pytest.mark.win32`` etc. and you
also have tests that run on all platforms and have no specific
marker. If you now want to have a way to only run the tests
for your particular platform, you could use the following plugin::
@@ -446,7 +446,7 @@ for your particular platform, you could use the following plugin::
import sys
import pytest
ALL = set("osx linux2 win32".split())
ALL = set("darwin linux2 win32".split())
def pytest_runtest_setup(item):
if isinstance(item, item.Function):
@@ -462,7 +462,7 @@ Let's do a little test file to show how this looks like::
import pytest
@pytest.mark.osx
@pytest.mark.darwin
def test_if_apple_is_evil():
pass
@@ -481,7 +481,7 @@ then you will see two test skipped and two executed tests as expected::
$ py.test -rs # this option reports skip reasons
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -495,7 +495,7 @@ Note that if you specify a platform via the marker-command line option like this
$ py.test -m linux2
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -547,7 +547,7 @@ We can now use the ``-m option`` to select one set::
$ py.test -m interface --tb=short
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -569,7 +569,7 @@ or to select both "event" and "interface" tests::
$ py.test -m "interface or event" --tb=short
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items

View File

@@ -27,11 +27,11 @@ now execute the test specification::
nonpython $ py.test test_simple.yml
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
test_simple.yml .F
test_simple.yml F.
======= FAILURES ========
_______ usecase: hello ________
@@ -59,13 +59,13 @@ consulted when reporting in ``verbose`` mode::
nonpython $ py.test -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collecting ... collected 2 items
test_simple.yml::ok PASSED
test_simple.yml::hello FAILED
test_simple.yml::ok PASSED
======= FAILURES ========
_______ usecase: hello ________
@@ -81,11 +81,11 @@ interesting to just look at the collection tree::
nonpython $ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
<YamlFile 'test_simple.yml'>
<YamlItem 'ok'>
<YamlItem 'hello'>
<YamlItem 'ok'>
======= no tests ran in 0.12 seconds ========

View File

@@ -130,7 +130,7 @@ objects, they are still using the default pytest representation::
$ py.test test_time.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 6 items
<Module 'test_time.py'>
@@ -181,7 +181,7 @@ this is a fully self-contained example which you can run with::
$ py.test test_scenarios.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -194,7 +194,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ py.test --collect-only test_scenarios.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
<Module 'test_scenarios.py'>
@@ -259,7 +259,7 @@ Let's first see how it looks like at collection time::
$ py.test test_backends.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
<Module 'test_backends.py'>
@@ -320,7 +320,7 @@ The result of this test will be successful::
$ py.test test_indirect_list.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
<Module 'test_indirect_list.py'>
@@ -333,7 +333,7 @@ The result of this test will be successful::
Parametrizing test methods through per-class configuration
--------------------------------------------------------------
.. _`unittest parametrizer`: http://code.google.com/p/unittest-ext/source/browse/trunk/params.py
.. _`unittest parametrizer`: https://github.com/testing-cabal/unittest-ext/blob/master/params.py
Here is an example ``pytest_generate_function`` function implementing a
@@ -369,7 +369,7 @@ argument sets to use for each test function. Let's run it::
$ py.test -q
F..
======= FAILURES ========
_______ TestClass.test_equals[2-1] ________
_______ TestClass.test_equals[1-2] ________
self = <test_parametrize.TestClass object at 0xdeadbeef>, a = 1, b = 2
@@ -397,11 +397,8 @@ is to be run with different sets of arguments for its three arguments:
Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize)::
. $ py.test -rs -q multipython.py
ssssssssssss...ssssssssssss
======= short test summary info ========
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:22: 'python2.6' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:22: 'python3.3' not found
3 passed, 24 skipped in 0.12 seconds
...........................
27 passed in 0.12 seconds
Indirect parametrization of optional implementations/imports
--------------------------------------------------------------------
@@ -448,7 +445,7 @@ If you run this with reporting for skips enabled::
$ py.test -rs test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -82,7 +82,7 @@ then the test collection looks like this::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: setup.cfg
collected 2 items
<Module 'check_myapp.py'>
@@ -128,7 +128,7 @@ You can always peek at the collection tree without running tests like this::
. $ py.test --collect-only pythoncollection.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 3 items
<Module 'CWD/pythoncollection.py'>
@@ -182,7 +182,7 @@ interpreters and will leave out the setup.py file::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 0 items

View File

@@ -13,7 +13,7 @@ get on the terminal - we are working on that):
assertion $ py.test failure_demo.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/assertion, inifile:
collected 42 items

View File

@@ -108,7 +108,7 @@ directory with the above conftest.py::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -156,7 +156,7 @@ and when running it will see a skipped "slow" test::
$ py.test -rs # "-rs" means report details on the little 's'
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -170,7 +170,7 @@ Or run it including the ``slow`` marked test::
$ py.test --runslow
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -262,7 +262,7 @@ which will add the string to the test header accordingly::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
project deps: mylib-1.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -286,7 +286,7 @@ which will add info only when run with "--v"::
$ py.test -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
info1: did you know that ...
did you?
@@ -299,7 +299,7 @@ and nothing when run plainly::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
@@ -332,7 +332,7 @@ Now we can profile which test functions execute the slowest::
$ py.test --durations=3
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -341,7 +341,7 @@ Now we can profile which test functions execute the slowest::
======= slowest 3 test durations ========
0.20s call test_some_are_slow.py::test_funcslow2
0.10s call test_some_are_slow.py::test_funcslow1
0.00s teardown test_some_are_slow.py::test_funcslow2
0.00s setup test_some_are_slow.py::test_funcslow2
======= 3 passed in 0.12 seconds ========
incremental testing - test steps
@@ -394,11 +394,14 @@ If we run this::
$ py.test -rx
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
test_step.py .Fx.
======= short test summary info ========
XFAIL test_step.py::TestUserHandling::()::test_deletion
reason: previous test failed (test_modification)
======= FAILURES ========
_______ TestUserHandling.test_modification ________
@@ -410,9 +413,6 @@ If we run this::
E assert 0
test_step.py:9: AssertionError
======= short test summary info ========
XFAIL test_step.py::TestUserHandling::()::test_deletion
reason: previous test failed (test_modification)
======= 1 failed, 2 passed, 1 xfailed in 0.12 seconds ========
We'll see that ``test_deletion`` was not executed because ``test_modification``
@@ -465,7 +465,7 @@ We can run this::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 7 items
@@ -479,7 +479,7 @@ We can run this::
file $REGENDOC_TMPDIR/b/test_error.py, line 1
def test_root(db): # no db here, will error out
fixture 'db' not found
available fixtures: tmpdir, record_xml_property, cache, capsys, monkeypatch, recwarn, pytestconfig, tmpdir_factory, capfd
available fixtures: record_xml_property, pytestconfig, cache, capsys, recwarn, monkeypatch, tmpdir, capfd, tmpdir_factory
use 'py.test --fixtures [testpath]' for help on them.
$REGENDOC_TMPDIR/b/test_error.py:1
@@ -569,7 +569,7 @@ and run them::
$ py.test test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -660,7 +660,7 @@ and run it::
$ py.test -s test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items

View File

@@ -121,7 +121,7 @@ in a managed class/module/function scope.
.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
Can I yield multiple values from a fixture function function?
Can I yield multiple values from a fixture function?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
There are two conceptual reasons why yielding from a factory function

View File

@@ -75,7 +75,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
$ py.test test_smtpsimple.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -193,7 +193,7 @@ inspect what is going on and can now run the tests::
$ py.test test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -480,7 +480,7 @@ Running the above tests results in the following test IDs being used::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 10 items
<Module 'test_anothersmtp.py'>
@@ -531,7 +531,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ py.test -v test_appsetup.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items
@@ -597,7 +597,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
$ py.test -v -s test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items

View File

@@ -27,7 +27,7 @@ Installation options::
To check your installation has installed the correct version::
$ py.test --version
This is pytest version 2.8.4, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py
This is pytest version 2.8.7, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py
If you get an error checkout :ref:`installation issues`.
@@ -49,7 +49,7 @@ That's it. You can execute the test function now::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -193,7 +193,7 @@ Where to go next
Here are a few suggestions where to go next:
* :ref:`cmdline` for command line invocation examples
* :ref:`good practises <goodpractises>` for virtualenv, test layout, genscript support
* :ref:`good practices <goodpractices>` for virtualenv, test layout, genscript support
* :ref:`fixtures` for providing a functional baseline to your tests
* :ref:`apiref` for documentation and examples on using ``pytest``
* :ref:`plugins` managing and writing plugins

View File

@@ -1,5 +1,5 @@
.. highlightlang:: python
.. _`goodpractises`:
.. _`goodpractices`:
Good Integration Practices
=================================================

View File

@@ -40,7 +40,7 @@ pytest: helps you write better programs
- multi-paradigm: pytest can run ``nose``, ``unittest`` and
``doctest`` style test suites, including running testcases made for
Django and trial
- supports :ref:`good integration practises <goodpractises>`
- supports :ref:`good integration practices <goodpractices>`
- supports extended :ref:`xUnit style setup <xunitsetup>`
- supports domain-specific :ref:`non-python tests`
- supports generating `test coverage reports

View File

@@ -5,10 +5,9 @@ Getting started basics
.. toctree::
:maxdepth: 2
index
getting-started
usage
goodpractises
goodpractices
projects
faq

View File

@@ -41,21 +41,21 @@ to an expected output::
# content of test_expectation.py
import pytest
@pytest.mark.parametrize("input,expected", [
@pytest.mark.parametrize("test_input,expected", [
("3+5", 8),
("2+4", 6),
("6*9", 42),
])
def test_eval(input, expected):
assert eval(input) == expected
def test_eval(test_input, expected):
assert eval(test_input) == expected
Here, the ``@parametrize`` decorator defines three different ``(input,expected)``
Here, the ``@parametrize`` decorator defines three different ``(test_input,expected)``
tuples so that the ``test_eval`` function will run three times using
them in turn::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -64,15 +64,15 @@ them in turn::
======= FAILURES ========
_______ test_eval[6*9-42] ________
input = '6*9', expected = 42
test_input = '6*9', expected = 42
@pytest.mark.parametrize("input,expected", [
@pytest.mark.parametrize("test_input,expected", [
("3+5", 8),
("2+4", 6),
("6*9", 42),
])
def test_eval(input, expected):
> assert eval(input) == expected
def test_eval(test_input, expected):
> assert eval(test_input) == expected
E assert 54 == 42
E + where 54 = eval('6*9')
@@ -91,19 +91,19 @@ for example with the builtin ``mark.xfail``::
# content of test_expectation.py
import pytest
@pytest.mark.parametrize("input,expected", [
@pytest.mark.parametrize("test_input,expected", [
("3+5", 8),
("2+4", 6),
pytest.mark.xfail(("6*9", 42)),
])
def test_eval(input, expected):
assert eval(input) == expected
def test_eval(test_input, expected):
assert eval(test_input) == expected
Let's run this::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items

View File

@@ -14,10 +14,9 @@ Installing a third party plugin can be easily done with ``pip``::
pip uninstall pytest-NAME
If a plugin is installed, ``pytest`` automatically finds and integrates it,
there is no need to activate it. We have a :doc:`page listing
all 3rd party plugins and their status against the latest py.test version
<plugins_index/index>` and here is a little annotated list
for some popular plugins:
there is no need to activate it.
Here is a little annotated list for some popular plugins:
.. _`django`: https://www.djangoproject.com/
@@ -28,7 +27,7 @@ for some popular plugins:
for `twisted <http://twistedmatrix.com>`_ apps, starting a reactor and
processing deferreds from test functions.
* `pytest-capturelog <http://pypi.python.org/pypi/pytest-capturelog>`_:
* `pytest-catchlog <http://pypi.python.org/pypi/pytest-catchlog>`_:
to capture and assert about messages from the logging module
* `pytest-cov <http://pypi.python.org/pypi/pytest-cov>`_:
@@ -50,15 +49,14 @@ for some popular plugins:
* `pytest-timeout <http://pypi.python.org/pypi/pytest-timeout>`_:
to timeout tests based on function marks or global definitions.
* `pytest-cache <http://pypi.python.org/pypi/pytest-cache>`_:
to interactively re-run failing tests and help other plugins to
store test run information across invocations.
* `pytest-pep8 <http://pypi.python.org/pypi/pytest-pep8>`_:
a ``--pep8`` option to enable PEP8 compliance checking.
* `pytest-flakes <https://pypi.python.org/pypi/pytest-flakes>`_:
check source code with pyflakes.
* `oejskit <http://pypi.python.org/pypi/oejskit>`_:
a plugin to run javascript unittests in life browsers
a plugin to run javascript unittests in live browsers.
To see a complete list of all plugins with their latest testing
status against different py.test and Python versions, please visit

Binary file not shown.

Before

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 734 B

View File

@@ -1,336 +0,0 @@
.. _plugins_index:
List of Third-Party Plugins
===========================
The table below contains a listing of plugins found in PyPI and
their status when tested when using latest py.test and python versions.
A complete listing can also be found at
`plugincompat <http://plugincompat.herokuapp.com/>`_, which contains tests
status against other py.test releases.
============================================================================================ ================================================================================================================ ================================================================================================================ ========================================================================================== ===================================================================================================================================================
Name Py27 Py34 Home Summary
============================================================================================ ================================================================================================================ ================================================================================================================ ========================================================================================== ===================================================================================================================================================
`pytest-allure-adaptor <http://pypi.python.org/pypi/pytest-allure-adaptor>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-allure-adaptor-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-allure-adaptor-latest?py=py34&pytest=2.8.3 .. image:: github.png Plugin for py.test to generate allure xml reports
:target: http://plugincompat.herokuapp.com/output/pytest-allure-adaptor-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-allure-adaptor-latest?py=py34&pytest=2.8.3 :target: https://github.com/allure-framework/allure-python
`pytest-ansible <http://pypi.python.org/pypi/pytest-ansible>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ansible-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ansible-latest?py=py34&pytest=2.8.3 .. image:: github.png Plugin for py.test to allow running ansible
:target: http://plugincompat.herokuapp.com/output/pytest-ansible-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ansible-latest?py=py34&pytest=2.8.3 :target: http://github.com/jlaska/pytest-ansible
`pytest-asyncio <http://pypi.python.org/pypi/pytest-asyncio>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-asyncio-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-asyncio-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest support for asyncio.
:target: http://plugincompat.herokuapp.com/output/pytest-asyncio-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-asyncio-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-asyncio
`pytest-autochecklog <http://pypi.python.org/pypi/pytest-autochecklog>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-autochecklog-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-autochecklog-latest?py=py34&pytest=2.8.3 .. image:: github.png automatically check condition and log all the checks
:target: http://plugincompat.herokuapp.com/output/pytest-autochecklog-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-autochecklog-latest?py=py34&pytest=2.8.3 :target: https://github.com/steven004/python-autochecklog
`pytest-bdd <http://pypi.python.org/pypi/pytest-bdd>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-bdd-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-bdd-latest?py=py34&pytest=2.8.3 .. image:: github.png BDD for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-bdd-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-bdd-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-bdd
`pytest-beakerlib <http://pypi.python.org/pypi/pytest-beakerlib>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-beakerlib-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-beakerlib-latest?py=py34&pytest=2.8.3 `link <https://fedorahosted.org/python-pytest-beakerlib/>`_ A pytest plugin that reports test results to the BeakerLib framework
:target: http://plugincompat.herokuapp.com/output/pytest-beakerlib-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-beakerlib-latest?py=py34&pytest=2.8.3
`pytest-beds <http://pypi.python.org/pypi/pytest-beds>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-beds-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-beds-latest?py=py34&pytest=2.8.3 .. image:: github.png Fixtures for testing Google Appengine (GAE) apps
:target: http://plugincompat.herokuapp.com/output/pytest-beds-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-beds-latest?py=py34&pytest=2.8.3 :target: https://github.com/kaste/pytest-beds
`pytest-bench <http://pypi.python.org/pypi/pytest-bench>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-bench-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-bench-latest?py=py34&pytest=2.8.3 .. image:: github.png Benchmark utility that plugs into pytest.
:target: http://plugincompat.herokuapp.com/output/pytest-bench-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-bench-latest?py=py34&pytest=2.8.3 :target: http://github.com/concordusapps/pytest-bench
`pytest-benchmark <http://pypi.python.org/pypi/pytest-benchmark>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-benchmark-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-benchmark-latest?py=py34&pytest=2.8.3 .. image:: github.png A ``py.test`` fixture for benchmarking code.
:target: http://plugincompat.herokuapp.com/output/pytest-benchmark-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-benchmark-latest?py=py34&pytest=2.8.3 :target: https://github.com/ionelmc/pytest-benchmark
`pytest-blockage <http://pypi.python.org/pypi/pytest-blockage>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-blockage-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-blockage-latest?py=py34&pytest=2.8.3 .. image:: github.png Disable network requests during a test run.
:target: http://plugincompat.herokuapp.com/output/pytest-blockage-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-blockage-latest?py=py34&pytest=2.8.3 :target: https://github.com/rob-b/pytest-blockage
`pytest-blocker <http://pypi.python.org/pypi/pytest-blocker>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-blocker-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-blocker-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to mark a test as blocker and skip all other tests
:target: http://plugincompat.herokuapp.com/output/pytest-blocker-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-blocker-latest?py=py34&pytest=2.8.3 :target: http://github.com/EverythingMe/pytest-blocker
`pytest-bpdb <http://pypi.python.org/pypi/pytest-bpdb>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-bpdb-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-bpdb-latest?py=py34&pytest=2.8.3 .. image:: github.png A py.test plug-in to enable drop to bpdb debugger on test failure.
:target: http://plugincompat.herokuapp.com/output/pytest-bpdb-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-bpdb-latest?py=py34&pytest=2.8.3 :target: https://github.com/slafs/pytest-bpdb
`pytest-browsermob-proxy <http://pypi.python.org/pypi/pytest-browsermob-proxy>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-browsermob-proxy-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-browsermob-proxy-latest?py=py34&pytest=2.8.3 .. image:: github.png BrowserMob proxy plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-browsermob-proxy-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-browsermob-proxy-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-browsermob-proxy
`pytest-bugzilla <http://pypi.python.org/pypi/pytest-bugzilla>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-bugzilla-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-bugzilla-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test bugzilla integration plugin
:target: http://plugincompat.herokuapp.com/output/pytest-bugzilla-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-bugzilla-latest?py=py34&pytest=2.8.3 :target: http://github.com/nibrahim/pytest_bugzilla
`pytest-marker-bugzilla <http://pypi.python.org/pypi/pytest-marker-bugzilla>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-marker-bugzilla-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-marker-bugzilla-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test bugzilla integration plugin, using markers
:target: http://plugincompat.herokuapp.com/output/pytest-marker-bugzilla-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-marker-bugzilla-latest?py=py34&pytest=2.8.3 :target: http://github.com/eanxgeek/pytest_marker_bugzilla
`pytest-remove-stale-bytecode <http://pypi.python.org/pypi/pytest-remove-stale-bytecode>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-remove-stale-bytecode-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-remove-stale-bytecode-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test plugin to remove stale byte code files.
:target: http://plugincompat.herokuapp.com/output/pytest-remove-stale-bytecode-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-remove-stale-bytecode-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/gocept/pytest-remove-stale-bytecode/
`pytest-cache <http://pypi.python.org/pypi/pytest-cache>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cache-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cache-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin with mechanisms for caching across test runs
:target: http://plugincompat.herokuapp.com/output/pytest-cache-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cache-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/hpk42/pytest-cache/
`pytest-cagoule <http://pypi.python.org/pypi/pytest-cagoule>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cagoule-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cagoule-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest plugin to only run tests affected by changes
:target: http://plugincompat.herokuapp.com/output/pytest-cagoule-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cagoule-latest?py=py34&pytest=2.8.3 :target: https://github.com/davidszotten/pytest-cagoule
`pytest-capturelog <http://pypi.python.org/pypi/pytest-capturelog>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-capturelog-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-capturelog-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test plugin to capture log messages
:target: http://plugincompat.herokuapp.com/output/pytest-capturelog-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-capturelog-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/memedough/pytest-capturelog/overview
`pytest-django-casperjs <http://pypi.python.org/pypi/pytest-django-casperjs>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-casperjs-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-casperjs-latest?py=py34&pytest=2.8.3 .. image:: github.png Integrate CasperJS with your django tests as a pytest fixture.
:target: http://plugincompat.herokuapp.com/output/pytest-django-casperjs-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-casperjs-latest?py=py34&pytest=2.8.3 :target: https://github.com/EnTeQuAk/pytest-django-casperjs/
`pytest-catchlog <http://pypi.python.org/pypi/pytest-catchlog>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-catchlog-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-catchlog-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to catch log messages. This is a fork of pytest-capturelog.
:target: http://plugincompat.herokuapp.com/output/pytest-catchlog-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-catchlog-latest?py=py34&pytest=2.8.3 :target: https://github.com/eisensheng/pytest-catchlog
`pytest-circleci <http://pypi.python.org/pypi/pytest-circleci>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-circleci-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-circleci-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin for CircleCI
:target: http://plugincompat.herokuapp.com/output/pytest-circleci-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-circleci-latest?py=py34&pytest=2.8.3 :target: https://github.com/micktwomey/pytest-circleci
`pytest-cloud <http://pypi.python.org/pypi/pytest-cloud>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cloud-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cloud-latest?py=py34&pytest=2.8.3 .. image:: github.png Distributed tests planner plugin for pytest testing framework.
:target: http://plugincompat.herokuapp.com/output/pytest-cloud-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cloud-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-cloud
`pytest-codecheckers <http://pypi.python.org/pypi/pytest-codecheckers>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-codecheckers-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-codecheckers-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin to add source code sanity checks (pep8 and friends)
:target: http://plugincompat.herokuapp.com/output/pytest-codecheckers-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-codecheckers-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/RonnyPfannschmidt/pytest-codecheckers/
`pytest-colordots <http://pypi.python.org/pypi/pytest-colordots>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-colordots-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-colordots-latest?py=py34&pytest=2.8.3 .. image:: github.png Colorizes the progress indicators
:target: http://plugincompat.herokuapp.com/output/pytest-colordots-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-colordots-latest?py=py34&pytest=2.8.3 :target: https://github.com/svenstaro/pytest-colordots
`pytest-paste-config <http://pypi.python.org/pypi/pytest-paste-config>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-paste-config-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-paste-config-latest?py=py34&pytest=2.8.3 ? Allow setting the path to a paste config file
:target: http://plugincompat.herokuapp.com/output/pytest-paste-config-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-paste-config-latest?py=py34&pytest=2.8.3
`pytest-config <http://pypi.python.org/pypi/pytest-config>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-config-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-config-latest?py=py34&pytest=2.8.3 .. image:: github.png Base configurations and utilities for developing your Python project test suite with pytest.
:target: http://plugincompat.herokuapp.com/output/pytest-config-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-config-latest?py=py34&pytest=2.8.3 :target: https://github.com/buzzfeed/pytest_config
`pytest-contextfixture <http://pypi.python.org/pypi/pytest-contextfixture>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-contextfixture-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-contextfixture-latest?py=py34&pytest=2.8.3 .. image:: github.png Define pytest fixtures as context managers.
:target: http://plugincompat.herokuapp.com/output/pytest-contextfixture-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-contextfixture-latest?py=py34&pytest=2.8.3 :target: http://github.com/pelme/pytest-contextfixture/
`pytest-couchdbkit <http://pypi.python.org/pypi/pytest-couchdbkit>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-couchdbkit-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-couchdbkit-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test extension for per-test couchdb databases using couchdbkit
:target: http://plugincompat.herokuapp.com/output/pytest-couchdbkit-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-couchdbkit-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/RonnyPfannschmidt/pytest-couchdbkit
`pytest-cov <http://pypi.python.org/pypi/pytest-cov>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cov-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cov-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest plugin for measuring coverage.
:target: http://plugincompat.herokuapp.com/output/pytest-cov-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cov-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-cov
`pytest-cover <http://pypi.python.org/pypi/pytest-cover>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cover-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cover-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest plugin for measuring coverage. Forked from `pytest-cov`.
:target: http://plugincompat.herokuapp.com/output/pytest-cover-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cover-latest?py=py34&pytest=2.8.3 :target: https://github.com/ionelmc/pytest-cover
`pytest-cpp <http://pypi.python.org/pypi/pytest-cpp>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-cpp-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-cpp-latest?py=py34&pytest=2.8.3 .. image:: github.png Use pytest's runner to discover and execute C++ tests
:target: http://plugincompat.herokuapp.com/output/pytest-cpp-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-cpp-latest?py=py34&pytest=2.8.3 :target: http://github.com/pytest-dev/pytest-cpp
`pytest-curl-report <http://pypi.python.org/pypi/pytest-curl-report>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-curl-report-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-curl-report-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin to generate curl command line report
:target: http://plugincompat.herokuapp.com/output/pytest-curl-report-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-curl-report-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/pytest-dev/pytest-curl-report
`pytest-data <http://pypi.python.org/pypi/pytest-data>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-data-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-data-latest?py=py34&pytest=2.8.3 .. image:: github.png Useful functions for managing data for pytest fixtures
:target: http://plugincompat.herokuapp.com/output/pytest-data-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-data-latest?py=py34&pytest=2.8.3 :target: https://github.com/horejsek/python-pytest-data
`pytest-datadir <http://pypi.python.org/pypi/pytest-datadir>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-datadir-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-datadir-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for test data directories and files
:target: http://plugincompat.herokuapp.com/output/pytest-datadir-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-datadir-latest?py=py34&pytest=2.8.3 :target: http://github.com/gabrielcnr/pytest-datadir
`pytest-datafiles <http://pypi.python.org/pypi/pytest-datafiles>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-datafiles-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-datafiles-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to create a 'tmpdir' containing predefined files/directories.
:target: http://plugincompat.herokuapp.com/output/pytest-datafiles-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-datafiles-latest?py=py34&pytest=2.8.3 :target: https://github.com/omarkohl/pytest-datafiles
`pytest-dbfixtures <http://pypi.python.org/pypi/pytest-dbfixtures>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-dbfixtures-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-dbfixtures-latest?py=py34&pytest=2.8.3 .. image:: github.png Databases fixtures plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-dbfixtures-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-dbfixtures-latest?py=py34&pytest=2.8.3 :target: https://github.com/ClearcodeHQ/pytest-dbfixtures
`pytest-dbus-notification <http://pypi.python.org/pypi/pytest-dbus-notification>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-dbus-notification-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-dbus-notification-latest?py=py34&pytest=2.8.3 .. image:: github.png D-BUS notifications for pytest results.
:target: http://plugincompat.herokuapp.com/output/pytest-dbus-notification-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-dbus-notification-latest?py=py34&pytest=2.8.3 :target: https://github.com/bmathieu33/pytest-dbus-notification
`pytest-describe <http://pypi.python.org/pypi/pytest-describe>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-describe-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-describe-latest?py=py34&pytest=2.8.3 .. image:: github.png Describe-style plugin for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-describe-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-describe-latest?py=py34&pytest=2.8.3 :target: https://github.com/ropez/pytest-describe
`pytest-diamond <http://pypi.python.org/pypi/pytest-diamond>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-diamond-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-diamond-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for diamond
:target: http://plugincompat.herokuapp.com/output/pytest-diamond-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-diamond-latest?py=py34&pytest=2.8.3 :target: https://github.com/python-diamond/pytest-diamond
`pytest-diffeo <http://pypi.python.org/pypi/pytest-diffeo>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-diffeo-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-diffeo-latest?py=py34&pytest=2.8.3 .. image:: github.png Common py.test support for Diffeo packages
:target: http://plugincompat.herokuapp.com/output/pytest-diffeo-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-diffeo-latest?py=py34&pytest=2.8.3 :target: https://github.com/diffeo/pytest-diffeo
`pytest-disable <http://pypi.python.org/pypi/pytest-disable>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-disable-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-disable-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to disable a test and skip it from testrun
:target: http://plugincompat.herokuapp.com/output/pytest-disable-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-disable-latest?py=py34&pytest=2.8.3 :target: http://github.com/EverythingMe/pytest-disable
`pytest-django-sqlcounts <http://pypi.python.org/pypi/pytest-django-sqlcounts>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-sqlcounts-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-sqlcounts-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin for reporting the number of SQLs executed per django testcase.
:target: http://plugincompat.herokuapp.com/output/pytest-django-sqlcounts-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-sqlcounts-latest?py=py34&pytest=2.8.3 :target: https://github.com/stj/pytest-django-sqlcount
`pytest-django-sqlcount <http://pypi.python.org/pypi/pytest-django-sqlcount>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-sqlcount-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-sqlcount-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin for reporting the number of SQLs executed per django testcase.
:target: http://plugincompat.herokuapp.com/output/pytest-django-sqlcount-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-sqlcount-latest?py=py34&pytest=2.8.3 :target: https://github.com/stj/pytest-django-sqlcount
`pytest-django-haystack <http://pypi.python.org/pypi/pytest-django-haystack>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-haystack-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-haystack-latest?py=py34&pytest=2.8.3 .. image:: github.png Cleanup your Haystack indexes between tests
:target: http://plugincompat.herokuapp.com/output/pytest-django-haystack-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-haystack-latest?py=py34&pytest=2.8.3 :target: http://github.com/rouge8/pytest-django-haystack
`pytest-django-lite <http://pypi.python.org/pypi/pytest-django-lite>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-lite-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-lite-latest?py=py34&pytest=2.8.3 .. image:: github.png The bare minimum to integrate py.test with Django.
:target: http://plugincompat.herokuapp.com/output/pytest-django-lite-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-lite-latest?py=py34&pytest=2.8.3 :target: https://github.com/dcramer/pytest-django-lite
`pytest-django <http://pypi.python.org/pypi/pytest-django>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-django-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-django-latest?py=py34&pytest=2.8.3 `link <http://pytest-django.readthedocs.org/>`_ A Django plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-django-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-django-latest?py=py34&pytest=2.8.3
`pytest-doc <http://pypi.python.org/pypi/pytest-doc>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-doc-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-doc-latest?py=py34&pytest=2.8.3 `link <http://pytest-doc.readthedocs.org/>`_ A documentation plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-doc-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-doc-latest?py=py34&pytest=2.8.3
`pytest-docker-pexpect <http://pypi.python.org/pypi/pytest-docker-pexpect>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-docker-pexpect-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-docker-pexpect-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for writing functional tests with pexpect and docker
:target: http://plugincompat.herokuapp.com/output/pytest-docker-pexpect-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-docker-pexpect-latest?py=py34&pytest=2.8.3 :target: https://github.com/nvbn/pytest-docker-pexpect
`pytest-dump2json <http://pypi.python.org/pypi/pytest-dump2json>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-dump2json-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-dump2json-latest?py=py34&pytest=2.8.3 .. image:: github.png A pytest plugin for dumping test results to json.
:target: http://plugincompat.herokuapp.com/output/pytest-dump2json-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-dump2json-latest?py=py34&pytest=2.8.3 :target: https://github.com/d6e/pytest-dump2json
`pytest-echo <http://pypi.python.org/pypi/pytest-echo>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-echo-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-echo-latest?py=py34&pytest=2.8.3 `link <http://pypi.python.org/pypi/pytest-echo/>`_ pytest plugin with mechanisms for echoing environment variables, package version and generic attributes
:target: http://plugincompat.herokuapp.com/output/pytest-echo-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-echo-latest?py=py34&pytest=2.8.3
`pytest-env <http://pypi.python.org/pypi/pytest-env>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-env-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-env-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin that allows you to add environment variables.
:target: http://plugincompat.herokuapp.com/output/pytest-env-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-env-latest?py=py34&pytest=2.8.3 :target: https://github.com/MobileDynasty/pytest-env
`pytest-envfiles <http://pypi.python.org/pypi/pytest-envfiles>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-envfiles-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-envfiles-latest?py=py34&pytest=2.8.3 .. image:: github.png A py.test plugin that parses environment files before running tests
:target: http://plugincompat.herokuapp.com/output/pytest-envfiles-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-envfiles-latest?py=py34&pytest=2.8.3 :target: https://github.com/JonnyFunFun/pytest-envfiles
`pytest-eradicate <http://pypi.python.org/pypi/pytest-eradicate>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-eradicate-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-eradicate-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to check for commented out code
:target: http://plugincompat.herokuapp.com/output/pytest-eradicate-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-eradicate-latest?py=py34&pytest=2.8.3 :target: https://github.com/aequitas/pytest-eradicate
`pytest-expect <http://pypi.python.org/pypi/pytest-expect>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-expect-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-expect-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to store test expectations and mark tests based on them
:target: http://plugincompat.herokuapp.com/output/pytest-expect-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-expect-latest?py=py34&pytest=2.8.3 :target: https://github.com/gsnedders/pytest-expect
`pytest-factoryboy <http://pypi.python.org/pypi/pytest-factoryboy>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-factoryboy-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-factoryboy-latest?py=py34&pytest=2.8.3 .. image:: github.png Factory Boy support for pytest.
:target: http://plugincompat.herokuapp.com/output/pytest-factoryboy-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-factoryboy-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-factoryboy
`pytest-poo-fail <http://pypi.python.org/pypi/pytest-poo-fail>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-poo-fail-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-poo-fail-latest?py=py34&pytest=2.8.3 .. image:: github.png Visualize your failed tests with poo
:target: http://plugincompat.herokuapp.com/output/pytest-poo-fail-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-poo-fail-latest?py=py34&pytest=2.8.3 :target: http://github.com/alyssa.barela/pytest-poo-fail
`pytest-faker <http://pypi.python.org/pypi/pytest-faker>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-faker-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-faker-latest?py=py34&pytest=2.8.3 .. image:: github.png Faker integration for pytest framework.
:target: http://plugincompat.herokuapp.com/output/pytest-faker-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-faker-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-faker
`pytest-faulthandler <http://pypi.python.org/pypi/pytest-faulthandler>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-faulthandler-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-faulthandler-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin that activates the fault handler module for tests
:target: http://plugincompat.herokuapp.com/output/pytest-faulthandler-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-faulthandler-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-faulthandler
`pytest-fauxfactory <http://pypi.python.org/pypi/pytest-fauxfactory>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-fauxfactory-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-fauxfactory-latest?py=py34&pytest=2.8.3 .. image:: github.png Integration of fauxfactory into pytest.
:target: http://plugincompat.herokuapp.com/output/pytest-fauxfactory-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-fauxfactory-latest?py=py34&pytest=2.8.3 :target: https://github.com/mfalesni/pytest-fauxfactory
`pytest-figleaf <http://pypi.python.org/pypi/pytest-figleaf>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-figleaf-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-figleaf-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test figleaf coverage plugin
:target: http://plugincompat.herokuapp.com/output/pytest-figleaf-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-figleaf-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/hpk42/pytest-figleaf
`pytest-fixture-tools <http://pypi.python.org/pypi/pytest-fixture-tools>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-fixture-tools-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-fixture-tools-latest?py=py34&pytest=2.8.3 ? Plugin for pytest which provides tools for fixtures
:target: http://plugincompat.herokuapp.com/output/pytest-fixture-tools-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-fixture-tools-latest?py=py34&pytest=2.8.3
`pytest-flake8 <http://pypi.python.org/pypi/pytest-flake8>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-flake8-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-flake8-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to check FLAKE8 requirements
:target: http://plugincompat.herokuapp.com/output/pytest-flake8-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-flake8-latest?py=py34&pytest=2.8.3 :target: https://github.com/tholo/pytest-flake8
`pytest-flakes <http://pypi.python.org/pypi/pytest-flakes>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-flakes-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-flakes-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to check source code with pyflakes
:target: http://plugincompat.herokuapp.com/output/pytest-flakes-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-flakes-latest?py=py34&pytest=2.8.3 :target: https://github.com/fschulze/pytest-flakes
`pytest-ignore-flaky <http://pypi.python.org/pypi/pytest-ignore-flaky>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ignore-flaky-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ignore-flaky-latest?py=py34&pytest=2.8.3 `link <http://pypi.python.org/pypi/pytest-ignore-flaky>`_ ignore failures from flaky tests (pytest plugin)
:target: http://plugincompat.herokuapp.com/output/pytest-ignore-flaky-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ignore-flaky-latest?py=py34&pytest=2.8.3
`pytest-flask <http://pypi.python.org/pypi/pytest-flask>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-flask-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-flask-latest?py=py34&pytest=2.8.3 .. image:: github.png A set of py.test fixtures to test Flask applications.
:target: http://plugincompat.herokuapp.com/output/pytest-flask-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-flask-latest?py=py34&pytest=2.8.3 :target: https://github.com/vitalk/pytest-flask
`pytest-travis-fold <http://pypi.python.org/pypi/pytest-travis-fold>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-travis-fold-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-travis-fold-latest?py=py34&pytest=2.8.3 .. image:: github.png Folds captured output sections in Travis CI build log
:target: http://plugincompat.herokuapp.com/output/pytest-travis-fold-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-travis-fold-latest?py=py34&pytest=2.8.3 :target: https://github.com/abusalimov/pytest-travis-fold
`pytest-gitignore <http://pypi.python.org/pypi/pytest-gitignore>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-gitignore-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-gitignore-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to ignore the same files as git
:target: http://plugincompat.herokuapp.com/output/pytest-gitignore-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-gitignore-latest?py=py34&pytest=2.8.3 :target: https://github.com/tgs/pytest-gitignore
`pytest-greendots <http://pypi.python.org/pypi/pytest-greendots>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-greendots-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-greendots-latest?py=py34&pytest=2.8.3 ? Green progress dots
:target: http://plugincompat.herokuapp.com/output/pytest-greendots-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-greendots-latest?py=py34&pytest=2.8.3
`pytest-growl <http://pypi.python.org/pypi/pytest-growl>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-growl-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-growl-latest?py=py34&pytest=2.8.3 ? Growl notifications for pytest results.
:target: http://plugincompat.herokuapp.com/output/pytest-growl-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-growl-latest?py=py34&pytest=2.8.3
`pytest-html <http://pypi.python.org/pypi/pytest-html>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-html-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-html-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for generating HTML reports
:target: http://plugincompat.herokuapp.com/output/pytest-html-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-html-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-html
`pytest-httpbin <http://pypi.python.org/pypi/pytest-httpbin>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-httpbin-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-httpbin-latest?py=py34&pytest=2.8.3 .. image:: github.png Easily test your HTTP library against a local copy of httpbin
:target: http://plugincompat.herokuapp.com/output/pytest-httpbin-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-httpbin-latest?py=py34&pytest=2.8.3 :target: https://github.com/kevin1024/pytest-httpbin
`pytest-httpretty <http://pypi.python.org/pypi/pytest-httpretty>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-httpretty-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-httpretty-latest?py=py34&pytest=2.8.3 .. image:: github.png A thin wrapper of HTTPretty for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-httpretty-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-httpretty-latest?py=py34&pytest=2.8.3 :target: http://github.com/papaeye/pytest-httpretty
`pytest-incremental <http://pypi.python.org/pypi/pytest-incremental>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-incremental-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-incremental-latest?py=py34&pytest=2.8.3 `link <http://pytest-incremental.readthedocs.org>`_ an incremental test runner (pytest plugin)
:target: http://plugincompat.herokuapp.com/output/pytest-incremental-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-incremental-latest?py=py34&pytest=2.8.3
`pytest-instafail <http://pypi.python.org/pypi/pytest-instafail>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-instafail-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-instafail-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to show failures instantly
:target: http://plugincompat.herokuapp.com/output/pytest-instafail-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-instafail-latest?py=py34&pytest=2.8.3 :target: https://github.com/jpvanhal/pytest-instafail
`pytest-ipdb <http://pypi.python.org/pypi/pytest-ipdb>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ipdb-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ipdb-latest?py=py34&pytest=2.8.3 .. image:: github.png A py.test plug-in to enable drop to ipdb debugger on test failure.
:target: http://plugincompat.herokuapp.com/output/pytest-ipdb-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ipdb-latest?py=py34&pytest=2.8.3 :target: https://github.com/mverteuil/pytest-ipdb
`pytest-ipynb <http://pypi.python.org/pypi/pytest-ipynb>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ipynb-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ipynb-latest?py=py34&pytest=2.8.3 .. image:: github.png Use pytest's runner to discover and execute tests as cells of IPython notebooks
:target: http://plugincompat.herokuapp.com/output/pytest-ipynb-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ipynb-latest?py=py34&pytest=2.8.3 :target: http://github.com/zonca/pytest-ipynb
`pytest-isort <http://pypi.python.org/pypi/pytest-isort>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-isort-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-isort-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to perform isort checks (import ordering)
:target: http://plugincompat.herokuapp.com/output/pytest-isort-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-isort-latest?py=py34&pytest=2.8.3 :target: http://github.com/moccu/pytest-isort/
`pytest-jira <http://pypi.python.org/pypi/pytest-jira>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-jira-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-jira-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test JIRA integration plugin, using markers
:target: http://plugincompat.herokuapp.com/output/pytest-jira-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-jira-latest?py=py34&pytest=2.8.3 :target: http://github.com/jlaska/pytest_jira
`pytest-knows <http://pypi.python.org/pypi/pytest-knows>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-knows-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-knows-latest?py=py34&pytest=2.8.3 .. image:: github.png A pytest plugin that can automaticly skip test case based on dependence info calculated by trace
:target: http://plugincompat.herokuapp.com/output/pytest-knows-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-knows-latest?py=py34&pytest=2.8.3 :target: https://github.com/mapix/ptknows
`pytest-konira <http://pypi.python.org/pypi/pytest-konira>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-konira-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-konira-latest?py=py34&pytest=2.8.3 .. image:: github.png Run Konira DSL tests with py.test
:target: http://plugincompat.herokuapp.com/output/pytest-konira-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-konira-latest?py=py34&pytest=2.8.3 :target: http://github.com/alfredodeza/pytest-konira
`pytest-localserver <http://pypi.python.org/pypi/pytest-localserver>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-localserver-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-localserver-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test plugin to test server connections locally.
:target: http://plugincompat.herokuapp.com/output/pytest-localserver-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-localserver-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/basti/pytest-localserver/
`pytest-markfiltration <http://pypi.python.org/pypi/pytest-markfiltration>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-markfiltration-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-markfiltration-latest?py=py34&pytest=2.8.3 .. image:: github.png UNKNOWN
:target: http://plugincompat.herokuapp.com/output/pytest-markfiltration-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-markfiltration-latest?py=py34&pytest=2.8.3 :target: https://github.com/adamgoucher/pytest-markfiltration
`pytest-marks <http://pypi.python.org/pypi/pytest-marks>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-marks-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-marks-latest?py=py34&pytest=2.8.3 .. image:: github.png UNKNOWN
:target: http://plugincompat.herokuapp.com/output/pytest-marks-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-marks-latest?py=py34&pytest=2.8.3 :target: https://github.com/adamgoucher/pytest-marks
`pytest-mccabe <http://pypi.python.org/pypi/pytest-mccabe>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-mccabe-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-mccabe-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to run the mccabe code complexity checker.
:target: http://plugincompat.herokuapp.com/output/pytest-mccabe-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-mccabe-latest?py=py34&pytest=2.8.3 :target: https://github.com/The-Compiler/pytest-mccabe
`pytest-mock <http://pypi.python.org/pypi/pytest-mock>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-mock-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-mock-latest?py=py34&pytest=2.8.3 .. image:: github.png Thin-wrapper around the mock package for easier use with py.test
:target: http://plugincompat.herokuapp.com/output/pytest-mock-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-mock-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-mock/
`pytest-monkeyplus <http://pypi.python.org/pypi/pytest-monkeyplus>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-monkeyplus-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-monkeyplus-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest's monkeypatch subclass with extra functionalities
:target: http://plugincompat.herokuapp.com/output/pytest-monkeyplus-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-monkeyplus-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/hsoft/pytest-monkeyplus/
`pytest-moto <http://pypi.python.org/pypi/pytest-moto>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-moto-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-moto-latest?py=py34&pytest=2.8.3 .. image:: github.png Fixtures for integration tests of AWS services,uses moto mocking library.
:target: http://plugincompat.herokuapp.com/output/pytest-moto-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-moto-latest?py=py34&pytest=2.8.3 :target: https://github.com/jotes/pytest-moto
`pytest-mozwebqa <http://pypi.python.org/pypi/pytest-mozwebqa>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-mozwebqa-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-mozwebqa-latest?py=py34&pytest=2.8.3 .. image:: github.png Mozilla WebQA plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-mozwebqa-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-mozwebqa-latest?py=py34&pytest=2.8.3 :target: https://github.com/mozilla/pytest-mozwebqa
`pytest-mpl <http://pypi.python.org/pypi/pytest-mpl>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-mpl-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-mpl-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to help with testing figures output from Matplotlib
:target: http://plugincompat.herokuapp.com/output/pytest-mpl-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-mpl-latest?py=py34&pytest=2.8.3 :target: https://github.com/astrofrog/pytest-mpl
`pytest-multihost <http://pypi.python.org/pypi/pytest-multihost>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-multihost-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-multihost-latest?py=py34&pytest=2.8.3 `link <https://fedorahosted.org/python-pytest-multihost/>`_ Utility for writing multi-host tests for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-multihost-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-multihost-latest?py=py34&pytest=2.8.3
`pytest-nocustom <http://pypi.python.org/pypi/pytest-nocustom>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-nocustom-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-nocustom-latest?py=py34&pytest=2.8.3 .. image:: github.png Run all tests without custom markers
:target: http://plugincompat.herokuapp.com/output/pytest-nocustom-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-nocustom-latest?py=py34&pytest=2.8.3 :target: http://github.com/alyssabarela/pytest-nocustom
`pytest-oerp <http://pypi.python.org/pypi/pytest-oerp>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-oerp-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-oerp-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to test OpenERP modules
:target: http://plugincompat.herokuapp.com/output/pytest-oerp-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-oerp-latest?py=py34&pytest=2.8.3 :target: http://github.com/santagada/pytest-oerp/
`pytest-oot <http://pypi.python.org/pypi/pytest-oot>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-oot-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-oot-latest?py=py34&pytest=2.8.3 .. image:: github.png Run object-oriented tests in a simple format
:target: http://plugincompat.herokuapp.com/output/pytest-oot-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-oot-latest?py=py34&pytest=2.8.3 :target: https://github.com/steven004/pytest_oot
`pytest-optional <http://pypi.python.org/pypi/pytest-optional>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-optional-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-optional-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png include/exclude values of fixtures in pytest
:target: http://plugincompat.herokuapp.com/output/pytest-optional-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-optional-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/maho/pytest-optional
`pytest-ordering <http://pypi.python.org/pypi/pytest-ordering>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ordering-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ordering-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to run your tests in a specific order
:target: http://plugincompat.herokuapp.com/output/pytest-ordering-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ordering-latest?py=py34&pytest=2.8.3 :target: https://github.com/ftobia/pytest-ordering
`pytest-osxnotify <http://pypi.python.org/pypi/pytest-osxnotify>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-osxnotify-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-osxnotify-latest?py=py34&pytest=2.8.3 .. image:: github.png OS X notifications for py.test results.
:target: http://plugincompat.herokuapp.com/output/pytest-osxnotify-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-osxnotify-latest?py=py34&pytest=2.8.3 :target: https://github.com/dbader/pytest-osxnotify
`pytest-pep257 <http://pypi.python.org/pypi/pytest-pep257>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pep257-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pep257-latest?py=py34&pytest=2.8.3 ? py.test plugin for pep257
:target: http://plugincompat.herokuapp.com/output/pytest-pep257-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pep257-latest?py=py34&pytest=2.8.3
`pytest-pep8 <http://pypi.python.org/pypi/pytest-pep8>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pep8-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pep8-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin to check PEP8 requirements
:target: http://plugincompat.herokuapp.com/output/pytest-pep8-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pep8-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/pytest-dev/pytest-pep8
`pytest-pipeline <http://pypi.python.org/pypi/pytest-pipeline>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pipeline-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pipeline-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest plugin for functional testing of data analysis pipelines
:target: http://plugincompat.herokuapp.com/output/pytest-pipeline-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pipeline-latest?py=py34&pytest=2.8.3 :target: https://github.com/bow/pytest-pipeline
`pytest-poo <http://pypi.python.org/pypi/pytest-poo>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-poo-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-poo-latest?py=py34&pytest=2.8.3 .. image:: github.png Visualize your crappy tests
:target: http://plugincompat.herokuapp.com/output/pytest-poo-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-poo-latest?py=py34&pytest=2.8.3 :target: http://github.com/pelme/pytest-poo
`pytest-proper-wheel <http://pypi.python.org/pypi/pytest-proper-wheel>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-proper-wheel-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-proper-wheel-latest?py=py34&pytest=2.8.3 `link <http://pytest.org>`_ pytest: simple powerful testing with Python
:target: http://plugincompat.herokuapp.com/output/pytest-proper-wheel-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-proper-wheel-latest?py=py34&pytest=2.8.3
`pytest-purkinje <http://pypi.python.org/pypi/pytest-purkinje>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-purkinje-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-purkinje-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin for purkinje test runner
:target: http://plugincompat.herokuapp.com/output/pytest-purkinje-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-purkinje-latest?py=py34&pytest=2.8.3 :target: https://github.com/bbiskup
`pytest-pycharm <http://pypi.python.org/pypi/pytest-pycharm>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pycharm-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pycharm-latest?py=py34&pytest=2.8.3 .. image:: github.png Plugin for py.test to enter PyCharm debugger on uncaught exceptions
:target: http://plugincompat.herokuapp.com/output/pytest-pycharm-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pycharm-latest?py=py34&pytest=2.8.3 :target: https://github.com/jlubcke/pytest-pycharm
`pytest-pydev <http://pypi.python.org/pypi/pytest-pydev>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pydev-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pydev-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test plugin to connect to a remote debug server with PyDev or PyCharm.
:target: http://plugincompat.herokuapp.com/output/pytest-pydev-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pydev-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/basti/pytest-pydev/
`pytest-pylint <http://pypi.python.org/pypi/pytest-pylint>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pylint-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pylint-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to check source code with pylint
:target: http://plugincompat.herokuapp.com/output/pytest-pylint-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pylint-latest?py=py34&pytest=2.8.3 :target: https://github.com/carsongee/pytest-pylint
`pytest-pyq <http://pypi.python.org/pypi/pytest-pyq>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pyq-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pyq-latest?py=py34&pytest=2.8.3 `link <http://pyq.enlnt.com>`_ Pytest fixture "q" for pyq
:target: http://plugincompat.herokuapp.com/output/pytest-pyq-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pyq-latest?py=py34&pytest=2.8.3
`pytest-readme <http://pypi.python.org/pypi/pytest-readme>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-readme-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-readme-latest?py=py34&pytest=2.8.3 .. image:: github.png Test your README.md file
:target: http://plugincompat.herokuapp.com/output/pytest-readme-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-readme-latest?py=py34&pytest=2.8.3 :target: https://github.com/boxed/pytest-readme
`pytest-trepan <http://pypi.python.org/pypi/pytest-trepan>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-trepan-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-trepan-latest?py=py34&pytest=2.8.3 .. image:: github.png Pytest plugin for trepan debugger.
:target: http://plugincompat.herokuapp.com/output/pytest-trepan-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-trepan-latest?py=py34&pytest=2.8.3 :target: http://github.com/rocky/pytest-trepan
`pytest-vw <http://pypi.python.org/pypi/pytest-vw>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-vw-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-vw-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest-vw makes your failing test cases succeed under CI tools scrutiny
:target: http://plugincompat.herokuapp.com/output/pytest-vw-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-vw-latest?py=py34&pytest=2.8.3 :target: https://github.com/The-Compiler/pytest-vw
`pytest-rage <http://pypi.python.org/pypi/pytest-rage>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-rage-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-rage-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to implement PEP712
:target: http://plugincompat.herokuapp.com/output/pytest-rage-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-rage-latest?py=py34&pytest=2.8.3 :target: http://github.com/santagada/pytest-rage/
`pytest-smartcov <http://pypi.python.org/pypi/pytest-smartcov>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-smartcov-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-smartcov-latest?py=py34&pytest=2.8.3 .. image:: github.png Smart coverage plugin for pytest.
:target: http://plugincompat.herokuapp.com/output/pytest-smartcov-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-smartcov-latest?py=py34&pytest=2.8.3 :target: https://github.com/carljm/pytest-smartcov/
`pytest-spawner <http://pypi.python.org/pypi/pytest-spawner>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-spawner-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-spawner-latest?py=py34&pytest=2.8.3 `link <https://git.qe-infra.yandex-team.ru/users/dldmitry/repos/pytest-spawner/browse>`_ py.test plugin to spawn process and communicate with them.
:target: http://plugincompat.herokuapp.com/output/pytest-spawner-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-spawner-latest?py=py34&pytest=2.8.3
`pytest-session2file <http://pypi.python.org/pypi/pytest-session2file>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py34&pytest=2.8.3 .. image:: github.png 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.
:target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py34&pytest=2.8.3 :target: https://github.com/BuhtigithuB/pytest-session2file
`pytest-selenium <http://pypi.python.org/pypi/pytest-selenium>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for Selenium
:target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-selenium
`pytest-random <http://pypi.python.org/pypi/pytest-random>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-random-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-random-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to randomize tests
:target: http://plugincompat.herokuapp.com/output/pytest-random-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-random-latest?py=py34&pytest=2.8.3 :target: https://github.com/klrmn/pytest-random
`pytest-sourceorder <http://pypi.python.org/pypi/pytest-sourceorder>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-sourceorder-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-sourceorder-latest?py=py34&pytest=2.8.3 `link <https://fedorahosted.org/python-pytest-sourceorder/>`_ Test-ordering plugin for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-sourceorder-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-sourceorder-latest?py=py34&pytest=2.8.3
`pytest-wholenodeid <http://pypi.python.org/pypi/pytest-wholenodeid>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-wholenodeid-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-wholenodeid-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest addon for displaying the whole node id for failures
:target: http://plugincompat.herokuapp.com/output/pytest-wholenodeid-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-wholenodeid-latest?py=py34&pytest=2.8.3 :target: https://github.com/willkg/pytest-wholenodeid
`pytest-translations <http://pypi.python.org/pypi/pytest-translations>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-translations-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-translations-latest?py=py34&pytest=2.8.3 .. image:: github.png Test your translation files
:target: http://plugincompat.herokuapp.com/output/pytest-translations-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-translations-latest?py=py34&pytest=2.8.3 :target: https://github.com/thermondo/pytest-translations
`pytest-raisesregexp <http://pypi.python.org/pypi/pytest-raisesregexp>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-raisesregexp-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-raisesregexp-latest?py=py34&pytest=2.8.3 .. image:: github.png Simple pytest plugin to look for regex in Exceptions
:target: http://plugincompat.herokuapp.com/output/pytest-raisesregexp-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-raisesregexp-latest?py=py34&pytest=2.8.3 :target: https://github.com/Walkman/pytest_raisesregexp
`pytest-rerunfailures <http://pypi.python.org/pypi/pytest-rerunfailures>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-rerunfailures-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-rerunfailures-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to re-run tests to eliminate flakey failures
:target: http://plugincompat.herokuapp.com/output/pytest-rerunfailures-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-rerunfailures-latest?py=py34&pytest=2.8.3 :target: https://github.com/klrmn/pytest-rerunfailures
`pytest-trialtemp <http://pypi.python.org/pypi/pytest-trialtemp>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-trialtemp-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-trialtemp-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin for using the same _trial_temp working directory as trial
:target: http://plugincompat.herokuapp.com/output/pytest-trialtemp-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-trialtemp-latest?py=py34&pytest=2.8.3 :target: http://github.com/jerith/pytest-trialtemp
`pytest-zap <http://pypi.python.org/pypi/pytest-zap>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-zap-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-zap-latest?py=py34&pytest=2.8.3 .. image:: github.png OWASP ZAP plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-zap-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-zap-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-zap
`pytest-stepwise <http://pypi.python.org/pypi/pytest-stepwise>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-stepwise-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-stepwise-latest?py=py34&pytest=2.8.3 .. image:: github.png Run a test suite one failing test at a time.
:target: http://plugincompat.herokuapp.com/output/pytest-stepwise-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-stepwise-latest?py=py34&pytest=2.8.3 :target: https://github.com/nip3o/pytest-stepwise
`pytest-session_to_file <http://pypi.python.org/pypi/pytest-session_to_file>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-session_to_file-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-session_to_file-latest?py=py34&pytest=2.8.3 `link <https://pypi.python.org/pypi/pytest-session_to_file>`_ pytest-session_to_file is a py.test plugin for capturing and saving to file the stdout of py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-session_to_file-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-session_to_file-latest?py=py34&pytest=2.8.3
`pytest-spec <http://pypi.python.org/pypi/pytest-spec>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-spec-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-spec-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin to display test execution output like a SPECIFICATION
:target: http://plugincompat.herokuapp.com/output/pytest-spec-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-spec-latest?py=py34&pytest=2.8.3 :target: https://github.com/pchomik/pytest-spec
`pytest-selenium <http://pypi.python.org/pypi/pytest-selenium>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for Selenium
:target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-selenium
`pytest-testmon <http://pypi.python.org/pypi/pytest-testmon>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-testmon-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-testmon-latest?py=py34&pytest=2.8.3 .. image:: github.png take TDD to a new level with py.test and testmon
:target: http://plugincompat.herokuapp.com/output/pytest-testmon-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-testmon-latest?py=py34&pytest=2.8.3 :target: https://github.com/tarpas/pytest-testmon/
`pytest-variables <http://pypi.python.org/pypi/pytest-variables>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-variables-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-variables-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for providing variables to tests/fixtures
:target: http://plugincompat.herokuapp.com/output/pytest-variables-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-variables-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-variables
`pytest-runfailed <http://pypi.python.org/pypi/pytest-runfailed>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-runfailed-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-runfailed-latest?py=py34&pytest=2.8.3 .. image:: github.png implement a --failed option for pytest
:target: http://plugincompat.herokuapp.com/output/pytest-runfailed-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-runfailed-latest?py=py34&pytest=2.8.3 :target: http://github.com/dmerejkowsky/pytest-runfailed
`pytest-testmon <http://pypi.python.org/pypi/pytest-testmon>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-testmon-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-testmon-latest?py=py34&pytest=2.8.3 .. image:: github.png take TDD to a new level with py.test and testmon
:target: http://plugincompat.herokuapp.com/output/pytest-testmon-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-testmon-latest?py=py34&pytest=2.8.3 :target: https://github.com/tarpas/pytest-testmon/
`pytest-stepwise <http://pypi.python.org/pypi/pytest-stepwise>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-stepwise-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-stepwise-latest?py=py34&pytest=2.8.3 .. image:: github.png Run a test suite one failing test at a time.
:target: http://plugincompat.herokuapp.com/output/pytest-stepwise-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-stepwise-latest?py=py34&pytest=2.8.3 :target: https://github.com/nip3o/pytest-stepwise
`pytest-xprocess <http://pypi.python.org/pypi/pytest-xprocess>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-xprocess-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-xprocess-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin to manage external processes across test runs
:target: http://plugincompat.herokuapp.com/output/pytest-xprocess-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-xprocess-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/hpk42/pytest-xprocess/
`pytest-session2file <http://pypi.python.org/pypi/pytest-session2file>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py34&pytest=2.8.3 .. image:: github.png 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.
:target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py34&pytest=2.8.3 :target: https://github.com/BuhtigithuB/pytest_session2file
`pytest-selenium <http://pypi.python.org/pypi/pytest-selenium>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-selenium-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for Selenium
:target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-selenium-latest?py=py34&pytest=2.8.3 :target: https://github.com/davehunt/pytest-selenium
`pytest-tornado <http://pypi.python.org/pypi/pytest-tornado>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-tornado-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-tornado-latest?py=py34&pytest=2.8.3 .. image:: github.png A py.test plugin providing fixtures and markers to simplify testing of asynchronous tornado applications.
:target: http://plugincompat.herokuapp.com/output/pytest-tornado-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-tornado-latest?py=py34&pytest=2.8.3 :target: https://github.com/eugeniy/pytest-tornado
`pytest-ubersmith <http://pypi.python.org/pypi/pytest-ubersmith>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-ubersmith-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-ubersmith-latest?py=py34&pytest=2.8.3 .. image:: github.png Easily mock calls to ubersmith at the `requests` level.
:target: http://plugincompat.herokuapp.com/output/pytest-ubersmith-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-ubersmith-latest?py=py34&pytest=2.8.3 :target: https://github.com/hivelocity/pytest-ubersmith
`pytest-session2file <http://pypi.python.org/pypi/pytest-session2file>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-session2file-latest?py=py34&pytest=2.8.3 .. image:: github.png 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.
:target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-session2file-latest?py=py34&pytest=2.8.3 :target: https://github.com/BuhtigithuB/pytest_session2file
`pytest-timeout <http://pypi.python.org/pypi/pytest-timeout>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-timeout-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-timeout-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test plugin to abort hanging tests
:target: http://plugincompat.herokuapp.com/output/pytest-timeout-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-timeout-latest?py=py34&pytest=2.8.3 :target: http://bitbucket.org/pytest-dev/pytest-timeout/
`pytest-quickcheck <http://pypi.python.org/pypi/pytest-quickcheck>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-quickcheck-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-quickcheck-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png pytest plugin to generate random data inspired by QuickCheck
:target: http://plugincompat.herokuapp.com/output/pytest-quickcheck-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-quickcheck-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/pytest-dev/pytest-quickcheck
`pytest-trello <http://pypi.python.org/pypi/pytest-trello>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-trello-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-trello-latest?py=py34&pytest=2.8.3 .. image:: github.png Plugin for py.test that integrates trello using markers
:target: http://plugincompat.herokuapp.com/output/pytest-trello-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-trello-latest?py=py34&pytest=2.8.3 :target: http://github.com/jlaska/pytest-trello
`pytest-twisted <http://pypi.python.org/pypi/pytest-twisted>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-twisted-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-twisted-latest?py=py34&pytest=2.8.3 .. image:: github.png A twisted plugin for py.test.
:target: http://plugincompat.herokuapp.com/output/pytest-twisted-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-twisted-latest?py=py34&pytest=2.8.3 :target: https://github.com/schmir/pytest-twisted
`pytest-sftpserver <http://pypi.python.org/pypi/pytest-sftpserver>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-sftpserver-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-sftpserver-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test plugin to locally test sftp server connections.
:target: http://plugincompat.herokuapp.com/output/pytest-sftpserver-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-sftpserver-latest?py=py34&pytest=2.8.3 :target: http://github.com/ulope/pytest-sftpserver/
`pytest-yamlwsgi <http://pypi.python.org/pypi/pytest-yamlwsgi>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-yamlwsgi-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-yamlwsgi-latest?py=py34&pytest=2.8.3 ? Run tests against wsgi apps defined in yaml
:target: http://plugincompat.herokuapp.com/output/pytest-yamlwsgi-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-yamlwsgi-latest?py=py34&pytest=2.8.3
`pytest-watch <http://pypi.python.org/pypi/pytest-watch>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-watch-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-watch-latest?py=py34&pytest=2.8.3 .. image:: github.png Local continuous test runner with pytest and watchdog.
:target: http://plugincompat.herokuapp.com/output/pytest-watch-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-watch-latest?py=py34&pytest=2.8.3 :target: http://github.com/joeyespo/pytest-watch
`pytest-pythonpath <http://pypi.python.org/pypi/pytest-pythonpath>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-pythonpath-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-pythonpath-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest plugin for adding to the PYTHONPATH from command line or configs.
:target: http://plugincompat.herokuapp.com/output/pytest-pythonpath-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-pythonpath-latest?py=py34&pytest=2.8.3 :target: https://github.com/bigsassy/pytest-pythonpath
`pytest-watch <http://pypi.python.org/pypi/pytest-watch>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-watch-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-watch-latest?py=py34&pytest=2.8.3 .. image:: github.png Local continuous test runner with pytest and watchdog.
:target: http://plugincompat.herokuapp.com/output/pytest-watch-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-watch-latest?py=py34&pytest=2.8.3 :target: http://github.com/joeyespo/pytest-watch
`pytest-unmarked <http://pypi.python.org/pypi/pytest-unmarked>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-unmarked-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-unmarked-latest?py=py34&pytest=2.8.3 .. image:: github.png Run only unmarked tests
:target: http://plugincompat.herokuapp.com/output/pytest-unmarked-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-unmarked-latest?py=py34&pytest=2.8.3 :target: http://github.com/alyssa.barela/pytest-unmarked
`pytest-sugar <http://pypi.python.org/pypi/pytest-sugar>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-sugar-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-sugar-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test is a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show tests that fail instantly).
:target: http://plugincompat.herokuapp.com/output/pytest-sugar-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-sugar-latest?py=py34&pytest=2.8.3 :target: https://github.com/Frozenball/pytest-sugar
`pytest-qt <http://pypi.python.org/pypi/pytest-qt>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest support for PyQt and PySide applications
:target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py34&pytest=2.8.3 :target: http://github.com/pytest-dev/pytest-qt
`pytest-xdist <http://pypi.python.org/pypi/pytest-xdist>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-xdist-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-xdist-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png py.test xdist plugin for distributed testing and loop-on-failing modes
:target: http://plugincompat.herokuapp.com/output/pytest-xdist-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-xdist-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/pytest-dev/pytest-xdist
`pytest-sugar <http://pypi.python.org/pypi/pytest-sugar>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-sugar-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-sugar-latest?py=py34&pytest=2.8.3 .. image:: github.png py.test is a plugin for py.test that changes the default look and feel of py.test (e.g. progressbar, show tests that fail instantly).
:target: http://plugincompat.herokuapp.com/output/pytest-sugar-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-sugar-latest?py=py34&pytest=2.8.3 :target: https://github.com/Frozenball/pytest-sugar
`pytest-qt <http://pypi.python.org/pypi/pytest-qt>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest support for PyQt and PySide applications
:target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py34&pytest=2.8.3 :target: http://github.com/pytest-dev/pytest-qt
`pytest-regtest <http://pypi.python.org/pypi/pytest-regtest>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-regtest-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-regtest-latest?py=py34&pytest=2.8.3 `link <https://sissource.ethz.ch/uweschmitt/pytest-regtest/tree/master>`_ py.test plugin for regression tests
:target: http://plugincompat.herokuapp.com/output/pytest-regtest-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-regtest-latest?py=py34&pytest=2.8.3
`pytest-qt <http://pypi.python.org/pypi/pytest-qt>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-qt-latest?py=py34&pytest=2.8.3 .. image:: github.png pytest support for PyQt and PySide applications
:target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-qt-latest?py=py34&pytest=2.8.3 :target: http://github.com/pytest-dev/pytest-qt
`pytest-runner <http://pypi.python.org/pypi/pytest-runner>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-runner-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-runner-latest?py=py34&pytest=2.8.3 .. image:: bitbucket.png Invoke py.test as distutils command with dependency resolution.
:target: http://plugincompat.herokuapp.com/output/pytest-runner-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-runner-latest?py=py34&pytest=2.8.3 :target: https://bitbucket.org/pytest-dev/pytest-runner
`pytest-services <http://pypi.python.org/pypi/pytest-services>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-services-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-services-latest?py=py34&pytest=2.8.3 .. image:: github.png Services plugin for pytest testing framework
:target: http://plugincompat.herokuapp.com/output/pytest-services-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-services-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-services
`pytest-splinter <http://pypi.python.org/pypi/pytest-splinter>`_ .. image:: http://plugincompat.herokuapp.com/status/pytest-splinter-latest?py=py27&pytest=2.8.3 .. image:: http://plugincompat.herokuapp.com/status/pytest-splinter-latest?py=py34&pytest=2.8.3 .. image:: github.png Splinter plugin for pytest testing framework
:target: http://plugincompat.herokuapp.com/output/pytest-splinter-latest?py=py27&pytest=2.8.3 :target: http://plugincompat.herokuapp.com/output/pytest-splinter-latest?py=py34&pytest=2.8.3 :target: https://github.com/pytest-dev/pytest-splinter
============================================================================================ ================================================================================================================ ================================================================================================================ ========================================================================================== ===================================================================================================================================================
*(Updated on 2015-10-17)*

View File

@@ -1,308 +0,0 @@
"""
Script to generate the file `index.rst` with information about
pytest plugins taken directly from PyPI.
Usage:
python plugins_index.py
This command will update `index.rst` in the same directory found as this script.
This should be issued before every major documentation release to obtain latest
versions from PyPI.
Also includes plugin compatibility between different python and pytest versions,
obtained from http://plugincompat.herokuapp.com.
"""
from __future__ import print_function
from argparse import ArgumentParser
from collections import namedtuple
import datetime
from distutils.version import LooseVersion
import itertools
import os
import sys
import pytest
def get_proxy(url):
"""
wrapper function to obtain a xmlrpc proxy, taking in account import
differences between python 2.X and 3.X
:param url: url to bind the proxy to
:return: a ServerProxy instance
"""
if sys.version_info < (3, 0):
from xmlrpclib import ServerProxy
else:
from xmlrpc.client import ServerProxy
return ServerProxy(url)
def iter_plugins(client):
"""
Returns an iterator of (name, version) from PyPI.
:param client: ServerProxy
:param search: package names to search for
"""
for plug_data in client.search({'name': 'pytest'}):
if plug_data['name'].startswith('pytest-'):
yield plug_data['name'], plug_data['version']
def get_latest_versions(plugins):
"""
Returns an iterator of (name, version) from the given list of (name,
version), but returning only the latest version of the package. Uses
distutils.LooseVersion to ensure compatibility with PEP386.
"""
plugins = [(name, LooseVersion(version)) for (name, version) in plugins]
for name, grouped_plugins in itertools.groupby(plugins, key=lambda x: x[0]):
name, loose_version = list(grouped_plugins)[-1]
yield name, str(loose_version)
def obtain_plugins_table(plugins, client, verbose, pytest_ver):
"""
Returns information to populate a table of plugins, their versions,
authors, etc.
The returned information is a list of columns of `ColumnData`
namedtuples(text, link). Link can be None if the text for that column
should not be linked to anything.
:param plugins: list of (name, version)
:param client: ServerProxy
:param verbose: print plugin name and version as they are fetch
:param pytest_ver: pytest version to use.
"""
if pytest_ver is None:
pytest_ver = pytest.__version__
def get_repo_markup(repo):
"""
obtains appropriate markup for the given repository, as two lines
that should be output in the same table row. We use this to display an icon
for known repository hosts (github, etc), just a "?" char when
repository is not registered in pypi or a simple link otherwise.
"""
target = repo
if 'github.com' in repo:
image = 'github.png'
elif 'bitbucket.org' in repo:
image = 'bitbucket.png'
elif repo.lower() == 'unknown':
return '?', ''
else:
image = None
if image is not None:
image_markup = '.. image:: %s' % image
target_markup = ' :target: %s' % repo
pad_right = ('%-' + str(len(target_markup)) + 's')
return pad_right % image_markup, target_markup
else:
return ('`link <%s>`_' % target), ''
def sanitize_summary(summary):
"""Make sure summaries don't break our table formatting.
"""
return summary.replace('\n', ' ')
rows = []
ColumnData = namedtuple('ColumnData', 'text link')
headers = ['Name', 'Py27', 'Py34', 'Home', 'Summary']
repositories = obtain_override_repositories()
print('Generating plugins_index page (pytest-{0})'.format(pytest_ver))
plugins = list(plugins)
for index, (package_name, version) in enumerate(plugins):
if verbose:
print(package_name, version, '...', end='')
release_data = client.release_data(package_name, version)
common_params = dict(
site='http://plugincompat.herokuapp.com',
name=package_name,
version=version)
repository = repositories.get(package_name, release_data['home_page'])
repo_markup_1, repo_markup_2 = get_repo_markup(repository)
# first row: name, images and simple links
url = '.. image:: {site}/status/{name}-latest'
image_url = url.format(**common_params)
image_url += '?py={py}&pytest={pytest}'
row = (
ColumnData(package_name, release_data['package_url']),
ColumnData(image_url.format(py='py27', pytest=pytest_ver),
None),
ColumnData(image_url.format(py='py34', pytest=pytest_ver),
None),
ColumnData(
repo_markup_1,
None),
ColumnData(sanitize_summary(release_data['summary']), None),
)
assert len(row) == len(headers)
rows.append(row)
# second row: links for images (they should be in their own line)
url = ' :target: {site}/output/{name}-latest'
output_url = url.format(**common_params)
output_url += '?py={py}&pytest={pytest}'
row = (
ColumnData('', None),
ColumnData(output_url.format(py='py27', pytest=pytest_ver),
None),
ColumnData(output_url.format(py='py34', pytest=pytest_ver),
None),
ColumnData(repo_markup_2, None),
ColumnData('', None),
)
assert len(row) == len(headers)
rows.append(row)
if verbose:
print('OK (%d%%)' % ((index + 1) * 100 / len(plugins)))
print('Done: %d plugins' % len(plugins))
return headers, rows
def obtain_override_repositories():
"""
Used to override the "home_page" obtained from pypi to known
package repositories. Used when the author didn't fill the "home_page"
field in setup.py.
:return: dict of {package_name: repository_url}
"""
return {
'pytest-blockage': 'https://github.com/rob-b/pytest-blockage',
'pytest-konira': 'http://github.com/alfredodeza/pytest-konira',
'pytest-sugar': 'https://github.com/Frozenball/pytest-sugar',
}
def generate_plugins_index_from_table(filename, headers, rows, pytest_ver):
"""
Generates a RST file with the table data given.
:param filename: output filename
:param headers: see `obtain_plugins_table`
:param rows: see `obtain_plugins_table`
:param pytest_ver: see `obtain_plugins_table`
"""
# creates a list of rows, each being a str containing appropriate column
# text and link
table_texts = []
for row in rows:
column_texts = []
for i, col_data in enumerate(row):
text = '`%s <%s>`_' % (
col_data.text,
col_data.link) if col_data.link else col_data.text
column_texts.append(text)
table_texts.append(column_texts)
# compute max length of each column so we can build the rst table
column_lengths = [len(x) for x in headers]
for column_texts in table_texts:
for i, row_text in enumerate(column_texts):
column_lengths[i] = max(column_lengths[i], len(row_text) + 2)
def get_row_limiter(char):
return ' '.join(char * length for length in column_lengths)
with open(filename, 'w') as f:
# header
print(HEADER, file=f)
print(file=f)
# table
print(get_row_limiter('='), file=f)
formatted_headers = [
'{0:^{fill}}'.format(header, fill=column_lengths[i])
for i, header in enumerate(headers)]
print(*formatted_headers, file=f)
print(get_row_limiter('='), file=f)
for column_texts in table_texts:
formatted_rows = [
'{0:^{fill}}'.format(row_text, fill=column_lengths[i])
for i, row_text in enumerate(column_texts)
]
print(*formatted_rows, file=f)
print(file=f)
print(get_row_limiter('='), file=f)
print(file=f)
today = datetime.date.today().strftime('%Y-%m-%d')
print('*(Updated on %s)*' % today, file=f)
def generate_plugins_index(client, filename, verbose, pytest_ver):
"""
Generates an RST file with a table of the latest pytest plugins found in
PyPI.
:param client: ServerProxy
:param filename: output filename
:param verbose: print name and version of each plugin as they are fetch
:param pytest_ver: pytest version to use; if not given, use current pytest
version.
"""
plugins = get_latest_versions(iter_plugins(client))
headers, rows = obtain_plugins_table(plugins, client, verbose, pytest_ver)
generate_plugins_index_from_table(filename, headers, rows, pytest_ver)
def main(argv):
"""
Script entry point. Configures an option parser and calls the appropriate
internal function.
"""
filename = os.path.join(os.path.dirname(__file__), 'index.rst')
url = 'http://pypi.python.org/pypi'
parser = ArgumentParser(
description='Generates a document with all pytest plugins from PyPI')
parser.add_argument('-f', '--filename', default=filename,
help='output filename [default: %default]')
parser.add_argument('-u', '--url', default=url,
help='url of PyPI server to obtain data from [default: %default]')
parser.add_argument('-v', '--verbose', default=False, action='store_true',
help='verbose output')
parser.add_argument('version', default=None, action='store',
help='generate index for this pytest version')
options = parser.parse_args()
client = get_proxy(options.url)
generate_plugins_index(client, options.filename, options.verbose,
options.version)
print()
print('%s updated.' % options.filename)
return 0
# header for the plugins_index page
HEADER = '''.. _plugins_index:
List of Third-Party Plugins
===========================
The table below contains a listing of plugins found in PyPI and
their status when tested when using latest py.test and python versions.
A complete listing can also be found at
`plugincompat <http://plugincompat.herokuapp.com/>`_, which contains tests
status against other py.test releases.
'''
if __name__ == '__main__':
sys.exit(main(sys.argv))

View File

@@ -41,6 +41,10 @@ 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`.
.. _recwarn:
Recording warnings
@@ -87,6 +91,9 @@ Each recorded warning has the attributes ``message``, ``category``,
class of the warning. The ``message`` is the warning itself; calling
``str(message)`` will return the actual message of the warning.
.. note::
``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated
differently; see :ref:`ensuring_function_triggers`.
.. _ensuring_function_triggers:
@@ -94,16 +101,17 @@ Ensuring a function triggers a deprecation warning
-------------------------------------------------------
You can also call a global helper for checking
that a certain function call triggers a ``DeprecationWarning``::
that a certain function call triggers a ``DeprecationWarning`` or
``PendingDeprecationWarning``::
import pytest
def test_global():
pytest.deprecated_call(myfunction, 17)
By default, deprecation warnings will not be caught when using ``pytest.warns``
or ``recwarn``, since the default Python warnings filters hide
DeprecationWarnings. If you wish to record them in your own code, use the
By default, ``DeprecationWarning`` and ``PendingDeprecationWarning`` will not be
caught when using ``pytest.warns`` or ``recwarn`` because default Python warnings filters hide
them. If you wish to record them in your own code, use the
command ``warnings.simplefilter('always')``::
import warnings

View File

@@ -165,7 +165,7 @@ Running it with the report-on-xfail option gives this output::
example $ py.test -rx xfail_demo.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/example, inifile:
collected 7 items

View File

@@ -29,7 +29,7 @@ Running this would result in a passed test except for the last
$ py.test test_tmpdir.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -88,7 +88,7 @@ the ``self.db`` values in the traceback::
$ py.test test_unittest_db.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.7, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -16,7 +16,7 @@ reporting by calling `well specified hooks`_ of the following plugins:
* :ref:`builtin plugins`: loaded from pytest's internal ``_pytest`` directory.
* :ref:`external plugins <plugins_index>`: modules discovered through
* :ref:`external plugins <extplugins>`: modules discovered through
`setuptools entry points`_
* `conftest.py plugins`_: modules auto-discovered in test directories
@@ -95,7 +95,7 @@ Here is how you might run it::
python package directory (i.e. one containing an ``__init__.py``) then
"import conftest" can be ambiguous because there might be other
``conftest.py`` files as well on your PYTHONPATH or ``sys.path``.
It is thus good practise for projects to either put ``conftest.py``
It is thus good practice for projects to either put ``conftest.py``
under a package scope or to never import anything from a
conftest.py file.
@@ -110,7 +110,7 @@ you can copy from:
* a custom collection example plugin: :ref:`yaml plugin`
* around 20 doc:`builtin plugins` which provide pytest's own functionality
* many :ref:`external plugins <plugins_index>` providing additional features
* many `external plugins <http://plugincompat.herokuapp.com>`_ providing additional features
All of these plugins implement the documented `well specified hooks`_
to extend and add functionality.
@@ -485,12 +485,20 @@ Session related reporting hooks:
.. autofunction:: pytest_itemcollected
.. autofunction:: pytest_collectreport
.. autofunction:: pytest_deselected
.. autofunction:: pytest_report_header
.. autofunction:: pytest_report_teststatus
.. autofunction:: pytest_terminal_summary
And here is the central hook for reporting about
test execution:
.. autofunction:: pytest_runtest_logreport
You can also use this hook to customize assertion representation for some
types:
.. autofunction:: pytest_assertrepr_compare
Debugging/Interaction hooks
---------------------------

View File

@@ -1076,3 +1076,26 @@ def test_dont_collect_non_function_callable(testdir):
'WC2 *',
'*1 passed, 1 pytest-warnings in *',
])
def test_class_injection_does_not_break_collection(testdir):
"""Tests whether injection during collection time will terminate testing.
In this case the error should not occur if the TestClass itself
is modified during collection time, and the original method list
is still used for collection.
"""
testdir.makeconftest("""
from test_inject import TestClass
def pytest_generate_tests(metafunc):
TestClass.changed_var = {}
""")
testdir.makepyfile(test_inject='''
class TestClass(object):
def test_injection(self):
"""Test being parametrized."""
pass
''')
result = testdir.runpytest()
assert "RuntimeError: dictionary changed size during iteration" not in result.stdout.str()
result.stdout.fnmatch_lines(['*1 passed*'])

View File

@@ -203,7 +203,7 @@ class TestView:
cls.View = pytest.importorskip("_pytest.assertion.oldinterpret").View
def test_class_dispatch(self):
### Use a custom class hierarchy with existing instances
# Use a custom class hierarchy with existing instances
class Picklable(self.View):
pass

View File

@@ -1,3 +1,4 @@
# encoding: utf-8
import sys
from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile
import py
@@ -109,6 +110,46 @@ class TestDoctests:
"*UNEXPECTED*ZeroDivision*",
])
def test_docstring_context_around_error(self, testdir):
"""Test that we show some context before the actual line of a failing
doctest.
"""
testdir.makepyfile('''
def foo():
"""
text-line-1
text-line-2
text-line-3
text-line-4
text-line-5
text-line-6
text-line-7
text-line-8
text-line-9
text-line-10
text-line-11
>>> 1 + 1
3
text-line-after
"""
''')
result = testdir.runpytest('--doctest-modules')
result.stdout.fnmatch_lines([
'*docstring_context_around_error*',
'005*text-line-3',
'006*text-line-4',
'013*text-line-11',
'014*>>> 1 + 1',
'Expected:',
' 3',
'Got:',
' 2',
])
# lines below should be trimmed out
assert 'text-line-2' not in result.stdout.str()
assert 'text-line-after' not in result.stdout.str()
def test_doctest_linedata_missing(self, testdir):
testdir.tmpdir.join('hello.py').write(py.code.Source("""
class Fun(object):
@@ -339,6 +380,23 @@ class TestDoctests:
reprec = testdir.inline_run(p, "--doctest-glob=x*.txt")
reprec.assertoutcome(failed=1, passed=0)
def test_contains_unicode(self, testdir):
"""Fix internal error with docstrings containing non-ascii characters.
"""
testdir.makepyfile(u'''
# encoding: utf-8
def foo():
"""
>>> name = 'с' # not letter 'c' but instead Cyrillic 's'.
'anything'
"""
''')
result = testdir.runpytest('--doctest-modules')
result.stdout.fnmatch_lines([
'Got nothing',
'* 1 failed in*',
])
def test_ignore_import_errors_on_doctest(self, testdir):
p = testdir.makepyfile("""
import asdf
@@ -579,4 +637,4 @@ class TestDoctestAutoUseFixtures:
""")
result = testdir.runpytest('--doctest-modules')
assert 'FAILURES' not in str(result.stdout.str())
result.stdout.fnmatch_lines(['*=== 1 passed in *'])
result.stdout.fnmatch_lines(['*=== 1 passed in *'])

View File

@@ -2,7 +2,9 @@
from xml.dom import minidom
from _pytest.main import EXIT_NOTESTSCOLLECTED
import py, sys, os
import py
import sys
import os
from _pytest.junitxml import LogXML
import pytest
@@ -11,16 +13,72 @@ def runandparse(testdir, *args):
resultpath = testdir.tmpdir.join("junit.xml")
result = testdir.runpytest("--junitxml=%s" % resultpath, *args)
xmldoc = minidom.parse(str(resultpath))
return result, xmldoc
return result, DomNode(xmldoc)
def assert_attr(node, **kwargs):
__tracebackhide__ = True
for name, expected in kwargs.items():
def nodeval(node, name):
anode = node.getAttributeNode(name)
assert anode, "node %r has no attribute %r" %(node, name)
val = anode.value
if val != str(expected):
py.test.fail("%r != %r" %(str(val), str(expected)))
if anode is not None:
return anode.value
expected = dict((name, str(value)) for name, value in kwargs.items())
on_node = dict((name, nodeval(node, name)) for name in expected)
assert on_node == expected
class DomNode(object):
def __init__(self, dom):
self.__node = dom
def __repr__(self):
return self.__node.toxml()
def find_first_by_tag(self, tag):
return self.find_nth_by_tag(tag, 0)
def _by_tag(self, tag):
return self.__node.getElementsByTagName(tag)
def find_nth_by_tag(self, tag, n):
items = self._by_tag(tag)
try:
nth = items[n]
except IndexError:
pass
else:
return type(self)(nth)
def find_by_tag(self, tag):
t = type(self)
return [t(x) for x in self.__node.getElementsByTagName(tag)]
def __getitem__(self, key):
node = self.__node.getAttributeNode(key)
if node is not None:
return node.value
def assert_attr(self, **kwargs):
__tracebackhide__ = True
return assert_attr(self.__node, **kwargs)
def toxml(self):
return self.__node.toxml()
@property
def text(self):
return self.__node.childNodes[0].wholeText
@property
def tag(self):
return self.__node.tagName
@property
def next_siebling(self):
return type(self)(self.__node.nextSibling)
class TestPython:
def test_summing_simple(self, testdir):
@@ -41,8 +99,8 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, name="pytest", errors=0, failures=1, skips=3, tests=2)
node = dom.find_first_by_tag("testsuite")
node.assert_attr(name="pytest", errors=0, failures=1, skips=3, tests=2)
def test_timing_function(self, testdir):
testdir.makepyfile("""
@@ -55,9 +113,9 @@ class TestPython:
time.sleep(0.01)
""")
result, dom = runandparse(testdir)
node = dom.getElementsByTagName("testsuite")[0]
tnode = node.getElementsByTagName("testcase")[0]
val = tnode.getAttributeNode("time").value
node = dom.find_first_by_tag("testsuite")
tnode = node.find_first_by_tag("testcase")
val = tnode["time"]
assert round(float(val), 2) >= 0.03
def test_setup_error(self, testdir):
@@ -69,16 +127,16 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, errors=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(errors=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_setup_error.py",
line="2",
classname="test_setup_error",
name="test_function")
fnode = tnode.getElementsByTagName("error")[0]
assert_attr(fnode, message="test setup failure")
fnode = tnode.find_first_by_tag("error")
fnode.assert_attr(message="test setup failure")
assert "ValueError" in fnode.toxml()
def test_skip_contains_name_reason(self, testdir):
@@ -89,19 +147,16 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert result.ret == 0
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, skips=1)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(skips=1)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_skip_contains_name_reason.py",
line="1",
classname="test_skip_contains_name_reason",
name="test_skip")
snode = tnode.getElementsByTagName("skipped")[0]
assert_attr(snode,
type="pytest.skip",
message="hello23",
)
snode = tnode.find_first_by_tag("skipped")
snode.assert_attr(type="pytest.skip", message="hello23", )
def test_classname_instance(self, testdir):
testdir.makepyfile("""
@@ -111,10 +166,10 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, failures=1)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(failures=1)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_classname_instance.py",
line="1",
classname="test_classname_instance.TestClass",
@@ -125,10 +180,10 @@ class TestPython:
p.write("def test_func(): 0/0")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, failures=1)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(failures=1)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file=os.path.join("sub", "test_hello.py"),
line="0",
classname="sub.test_hello",
@@ -139,12 +194,12 @@ class TestPython:
testdir.makepyfile("def test_function(): pass")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, errors=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode, classname="pytest", name="internal")
fnode = tnode.getElementsByTagName("error")[0]
assert_attr(fnode, message="internal error")
node = dom.find_first_by_tag("testsuite")
node.assert_attr(errors=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(classname="pytest", name="internal")
fnode = tnode.find_first_by_tag("error")
fnode.assert_attr(message="internal error")
assert "Division" in fnode.toxml()
def test_failure_function(self, testdir):
@@ -158,22 +213,22 @@ class TestPython:
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, failures=1, tests=1)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(failures=1, tests=1)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_failure_function.py",
line="1",
classname="test_failure_function",
name="test_fail")
fnode = tnode.getElementsByTagName("failure")[0]
assert_attr(fnode, message="ValueError: 42")
fnode = tnode.find_first_by_tag("failure")
fnode.assert_attr(message="ValueError: 42")
assert "ValueError" in fnode.toxml()
systemout = fnode.nextSibling
assert systemout.tagName == "system-out"
systemout = fnode.next_siebling
assert systemout.tag == "system-out"
assert "hello-stdout" in systemout.toxml()
systemerr = systemout.nextSibling
assert systemerr.tagName == "system-err"
systemerr = systemout.next_siebling
assert systemerr.tag == "system-err"
assert "hello-stderr" in systemerr.toxml()
def test_failure_verbose_message(self, testdir):
@@ -184,10 +239,10 @@ class TestPython:
""")
result, dom = runandparse(testdir)
node = dom.getElementsByTagName("testsuite")[0]
tnode = node.getElementsByTagName("testcase")[0]
fnode = tnode.getElementsByTagName("failure")[0]
assert_attr(fnode, message="AssertionError: An error assert 0")
node = dom.find_first_by_tag("testsuite")
tnode = node.find_first_by_tag("testcase")
fnode = tnode.find_first_by_tag("failure")
fnode.assert_attr(message="AssertionError: An error assert 0")
def test_failure_escape(self, testdir):
testdir.makepyfile("""
@@ -199,22 +254,21 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, failures=3, tests=3)
node = dom.find_first_by_tag("testsuite")
node.assert_attr(failures=3, tests=3)
for index, char in enumerate("<&'"):
tnode = node.getElementsByTagName("testcase")[index]
assert_attr(tnode,
tnode = node.find_nth_by_tag("testcase", index)
tnode.assert_attr(
file="test_failure_escape.py",
line="1",
classname="test_failure_escape",
name="test_func[%s]" % char)
sysout = tnode.getElementsByTagName('system-out')[0]
text = sysout.childNodes[0].wholeText
sysout = tnode.find_first_by_tag('system-out')
text = sysout.text
assert text == '%s\n' % char
def test_junit_prefixing(self, testdir):
testdir.makepyfile("""
def test_func():
@@ -225,20 +279,20 @@ class TestPython:
""")
result, dom = runandparse(testdir, "--junitprefix=xyz")
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, failures=1, tests=2)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(failures=1, tests=2)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_junit_prefixing.py",
line="0",
classname="xyz.test_junit_prefixing",
name="test_func")
tnode = node.getElementsByTagName("testcase")[1]
assert_attr(tnode,
tnode = node.find_nth_by_tag("testcase", 1)
tnode.assert_attr(
file="test_junit_prefixing.py",
line="3",
classname="xyz.test_junit_prefixing."
"TestHello",
"TestHello",
name="test_hello")
def test_xfailure_function(self, testdir):
@@ -249,17 +303,17 @@ class TestPython:
""")
result, dom = runandparse(testdir)
assert not result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, skips=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(skips=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_xfailure_function.py",
line="1",
classname="test_xfailure_function",
name="test_xfail")
fnode = tnode.getElementsByTagName("skipped")[0]
assert_attr(fnode, message="expected test failure")
#assert "ValueError" in fnode.toxml()
fnode = tnode.find_first_by_tag("skipped")
fnode.assert_attr(message="expected test failure")
# assert "ValueError" in fnode.toxml()
def test_xfailure_xpass(self, testdir):
testdir.makepyfile("""
@@ -269,49 +323,50 @@ class TestPython:
pass
""")
result, dom = runandparse(testdir)
#assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, skips=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
# assert result.ret
node = dom.find_first_by_tag("testsuite")
node.assert_attr(skips=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_xfailure_xpass.py",
line="1",
classname="test_xfailure_xpass",
name="test_xpass")
fnode = tnode.getElementsByTagName("skipped")[0]
assert_attr(fnode, message="xfail-marked test passes unexpectedly")
#assert "ValueError" in fnode.toxml()
fnode = tnode.find_first_by_tag("skipped")
fnode.assert_attr(message="xfail-marked test passes unexpectedly")
# assert "ValueError" in fnode.toxml()
def test_collect_error(self, testdir):
testdir.makepyfile("syntax error")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, errors=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(errors=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_collect_error.py",
#classname="test_collect_error",
name="test_collect_error")
assert tnode.getAttributeNode("line") is None
fnode = tnode.getElementsByTagName("error")[0]
assert_attr(fnode, message="collection failure")
assert tnode["line"] is None
fnode = tnode.find_first_by_tag("error")
fnode.assert_attr(message="collection failure")
assert "SyntaxError" in fnode.toxml()
def test_collect_skipped(self, testdir):
testdir.makepyfile("import pytest; pytest.skip('xyz')")
result, dom = runandparse(testdir)
assert result.ret == EXIT_NOTESTSCOLLECTED
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, skips=1, tests=0)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
node = dom.find_first_by_tag("testsuite")
node.assert_attr(skips=1, tests=0)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(
file="test_collect_skipped.py",
#classname="test_collect_error",
name="test_collect_skipped")
assert tnode.getAttributeNode("line") is None # py.test doesn't give us a line here.
fnode = tnode.getElementsByTagName("skipped")[0]
assert_attr(fnode, message="collection skipped")
# py.test doesn't give us a line here.
assert tnode["line"] is None
fnode = tnode.find_first_by_tag("skipped")
fnode.assert_attr(message="collection skipped")
def test_unicode(self, testdir):
value = 'hx\xc4\x85\xc4\x87\n'
@@ -323,8 +378,8 @@ class TestPython:
""" % value)
result, dom = runandparse(testdir)
assert result.ret == 1
tnode = dom.getElementsByTagName("testcase")[0]
fnode = tnode.getElementsByTagName("failure")[0]
tnode = dom.find_first_by_tag("testcase")
fnode = tnode.find_first_by_tag("failure")
if not sys.platform.startswith("java"):
assert "hx" in fnode.toxml()
@@ -347,9 +402,9 @@ class TestPython:
print('hello-stdout')
""")
result, dom = runandparse(testdir)
node = dom.getElementsByTagName("testsuite")[0]
pnode = node.getElementsByTagName("testcase")[0]
systemout = pnode.getElementsByTagName("system-out")[0]
node = dom.find_first_by_tag("testsuite")
pnode = node.find_first_by_tag("testcase")
systemout = pnode.find_first_by_tag("system-out")
assert "hello-stdout" in systemout.toxml()
def test_pass_captures_stderr(self, testdir):
@@ -359,27 +414,61 @@ class TestPython:
sys.stderr.write('hello-stderr')
""")
result, dom = runandparse(testdir)
node = dom.getElementsByTagName("testsuite")[0]
pnode = node.getElementsByTagName("testcase")[0]
systemout = pnode.getElementsByTagName("system-err")[0]
node = dom.find_first_by_tag("testsuite")
pnode = node.find_first_by_tag("testcase")
systemout = pnode.find_first_by_tag("system-err")
assert "hello-stderr" in systemout.toxml()
def test_setup_error_captures_stdout(self, testdir):
testdir.makepyfile("""
def pytest_funcarg__arg(request):
print('hello-stdout')
raise ValueError()
def test_function(arg):
pass
""")
result, dom = runandparse(testdir)
node = dom.find_first_by_tag("testsuite")
pnode = node.find_first_by_tag("testcase")
systemout = pnode.find_first_by_tag("system-out")
assert "hello-stdout" in systemout.toxml()
def test_setup_error_captures_stderr(self, testdir):
testdir.makepyfile("""
import sys
def pytest_funcarg__arg(request):
sys.stderr.write('hello-stderr')
raise ValueError()
def test_function(arg):
pass
""")
result, dom = runandparse(testdir)
node = dom.find_first_by_tag("testsuite")
pnode = node.find_first_by_tag("testcase")
systemout = pnode.find_first_by_tag("system-err")
assert "hello-stderr" in systemout.toxml()
def test_mangle_testnames():
from _pytest.junitxml import mangle_testnames
names = ["a/pything.py", "Class", "()", "method"]
newnames = mangle_testnames(names)
assert newnames == ["a.pything", "Class", "method"]
def test_dont_configure_on_slaves(tmpdir):
gotten = []
class FakeConfig:
def __init__(self):
self.pluginmanager = self
self.option = self
junitprefix = None
#XXX: shouldnt need tmpdir ?
# XXX: shouldnt need tmpdir ?
xmlpath = str(tmpdir.join('junix.xml'))
register = gotten.append
fake_config = FakeConfig()
from _pytest import junitxml
junitxml.pytest_configure(fake_config)
@@ -408,14 +497,12 @@ class TestNonPython:
testdir.tmpdir.join("myfile.xyz").write("hello")
result, dom = runandparse(testdir)
assert result.ret
node = dom.getElementsByTagName("testsuite")[0]
assert_attr(node, errors=0, failures=1, skips=0, tests=1)
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode,
#classname="test_collect_error",
name="myfile.xyz")
fnode = tnode.getElementsByTagName("failure")[0]
assert_attr(fnode, message="custom item runtest failed")
node = dom.find_first_by_tag("testsuite")
node.assert_attr(errors=0, failures=1, skips=0, tests=1)
tnode = node.find_first_by_tag("testcase")
tnode.assert_attr(name="myfile.xyz")
fnode = tnode.find_first_by_tag("failure")
fnode.assert_attr(message="custom item runtest failed")
assert "custom item runtest failed" in fnode.toxml()
@@ -449,6 +536,7 @@ def test_nullbyte_replace(testdir):
text = xmlf.read()
assert '#x0' in text
def test_invalid_xml_escape():
# Test some more invalid xml chars, the full range should be
# tested really but let's just thest the edges of the ranges
@@ -463,14 +551,13 @@ def test_invalid_xml_escape():
unichr(65)
except NameError:
unichr = chr
invalid = (0x00, 0x1, 0xB, 0xC, 0xE, 0x19,
27, # issue #126
0xD800, 0xDFFF, 0xFFFE, 0x0FFFF) #, 0x110000)
valid = (0x9, 0xA, 0x20,) # 0xD, 0xD7FF, 0xE000, 0xFFFD, 0x10000, 0x10FFFF)
invalid = (0x00, 0x1, 0xB, 0xC, 0xE, 0x19, 27, # issue #126
0xD800, 0xDFFF, 0xFFFE, 0x0FFFF) # , 0x110000)
valid = (0x9, 0xA, 0x20, )
# 0xD, 0xD7FF, 0xE000, 0xFFFD, 0x10000, 0x10FFFF)
from _pytest.junitxml import bin_xml_escape
for i in invalid:
got = bin_xml_escape(unichr(i)).uniobj
if i <= 0xFF:
@@ -481,6 +568,7 @@ def test_invalid_xml_escape():
for i in valid:
assert chr(i) == bin_xml_escape(unichr(i)).uniobj
def test_logxml_path_expansion(tmpdir, monkeypatch):
home_tilde = py.path.local(os.path.expanduser('~')).join('test.xml')
@@ -494,6 +582,7 @@ def test_logxml_path_expansion(tmpdir, monkeypatch):
xml_var = LogXML('$HOME%stest.xml' % tmpdir.sep, None)
assert xml_var.logfile == home_var
def test_logxml_changingdir(testdir):
testdir.makepyfile("""
def test_func():
@@ -505,6 +594,7 @@ def test_logxml_changingdir(testdir):
assert result.ret == 0
assert testdir.tmpdir.join("a/x.xml").check()
def test_logxml_makedir(testdir):
"""--junitxml should automatically create directories for the xml file"""
testdir.makepyfile("""
@@ -515,6 +605,7 @@ def test_logxml_makedir(testdir):
assert result.ret == 0
assert testdir.tmpdir.join("path/to/results.xml").check()
def test_escaped_parametrized_names_xml(testdir):
testdir.makepyfile("""
import pytest
@@ -524,49 +615,57 @@ def test_escaped_parametrized_names_xml(testdir):
""")
result, dom = runandparse(testdir)
assert result.ret == 0
node = dom.getElementsByTagName("testcase")[0]
assert_attr(node,
name="test_func[#x00]")
node = dom.find_first_by_tag("testcase")
node.assert_attr(name="test_func[#x00]")
def test_unicode_issue368(testdir):
path = testdir.tmpdir.join("test.xml")
log = LogXML(str(path), None)
ustr = py.builtin._totext("ВНИ!", "utf-8")
from _pytest.runner import BaseReport
class Report(BaseReport):
longrepr = ustr
sections = []
nodeid = "something"
location = 'tests/filename.py', 42, 'TestClass.method'
report = Report()
test_report = Report()
# hopefully this is not too brittle ...
log.pytest_sessionstart()
log._opentestcase(report)
log.append_failure(report)
log.append_collect_error(report)
log.append_collect_skipped(report)
log.append_error(report)
report.longrepr = "filename", 1, ustr
log.append_skipped(report)
report.longrepr = "filename", 1, "Skipped: 卡嘣嘣"
log.append_skipped(report)
report.wasxfail = ustr
log.append_skipped(report)
node_reporter = log._opentestcase(test_report)
node_reporter.append_failure(test_report)
node_reporter.append_collect_error(test_report)
node_reporter.append_collect_skipped(test_report)
node_reporter.append_error(test_report)
test_report.longrepr = "filename", 1, ustr
node_reporter.append_skipped(test_report)
test_report.longrepr = "filename", 1, "Skipped: 卡嘣嘣"
node_reporter.append_skipped(test_report)
test_report.wasxfail = ustr
node_reporter.append_skipped(test_report)
log.pytest_sessionfinish()
def test_record_property(testdir):
testdir.makepyfile("""
def test_record(record_xml_property):
import pytest
@pytest.fixture
def other(record_xml_property):
record_xml_property("bar", 1)
def test_record(record_xml_property, other):
record_xml_property("foo", "<1");
""")
result, dom = runandparse(testdir, '-rw')
node = dom.getElementsByTagName("testsuite")[0]
tnode = node.getElementsByTagName("testcase")[0]
psnode = tnode.getElementsByTagName('properties')[0]
pnode = psnode.getElementsByTagName('property')[0]
assert_attr(pnode, name="foo", value="<1")
node = dom.find_first_by_tag("testsuite")
tnode = node.find_first_by_tag("testcase")
psnode = tnode.find_first_by_tag('properties')
pnodes = psnode.find_by_tag('property')
pnodes[0].assert_attr(name="bar", value="1")
pnodes[1].assert_attr(name="foo", value="<1")
result.stdout.fnmatch_lines('*C3*test_record_property.py*experimental*')
@@ -583,10 +682,89 @@ def test_random_report_log_xdist(testdir):
assert i != 22
""")
_, dom = runandparse(testdir, '-n2')
suite_node = dom.getElementsByTagName("testsuite")[0]
suite_node = dom.find_first_by_tag("testsuite")
failed = []
for case_node in suite_node.getElementsByTagName("testcase"):
if case_node.getElementsByTagName('failure'):
failed.append(case_node.getAttributeNode('name').value)
for case_node in suite_node.find_by_tag("testcase"):
if case_node.find_first_by_tag('failure'):
failed.append(case_node['name'])
assert failed == ['test_x[22]']
def test_runs_twice(testdir):
f = testdir.makepyfile('''
def test_pass():
pass
''')
result, dom = runandparse(testdir, f, f)
assert 'INTERNALERROR' not in result.stdout.str()
first, second = [x['classname'] for x in dom.find_by_tag("testcase")]
assert first == second
@pytest.mark.xfail(reason='hangs', run=False)
def test_runs_twice_xdist(testdir):
pytest.importorskip('xdist')
f = testdir.makepyfile('''
def test_pass():
pass
''')
result, dom = runandparse(
testdir, f,
'--dist', 'each', '--tx', '2*popen',)
assert 'INTERNALERROR' not in result.stdout.str()
first, second = [x['classname'] for x in dom.find_by_tag("testcase")]
assert first == second
def test_fancy_items_regression(testdir):
# issue 1259
testdir.makeconftest("""
import pytest
class FunItem(pytest.Item):
def runtest(self):
pass
class NoFunItem(pytest.Item):
def runtest(self):
pass
class FunCollector(pytest.File):
def collect(self):
return [
FunItem('a', self),
NoFunItem('a', self),
NoFunItem('b', self),
]
def pytest_collect_file(path, parent):
if path.check(ext='.py'):
return FunCollector(path, parent)
""")
testdir.makepyfile('''
def test_pass():
pass
''')
result, dom = runandparse(testdir)
assert 'INTERNALERROR' not in result.stdout.str()
items = sorted(
'%(classname)s %(name)s %(file)s' % x
for x in dom.find_by_tag("testcase"))
import pprint
pprint.pprint(items)
assert items == [
u'conftest a conftest.py',
u'conftest a conftest.py',
u'conftest b conftest.py',
u'test_fancy_items_regression a test_fancy_items_regression.py',
u'test_fancy_items_regression a test_fancy_items_regression.py',
u'test_fancy_items_regression b test_fancy_items_regression.py',
u'test_fancy_items_regression test_pass'
u' test_fancy_items_regression.py',
]

View File

@@ -1,7 +1,11 @@
import os, sys
import os
import sys
import textwrap
import pytest
from _pytest.monkeypatch import monkeypatch as MonkeyPatch
def pytest_funcarg__mp(request):
cwd = os.getcwd()
sys_path = list(sys.path)
@@ -13,9 +17,11 @@ def pytest_funcarg__mp(request):
request.addfinalizer(cleanup)
return MonkeyPatch()
def test_setattr():
class A:
x = 1
monkeypatch = MonkeyPatch()
pytest.raises(AttributeError, "monkeypatch.setattr(A, 'notexists', 2)")
monkeypatch.setattr(A, 'y', 2, raising=False)
@@ -32,9 +38,10 @@ def test_setattr():
assert A.x == 1
A.x = 5
monkeypatch.undo() # double-undo makes no modification
monkeypatch.undo() # double-undo makes no modification
assert A.x == 5
class TestSetattrWithImportPath:
def test_string_expression(self, monkeypatch):
monkeypatch.setattr("os.path.abspath", lambda x: "hello2")
@@ -55,11 +62,11 @@ class TestSetattrWithImportPath:
pytest.raises(TypeError, lambda: monkeypatch.setattr(None, None))
def test_unknown_import(self, monkeypatch):
pytest.raises(pytest.fail.Exception,
pytest.raises(ImportError,
lambda: monkeypatch.setattr("unkn123.classx", None))
def test_unknown_attr(self, monkeypatch):
pytest.raises(pytest.fail.Exception,
pytest.raises(AttributeError,
lambda: monkeypatch.setattr("os.path.qweqwe", None))
def test_unknown_attr_non_raising(self, monkeypatch):
@@ -73,9 +80,11 @@ class TestSetattrWithImportPath:
monkeypatch.undo()
assert os.path.abspath
def test_delattr():
class A:
x = 1
monkeypatch = MonkeyPatch()
monkeypatch.delattr(A, 'x')
assert not hasattr(A, 'x')
@@ -91,6 +100,7 @@ def test_delattr():
monkeypatch.undo()
assert A.x == 1
def test_setitem():
d = {'x': 1}
monkeypatch = MonkeyPatch()
@@ -108,6 +118,7 @@ def test_setitem():
monkeypatch.undo()
assert d['x'] == 5
def test_setitem_deleted_meanwhile():
d = {}
monkeypatch = MonkeyPatch()
@@ -116,6 +127,7 @@ def test_setitem_deleted_meanwhile():
monkeypatch.undo()
assert not d
@pytest.mark.parametrize("before", [True, False])
def test_setenv_deleted_meanwhile(before):
key = "qwpeoip123"
@@ -131,6 +143,7 @@ def test_setenv_deleted_meanwhile(before):
else:
assert key not in os.environ
def test_delitem():
d = {'x': 1}
monkeypatch = MonkeyPatch()
@@ -147,6 +160,7 @@ def test_delitem():
monkeypatch.undo()
assert d == {'hello': 'world', 'x': 1}
def test_setenv():
monkeypatch = MonkeyPatch()
monkeypatch.setenv('XYZ123', 2)
@@ -155,6 +169,7 @@ def test_setenv():
monkeypatch.undo()
assert 'XYZ123' not in os.environ
def test_delenv():
name = 'xyz1234'
assert name not in os.environ
@@ -175,6 +190,7 @@ def test_delenv():
if name in os.environ:
del os.environ[name]
def test_setenv_prepend():
import os
monkeypatch = MonkeyPatch()
@@ -185,6 +201,7 @@ def test_setenv_prepend():
monkeypatch.undo()
assert 'XYZ123' not in os.environ
def test_monkeypatch_plugin(testdir):
reprec = testdir.inline_runsource("""
def test_method(monkeypatch):
@@ -193,6 +210,7 @@ def test_monkeypatch_plugin(testdir):
res = reprec.countoutcomes()
assert tuple(res) == (1, 0, 0), res
def test_syspath_prepend(mp):
old = list(sys.path)
mp.syspath_prepend('world')
@@ -204,6 +222,7 @@ def test_syspath_prepend(mp):
mp.undo()
assert sys.path == old
def test_syspath_prepend_double_undo(mp):
mp.syspath_prepend('hello world')
mp.undo()
@@ -211,20 +230,24 @@ def test_syspath_prepend_double_undo(mp):
mp.undo()
assert sys.path[-1] == 'more hello world'
def test_chdir_with_path_local(mp, tmpdir):
mp.chdir(tmpdir)
assert os.getcwd() == tmpdir.strpath
def test_chdir_with_str(mp, tmpdir):
mp.chdir(tmpdir.strpath)
assert os.getcwd() == tmpdir.strpath
def test_chdir_undo(mp, tmpdir):
cwd = os.getcwd()
mp.chdir(tmpdir)
mp.undo()
assert os.getcwd() == cwd
def test_chdir_double_undo(mp, tmpdir):
mp.chdir(tmpdir.strpath)
mp.undo()
@@ -232,6 +255,7 @@ def test_chdir_double_undo(mp, tmpdir):
mp.undo()
assert os.getcwd() == tmpdir.strpath
def test_issue185_time_breaks(testdir):
testdir.makepyfile("""
import time
@@ -246,6 +270,22 @@ def test_issue185_time_breaks(testdir):
""")
def test_importerror(testdir):
p = testdir.mkpydir("package")
p.join("a.py").write(textwrap.dedent("""\
import doesnotexist
x = 1
"""))
testdir.tmpdir.join("test_importerror.py").write(textwrap.dedent("""\
def test_importerror(monkeypatch):
monkeypatch.setattr('package.a.x', 2)
"""))
result = testdir.runpytest()
result.stdout.fnmatch_lines("""
*import error in package.a: No module named {0}doesnotexist{0}*
""".format("'" if sys.version_info > (3, 0) else ""))
class SampleNew(object):
@staticmethod
@@ -258,11 +298,12 @@ class SampleNewInherit(SampleNew):
class SampleOld:
#oldstyle on python2
# oldstyle on python2
@staticmethod
def hello():
return True
class SampleOldInherit(SampleOld):
pass
@@ -280,4 +321,10 @@ def test_issue156_undo_staticmethod(Sample):
monkeypatch.undo()
assert Sample.hello()
def test_issue1338_name_resolving():
pytest.importorskip('requests')
monkeypatch = MonkeyPatch()
try:
monkeypatch.delattr('requests.sessions.Session.request')
finally:
monkeypatch.undo()

View File

@@ -75,6 +75,22 @@ class TestPDB:
if child.isalive():
child.wait()
def test_pdb_interaction_capture(self, testdir):
p1 = testdir.makepyfile("""
def test_1():
print("getrekt")
assert False
""")
child = testdir.spawn_pytest("--pdb %s" % p1)
child.expect("getrekt")
child.expect("(Pdb)")
child.sendeof()
rest = child.read().decode("utf8")
assert "1 failed" in rest
assert "getrekt" not in rest
if child.isalive():
child.wait()
def test_pdb_interaction_exception(self, testdir):
p1 = testdir.makepyfile("""
import pytest

View File

@@ -67,9 +67,10 @@ class TestWarningsRecorderChecker(object):
class TestDeprecatedCall(object):
"""test pytest.deprecated_call()"""
def dep(self, i):
def dep(self, i, j=None):
if i == 0:
py.std.warnings.warn("is deprecated", DeprecationWarning)
py.std.warnings.warn("is deprecated", DeprecationWarning,
stacklevel=1)
return 42
def dep_explicit(self, i):
@@ -79,11 +80,11 @@ class TestDeprecatedCall(object):
def test_deprecated_call_raises(self):
with pytest.raises(AssertionError) as excinfo:
pytest.deprecated_call(self.dep, 3)
pytest.deprecated_call(self.dep, 3, 5)
assert str(excinfo).find("did not produce") != -1
def test_deprecated_call(self):
pytest.deprecated_call(self.dep, 0)
pytest.deprecated_call(self.dep, 0, 5)
def test_deprecated_call_ret(self):
ret = pytest.deprecated_call(self.dep, 0)

View File

@@ -739,6 +739,23 @@ def test_terminal_summary(testdir):
world
""")
def test_terminal_summary_warnings_are_displayed(testdir):
"""Test that warnings emitted during pytest_terminal_summary are displayed.
(#1305).
"""
testdir.makeconftest("""
def pytest_terminal_summary(terminalreporter):
config = terminalreporter.config
config.warn('C1', 'internal warning')
""")
result = testdir.runpytest('-rw')
result.stdout.fnmatch_lines([
'*C1*internal warning',
'*== 1 pytest-warnings in *',
])
@pytest.mark.parametrize("exp_color, exp_line, stats_arg", [
# The method under test only cares about the length of each
# dict value, not the actual contents, so tuples of anything

View File

@@ -12,6 +12,7 @@ passenv = USER USERNAME
deps=
nose
mock
requests
[testenv:py26]
commands= py.test --lsof -rfsxX {posargs:testing}
@@ -155,4 +156,4 @@ norecursedirs = .tox ja .hg cx_freeze_source
[flake8]
ignore =E401,E225,E261,E128,E124,E301,E302,E121,E303,W391,E501,E231,E126,E701,E265,E241,E251,E226,E101,W191,E131,E203,E122,E123,E271,E712,E222,E127,E125,E221,W292,E111,E113,E293,E262,W293,E129,E702,E201,E272,E202
ignore =E401,E225,E261,E128,E124,E301,E302,E121,E303,W391,E501,E231,E126,E701,E265,E241,E251,E226,E101,W191,E131,E203,E122,E123,E271,E712,E222,E127,E125,E221,W292,E111,E113,E293,E262,W293,E129,E702,E201,E272,E202,E704,E731,E402