Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3315b3a12f | ||
|
|
64d7d00218 | ||
|
|
7c747c97ec | ||
|
|
56c5db6e12 | ||
|
|
2d05f831fe | ||
|
|
cb6181255e | ||
|
|
cd9e30b221 | ||
|
|
d028fe1e66 | ||
|
|
b825af2e66 | ||
|
|
60e9698530 | ||
|
|
9e6bb74d71 | ||
|
|
c8caa87759 | ||
|
|
b7de0401b8 | ||
|
|
01793ed8bc | ||
|
|
82d00efa8d | ||
|
|
61c569f960 | ||
|
|
dd56d7b7fc | ||
|
|
4de3d595c9 | ||
|
|
b28b3cc271 | ||
|
|
99072ea8c9 | ||
|
|
11a7bcaaa5 | ||
|
|
0caee1a673 | ||
|
|
4c87a6aa09 | ||
|
|
7b13c4bec0 | ||
|
|
aa8c352c10 | ||
|
|
ee75ecbda0 | ||
|
|
b2c0864fbf | ||
|
|
a80efb038a | ||
|
|
5b29f579c5 | ||
|
|
808cb8e3ad | ||
|
|
8727503dd4 | ||
|
|
f46de68804 | ||
|
|
3c19cfcd9a | ||
|
|
29b05c8391 | ||
|
|
26c835eea5 | ||
|
|
e2603d7050 | ||
|
|
369d9ecaa5 | ||
|
|
80d6d94635 | ||
|
|
63cba1ed0d | ||
|
|
71ab6b8b05 | ||
|
|
638b3f5e39 | ||
|
|
0ef73ed3e0 | ||
|
|
7cfb750d7f | ||
|
|
70f72229c6 | ||
|
|
2e02579437 | ||
|
|
8d49abb0d1 | ||
|
|
c5631b6567 | ||
|
|
522224ee7c | ||
|
|
015e8e574a | ||
|
|
87ff7ee232 | ||
|
|
b5490b289d | ||
|
|
99a5067edb | ||
|
|
5afb61ad26 | ||
|
|
fbfab6778c | ||
|
|
57bc14caa0 | ||
|
|
df3f21afb6 | ||
|
|
1a87bb2416 | ||
|
|
6e170a4a1c | ||
|
|
924a9667e1 | ||
|
|
319f6310f8 | ||
|
|
cd3a441304 | ||
|
|
8180165229 | ||
|
|
ec5a429c77 | ||
|
|
713069ebd4 | ||
|
|
8bf7e7cc4b | ||
|
|
7b20288c2b | ||
|
|
2b2bec6b97 | ||
|
|
7eea6b3b02 | ||
|
|
e87facfb22 | ||
|
|
855b115dab | ||
|
|
4263b8b407 | ||
|
|
7d150c20cf | ||
|
|
a124163425 | ||
|
|
2382546112 | ||
|
|
946bb08da5 | ||
|
|
85d1f0404a | ||
|
|
1d60f61ba8 | ||
|
|
ad05cbe6da | ||
|
|
1216a27b44 | ||
|
|
2b2240e904 | ||
|
|
74f7efd2a3 | ||
|
|
34db8aed34 | ||
|
|
af54e09759 | ||
|
|
dfaeefd692 | ||
|
|
46c85bc352 | ||
|
|
139c97930b | ||
|
|
9cfee82f9b | ||
|
|
c0a5f3df10 | ||
|
|
8220c05b01 | ||
|
|
d0f5f6676b | ||
|
|
ec02f694ef | ||
|
|
1c70827f33 | ||
|
|
1c46462991 | ||
|
|
ffa572531a | ||
|
|
fde2a6f5fd | ||
|
|
7b7737bf96 | ||
|
|
04e9ae75c8 | ||
|
|
9ea7826427 | ||
|
|
09cc45b0c5 | ||
|
|
0aa54101c9 | ||
|
|
5eef6a2821 | ||
|
|
518c88f149 | ||
|
|
5f5a7995b9 | ||
|
|
0528e5b45f | ||
|
|
9b04958303 | ||
|
|
faed54d6c7 | ||
|
|
1f609f96e6 | ||
|
|
0664ae137c | ||
|
|
d0107c898e | ||
|
|
9128fec4c4 | ||
|
|
80bcf8d624 | ||
|
|
b8df5446c0 | ||
|
|
2a31df072b | ||
|
|
02f5defd89 | ||
|
|
efb5332023 | ||
|
|
b9908cc036 | ||
|
|
c727860241 | ||
|
|
a4a12b8356 | ||
|
|
13ae2fe28b | ||
|
|
141a463fed | ||
|
|
b48a02fdb1 |
4
AUTHORS
4
AUTHORS
@@ -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
|
||||
|
||||
52
CHANGELOG
52
CHANGELOG
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
35
MANIFEST.in
35
MANIFEST.in
@@ -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
|
||||
|
||||
123
README.rst
123
README.rst
@@ -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.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#
|
||||
__version__ = '2.8.4'
|
||||
__version__ = '2.8.7'
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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[:] = []
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
105
appveyor.yml
105
appveyor.yml
@@ -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%"
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
39
doc/en/announce/release-2.8.5.rst
Normal file
39
doc/en/announce/release-2.8.5.rst
Normal 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.
|
||||
67
doc/en/announce/release-2.8.6.rst
Normal file
67
doc/en/announce/release-2.8.6.rst
Normal 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.
|
||||
31
doc/en/announce/release-2.8.7.rst
Normal file
31
doc/en/announce/release-2.8.7.rst
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ Full pytest documentation
|
||||
plugins
|
||||
cache
|
||||
contributing
|
||||
plugins_index/index
|
||||
talks
|
||||
|
||||
.. only:: html
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ========
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.. highlightlang:: python
|
||||
.. _`goodpractises`:
|
||||
.. _`goodpractices`:
|
||||
|
||||
Good Integration Practices
|
||||
=================================================
|
||||
@@ -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
|
||||
|
||||
@@ -5,10 +5,9 @@ Getting started basics
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
index
|
||||
getting-started
|
||||
usage
|
||||
goodpractises
|
||||
goodpractices
|
||||
projects
|
||||
faq
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 |
@@ -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)*
|
||||
@@ -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))
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
---------------------------
|
||||
|
||||
@@ -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*'])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *'])
|
||||
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
3
tox.ini
3
tox.ini
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user