Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba6ecc14c8 | ||
|
|
41d3b3f4f9 | ||
|
|
dda17994ec | ||
|
|
427cee109a | ||
|
|
30d459e2e3 | ||
|
|
f31447b82b | ||
|
|
b071fdc633 | ||
|
|
19766ef0bc | ||
|
|
94155ee62a | ||
|
|
835328d862 | ||
|
|
8dc497b54b | ||
|
|
da201c7d29 | ||
|
|
01068e5571 | ||
|
|
73cab77249 | ||
|
|
09bcf7f170 | ||
|
|
f1c4cfea2c | ||
|
|
e5deb8a927 | ||
|
|
24db3c123d | ||
|
|
940ed7e943 | ||
|
|
f279bd2bd5 | ||
|
|
6db2f315fa | ||
|
|
7660a19d0a | ||
|
|
8cba033bbb | ||
|
|
6b56c36ae7 | ||
|
|
65be1231b1 | ||
|
|
8639bf7554 | ||
|
|
f484e7c9ca | ||
|
|
2bafa74765 | ||
|
|
77d842ceb2 | ||
|
|
863b7d0c50 | ||
|
|
40ec35767f | ||
|
|
04cf5e1df4 | ||
|
|
138e255631 | ||
|
|
51378aba01 | ||
|
|
8e67dd13e7 | ||
|
|
99efc281ee | ||
|
|
a2b8981b50 | ||
|
|
e21ae3991d | ||
|
|
8a41b26f56 | ||
|
|
b6f766ae87 | ||
|
|
ceeb5149f3 | ||
|
|
b38cf77562 | ||
|
|
c60854474a | ||
|
|
c69fbd79a9 | ||
|
|
183f3737d4 | ||
|
|
1e10de574d | ||
|
|
722f9eadcd | ||
|
|
7a4fe7582c | ||
|
|
96a1d2941b | ||
|
|
ee284ec587 | ||
|
|
927f411ee2 | ||
|
|
919f50a3bd | ||
|
|
8f516d27fa | ||
|
|
d3f4b3d14a | ||
|
|
a1597aca89 | ||
|
|
7d498fdc82 | ||
|
|
2f11a85698 |
3
AUTHORS
3
AUTHORS
@@ -78,6 +78,7 @@ Kale Kundert
|
||||
Katarzyna Jachim
|
||||
Kevin Cox
|
||||
Lee Kamentsky
|
||||
Lev Maximov
|
||||
Lukas Bednar
|
||||
Maciek Fijalkowski
|
||||
Maho
|
||||
@@ -106,6 +107,7 @@ Punyashloka Biswal
|
||||
Quentin Pradet
|
||||
Ralf Schmitt
|
||||
Raphael Pierzina
|
||||
Raquel Alegre
|
||||
Roberto Polli
|
||||
Romain Dorgueil
|
||||
Roman Bolshakov
|
||||
@@ -125,6 +127,7 @@ Ted Xiao
|
||||
Thomas Grainger
|
||||
Tom Viner
|
||||
Trevor Bekolay
|
||||
Tyler Goodlet
|
||||
Vasily Kuznetsov
|
||||
Wouter van Ackooy
|
||||
Xuecong Liao
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
3.0.3
|
||||
=====
|
||||
|
||||
* The ``ids`` argument to ``parametrize`` again accepts ``unicode`` strings
|
||||
in Python 2 (`#1905`_).
|
||||
Thanks `@philpep`_ for the report and `@nicoddemus`_ for the PR.
|
||||
|
||||
* Assertions are now being rewritten for plugins in development mode
|
||||
(``pip install -e``) (`#1934`_).
|
||||
Thanks `@nicoddemus`_ for the PR.
|
||||
|
||||
* Fix pkg_resources import error in Jython projects (`#1853`).
|
||||
Thanks `@raquel-ucl`_ for the PR.
|
||||
|
||||
* Got rid of ``AttributeError: 'Module' object has no attribute '_obj'`` exception
|
||||
in Python 3 (`#1944`_).
|
||||
Thanks `@axil`_ for the PR.
|
||||
|
||||
* Explain a bad scope value passed to ``@fixture`` declarations or
|
||||
a ``MetaFunc.parametrize()`` call. Thanks `@tgoodlet`_ for the PR.
|
||||
|
||||
* This version includes ``pluggy-0.4.0``, which correctly handles
|
||||
``VersionConflict`` errors in plugins (`#704`_).
|
||||
Thanks `@nicoddemus`_ for the PR.
|
||||
|
||||
|
||||
.. _@philpep: https://github.com/philpep
|
||||
.. _@raquel-ucl: https://github.com/raquel-ucl
|
||||
.. _@axil: https://github.com/axil
|
||||
.. _@tgoodlet: https://github.com/tgoodlet
|
||||
|
||||
.. _#1905: https://github.com/pytest-dev/pytest/issues/1905
|
||||
.. _#1934: https://github.com/pytest-dev/pytest/issues/1934
|
||||
.. _#1944: https://github.com/pytest-dev/pytest/issues/1944
|
||||
.. _#704: https://github.com/pytest-dev/pytest/issues/704
|
||||
|
||||
|
||||
|
||||
3.0.2
|
||||
=====
|
||||
|
||||
@@ -75,7 +113,11 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||
|
||||
* Reinterpretation mode has now been removed. Only plain and rewrite
|
||||
mode are available, consequently the ``--assert=reinterp`` option is
|
||||
no longer available. Thanks `@flub`_ for the PR.
|
||||
no longer available. This also means files imported from plugins or
|
||||
``conftest.py`` will not benefit from improved assertions by
|
||||
default, you should use ``pytest.register_assert_rewrite()`` to
|
||||
explicitly turn on assertion rewriting for those files. Thanks
|
||||
`@flub`_ for the PR.
|
||||
|
||||
* The following deprecated commandline options were removed:
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ Note: this assumes you have already registered on pypi.
|
||||
11. Send release announcement to mailing lists:
|
||||
|
||||
- pytest-dev@python.org
|
||||
- testing-in-python@lists.idyll.org
|
||||
- python-announce-list@python.org
|
||||
- testing-in-python@lists.idyll.org (only for minor/major releases)
|
||||
|
||||
And announce the release on Twitter, making sure to add the hashtag ``#pytest``.
|
||||
|
||||
@@ -64,19 +64,19 @@ Note: this assumes you have already registered on pypi.
|
||||
a. **patch release (2.8.3)**:
|
||||
|
||||
1. Checkout ``master``.
|
||||
2. Update version number in ``_pytest/__init__.py`` to ``"2.8.4.dev"``.
|
||||
3. Create a new section in ``CHANGELOG.rst`` titled ``2.8.4.dev`` and add a few bullet points as placeholders for new entries.
|
||||
2. Update version number in ``_pytest/__init__.py`` to ``"2.8.4.dev0"``.
|
||||
3. Create a new section in ``CHANGELOG.rst`` titled ``2.8.4.dev0`` and add a few bullet points as placeholders for new entries.
|
||||
4. Commit and push.
|
||||
|
||||
b. **minor release (2.9.0)**:
|
||||
|
||||
1. Merge ``features`` into ``master``.
|
||||
2. Checkout ``master``.
|
||||
3. Follow the same steps for a **patch release** above, using the next patch release: ``2.9.1.dev``.
|
||||
3. Follow the same steps for a **patch release** above, using the next patch release: ``2.9.1.dev0``.
|
||||
4. Commit ``master``.
|
||||
5. Checkout ``features`` and merge with ``master`` (should be a fast-forward at this point).
|
||||
6. Update version number in ``_pytest/__init__.py`` to the next minor release: ``"2.10.0.dev"``.
|
||||
7. Create a new section in ``CHANGELOG.rst`` titled ``2.10.0.dev``, above ``2.9.1.dev``, and add a few bullet points as placeholders for new entries.
|
||||
6. Update version number in ``_pytest/__init__.py`` to the next minor release: ``"2.10.0.dev0"``.
|
||||
7. Create a new section in ``CHANGELOG.rst`` titled ``2.10.0.dev0``, above ``2.9.1.dev0``, and add a few bullet points as placeholders for new entries.
|
||||
8. Commit ``features``.
|
||||
9. Push ``master`` and ``features``.
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#
|
||||
__version__ = '3.0.2'
|
||||
__version__ = '3.0.3'
|
||||
|
||||
@@ -12,6 +12,7 @@ if sys.version_info[0] >= 3:
|
||||
else:
|
||||
from ._py2traceback import format_exception_only
|
||||
|
||||
|
||||
class Code(object):
|
||||
""" wrapper around Python code objects """
|
||||
def __init__(self, rawcode):
|
||||
@@ -28,6 +29,8 @@ class Code(object):
|
||||
def __eq__(self, other):
|
||||
return self.raw == other.raw
|
||||
|
||||
__hash__ = None
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
|
||||
@@ -52,22 +52,21 @@ class Source(object):
|
||||
return str(self) == other
|
||||
return False
|
||||
|
||||
__hash__ = None
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
return self.lines[key]
|
||||
else:
|
||||
if key.step not in (None, 1):
|
||||
raise IndexError("cannot slice a Source with a step")
|
||||
return self.__getslice__(key.start, key.stop)
|
||||
newsource = Source()
|
||||
newsource.lines = self.lines[key.start:key.stop]
|
||||
return newsource
|
||||
|
||||
def __len__(self):
|
||||
return len(self.lines)
|
||||
|
||||
def __getslice__(self, start, end):
|
||||
newsource = Source()
|
||||
newsource.lines = self.lines[start:end]
|
||||
return newsource
|
||||
|
||||
def strip(self):
|
||||
""" return new source object with trailing
|
||||
and leading blank lines removed.
|
||||
|
||||
@@ -105,7 +105,7 @@ except NameError:
|
||||
def assertrepr_compare(config, op, left, right):
|
||||
"""Return specialised explanations for some operators/operands"""
|
||||
width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op
|
||||
left_repr = py.io.saferepr(left, maxsize=int(width/2))
|
||||
left_repr = py.io.saferepr(left, maxsize=int(width//2))
|
||||
right_repr = py.io.saferepr(right, maxsize=width-len(left_repr))
|
||||
|
||||
summary = u('%s %s %s') % (ecu(left_repr), op, ecu(right_repr))
|
||||
|
||||
@@ -5,7 +5,6 @@ import traceback
|
||||
import types
|
||||
import warnings
|
||||
|
||||
import pkg_resources
|
||||
import py
|
||||
# DON't import pytest here because it causes import cycle troubles
|
||||
import sys, os
|
||||
@@ -952,18 +951,24 @@ class Config(object):
|
||||
except SystemError:
|
||||
mode = 'plain'
|
||||
else:
|
||||
import pkg_resources
|
||||
self.pluginmanager.rewrite_hook = hook
|
||||
for entrypoint in pkg_resources.iter_entry_points('pytest11'):
|
||||
for entry in entrypoint.dist._get_metadata('RECORD'):
|
||||
fn = entry.split(',')[0]
|
||||
is_simple_module = os.sep not in fn and fn.endswith('.py')
|
||||
is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py')
|
||||
if is_simple_module:
|
||||
module_name, ext = os.path.splitext(fn)
|
||||
hook.mark_rewrite(module_name)
|
||||
elif is_package:
|
||||
package_name = os.path.dirname(fn)
|
||||
hook.mark_rewrite(package_name)
|
||||
# 'RECORD' available for plugins installed normally (pip install)
|
||||
# 'SOURCES.txt' available for plugins installed in dev mode (pip install -e)
|
||||
# for installed plugins 'SOURCES.txt' returns an empty list, and vice-versa
|
||||
# so it shouldn't be an issue
|
||||
for metadata in ('RECORD', 'SOURCES.txt'):
|
||||
for entry in entrypoint.dist._get_metadata(metadata):
|
||||
fn = entry.split(',')[0]
|
||||
is_simple_module = os.sep not in fn and fn.endswith('.py')
|
||||
is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py')
|
||||
if is_simple_module:
|
||||
module_name, ext = os.path.splitext(fn)
|
||||
hook.mark_rewrite(module_name)
|
||||
elif is_package:
|
||||
package_name = os.path.dirname(fn)
|
||||
hook.mark_rewrite(package_name)
|
||||
self._warn_about_missing_assertion(mode)
|
||||
|
||||
def _warn_about_missing_assertion(self, mode):
|
||||
|
||||
@@ -599,12 +599,29 @@ class ScopeMismatchError(Exception):
|
||||
which has a lower scope (e.g. a Session one calls a function one)
|
||||
"""
|
||||
|
||||
|
||||
scopes = "session module class function".split()
|
||||
scopenum_function = scopes.index("function")
|
||||
|
||||
|
||||
def scopemismatch(currentscope, newscope):
|
||||
return scopes.index(newscope) > scopes.index(currentscope)
|
||||
|
||||
|
||||
def scope2index(scope, descr, where=None):
|
||||
"""Look up the index of ``scope`` and raise a descriptive value error
|
||||
if not defined.
|
||||
"""
|
||||
try:
|
||||
return scopes.index(scope)
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
"{0} {1}has an unsupported scope value '{2}'".format(
|
||||
descr, 'from {0} '.format(where) if where else '',
|
||||
scope)
|
||||
)
|
||||
|
||||
|
||||
class FixtureLookupError(LookupError):
|
||||
""" could not return a requested Fixture (missing or invalid). """
|
||||
def __init__(self, argname, request, msg=None):
|
||||
@@ -703,6 +720,7 @@ def call_fixture_func(fixturefunc, request, kwargs):
|
||||
res = fixturefunc(**kwargs)
|
||||
return res
|
||||
|
||||
|
||||
class FixtureDef:
|
||||
""" A container for a factory definition. """
|
||||
def __init__(self, fixturemanager, baseid, argname, func, scope, params,
|
||||
@@ -713,7 +731,11 @@ class FixtureDef:
|
||||
self.func = func
|
||||
self.argname = argname
|
||||
self.scope = scope
|
||||
self.scopenum = scopes.index(scope or "function")
|
||||
self.scopenum = scope2index(
|
||||
scope or "function",
|
||||
descr='fixture {0}'.format(func.__name__),
|
||||
where=baseid
|
||||
)
|
||||
self.params = params
|
||||
startindex = unittest and 1 or None
|
||||
self.argnames = getfuncargnames(func, startindex=startindex)
|
||||
|
||||
@@ -19,7 +19,7 @@ def pytest_addoption(parser):
|
||||
help="only run tests which match the given substring expression. "
|
||||
"An expression is a python evaluatable expression "
|
||||
"where all names are substring-matched against test names "
|
||||
"and their parent classes. Example: -k 'test_method or test "
|
||||
"and their parent classes. Example: -k 'test_method or test_"
|
||||
"other' matches all test functions and classes whose name "
|
||||
"contains 'test_method' or 'test_other'. "
|
||||
"Additionally keywords are matched to classes and functions "
|
||||
|
||||
@@ -205,11 +205,10 @@ class PyobjContext(object):
|
||||
class PyobjMixin(PyobjContext):
|
||||
def obj():
|
||||
def fget(self):
|
||||
try:
|
||||
return self._obj
|
||||
except AttributeError:
|
||||
obj = getattr(self, '_obj', None)
|
||||
if obj is None:
|
||||
self._obj = obj = self._getobj()
|
||||
return obj
|
||||
return obj
|
||||
def fset(self, value):
|
||||
self._obj = value
|
||||
return property(fget, fset, None, "underlying python object")
|
||||
@@ -771,7 +770,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||
It will also override any fixture-function defined scope, allowing
|
||||
to set a dynamic scope using test context or configuration.
|
||||
"""
|
||||
from _pytest.fixtures import scopes
|
||||
from _pytest.fixtures import scope2index
|
||||
from _pytest.mark import extract_argvalue
|
||||
from py.io import saferepr
|
||||
|
||||
@@ -800,7 +799,8 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||
if scope is None:
|
||||
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
|
||||
|
||||
scopenum = scopes.index(scope)
|
||||
scopenum = scope2index(
|
||||
scope, descr='call to {0}'.format(self.parametrize))
|
||||
valtypes = {}
|
||||
for arg in argnames:
|
||||
if arg not in self.fixturenames:
|
||||
@@ -832,7 +832,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||
raise ValueError('%d tests specified with %d ids' %(
|
||||
len(argvalues), len(ids)))
|
||||
for id_value in ids:
|
||||
if id_value is not None and not isinstance(id_value, str):
|
||||
if id_value is not None and not isinstance(id_value, py.builtin._basestring):
|
||||
msg = 'ids must be list of strings, found: %s (type: %s)'
|
||||
raise ValueError(msg % (saferepr(id_value), type(id_value).__name__))
|
||||
ids = idmaker(argnames, argvalues, idfn, ids, self.config)
|
||||
@@ -1357,6 +1357,8 @@ class approx(object):
|
||||
return False
|
||||
return all(a == x for a, x in zip(actual, self.expected))
|
||||
|
||||
__hash__ = None
|
||||
|
||||
def __ne__(self, actual):
|
||||
return not (actual == self)
|
||||
|
||||
@@ -1436,6 +1438,8 @@ class ApproxNonIterable(object):
|
||||
# Return true if the two numbers are within the tolerance.
|
||||
return abs(self.expected - actual) <= self.tolerance
|
||||
|
||||
__hash__ = None
|
||||
|
||||
def __ne__(self, actual):
|
||||
return not (actual == self)
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@ $ pip install -U pluggy==<version> --no-compile --target=_pytest/vendored_packag
|
||||
```
|
||||
|
||||
And commit the modified files. The `pluggy-<version>.dist-info` directory
|
||||
created by `pip` should be ignored.
|
||||
created by `pip` should be added as well.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
pluggy.py,sha256=v_RfWzyW6DPU1cJu_EFoL_OHq3t13qloVdR6UaMCXQA,29862
|
||||
pluggy-0.3.1.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7
|
||||
pluggy-0.3.1.dist-info/pbr.json,sha256=xX3s6__wOcAyF-AZJX1sdZyW6PUXT-FkfBlM69EEUCg,47
|
||||
pluggy-0.3.1.dist-info/RECORD,,
|
||||
pluggy-0.3.1.dist-info/metadata.json,sha256=nLKltOT78dMV-00uXD6Aeemp4xNsz2q59j6ORSDeLjw,1027
|
||||
pluggy-0.3.1.dist-info/METADATA,sha256=1b85Ho2u4iK30M099k7axMzcDDhLcIMb-A82JUJZnSo,1334
|
||||
pluggy-0.3.1.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110
|
||||
pluggy-0.3.1.dist-info/DESCRIPTION.rst,sha256=P5Akh1EdIBR6CeqtV2P8ZwpGSpZiTKPw0NyS7jEiD-g,306
|
||||
@@ -1 +0,0 @@
|
||||
{"license": "MIT license", "name": "pluggy", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "summary": "plugin and hook calling mechanisms for python", "platform": "unix", "version": "0.3.1", "extensions": {"python.details": {"document_names": {"description": "DESCRIPTION.rst"}, "contacts": [{"role": "author", "email": "holger at merlinux.eu", "name": "Holger Krekel"}]}}, "classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Libraries", "Topic :: Utilities", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"]}
|
||||
@@ -1 +0,0 @@
|
||||
{"is_release": false, "git_version": "7d4c9cd"}
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
Plugin registration and hook calling for Python
|
||||
===============================================
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
22
_pytest/vendored_packages/pluggy-0.4.0.dist-info/LICENSE.txt
Normal file
22
_pytest/vendored_packages/pluggy-0.4.0.dist-info/LICENSE.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Metadata-Version: 2.0
|
||||
Name: pluggy
|
||||
Version: 0.3.1
|
||||
Version: 0.4.0
|
||||
Summary: plugin and hook calling mechanisms for python
|
||||
Home-page: UNKNOWN
|
||||
Home-page: https://github.com/pytest-dev/pluggy
|
||||
Author: Holger Krekel
|
||||
Author-email: holger at merlinux.eu
|
||||
License: MIT license
|
||||
@@ -27,6 +27,7 @@ Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
|
||||
|
||||
Plugin registration and hook calling for Python
|
||||
===============================================
|
||||
|
||||
9
_pytest/vendored_packages/pluggy-0.4.0.dist-info/RECORD
Normal file
9
_pytest/vendored_packages/pluggy-0.4.0.dist-info/RECORD
Normal file
@@ -0,0 +1,9 @@
|
||||
pluggy.py,sha256=u0oG9cv-oLOkNvEBlwnnu8pp1AyxpoERgUO00S3rvpQ,31543
|
||||
pluggy-0.4.0.dist-info/DESCRIPTION.rst,sha256=ltvjkFd40LW_xShthp6RRVM6OB_uACYDFR3kTpKw7o4,307
|
||||
pluggy-0.4.0.dist-info/LICENSE.txt,sha256=ruwhUOyV1HgE9F35JVL9BCZ9vMSALx369I4xq9rhpkM,1134
|
||||
pluggy-0.4.0.dist-info/METADATA,sha256=pe2hbsqKFaLHC6wAQPpFPn0KlpcPfLBe_BnS4O70bfk,1364
|
||||
pluggy-0.4.0.dist-info/RECORD,,
|
||||
pluggy-0.4.0.dist-info/WHEEL,sha256=9Z5Xm-eel1bTS7e6ogYiKz0zmPEqDwIypurdHN1hR40,116
|
||||
pluggy-0.4.0.dist-info/metadata.json,sha256=T3go5L2qOa_-H-HpCZi3EoVKb8sZ3R-fOssbkWo2nvM,1119
|
||||
pluggy-0.4.0.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7
|
||||
pluggy-0.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
@@ -1,5 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.24.0)
|
||||
Generator: bdist_wheel (0.29.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py2-none-any
|
||||
Tag: py3-none-any
|
||||
@@ -0,0 +1 @@
|
||||
{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Libraries", "Topic :: Utilities", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"], "extensions": {"python.details": {"contacts": [{"email": "holger at merlinux.eu", "name": "Holger Krekel", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://github.com/pytest-dev/pluggy"}}}, "generator": "bdist_wheel (0.29.0)", "license": "MIT license", "metadata_version": "2.0", "name": "pluggy", "platform": "unix", "summary": "plugin and hook calling mechanisms for python", "version": "0.4.0"}
|
||||
@@ -67,8 +67,9 @@ Pluggy currently consists of functionality for:
|
||||
import sys
|
||||
import inspect
|
||||
|
||||
__version__ = '0.3.1'
|
||||
__all__ = ["PluginManager", "PluginValidationError",
|
||||
__version__ = '0.4.0'
|
||||
|
||||
__all__ = ["PluginManager", "PluginValidationError", "HookCallError",
|
||||
"HookspecMarker", "HookimplMarker"]
|
||||
|
||||
_py3 = sys.version_info > (3, 0)
|
||||
@@ -308,7 +309,7 @@ class PluginManager(object):
|
||||
""" Core Pluginmanager class which manages registration
|
||||
of plugin objects and 1:N hook calling.
|
||||
|
||||
You can register new hooks by calling ``addhooks(module_or_class)``.
|
||||
You can register new hooks by calling ``add_hookspec(module_or_class)``.
|
||||
You can register plugin objects (which contain hooks) by calling
|
||||
``register(plugin)``. The Pluginmanager is initialized with a
|
||||
prefix that is searched for in the names of the dict of registered
|
||||
@@ -374,7 +375,10 @@ class PluginManager(object):
|
||||
|
||||
def parse_hookimpl_opts(self, plugin, name):
|
||||
method = getattr(plugin, name)
|
||||
res = getattr(method, self.project_name + "_impl", None)
|
||||
try:
|
||||
res = getattr(method, self.project_name + "_impl", None)
|
||||
except Exception:
|
||||
res = {}
|
||||
if res is not None and not isinstance(res, dict):
|
||||
# false positive
|
||||
res = None
|
||||
@@ -455,6 +459,10 @@ class PluginManager(object):
|
||||
""" Return a plugin or None for the given name. """
|
||||
return self._name2plugin.get(name)
|
||||
|
||||
def has_plugin(self, name):
|
||||
""" Return True if a plugin with the given name is registered. """
|
||||
return self.get_plugin(name) is not None
|
||||
|
||||
def get_name(self, plugin):
|
||||
""" Return name for registered plugin or None if not registered. """
|
||||
for name, val in self._name2plugin.items():
|
||||
@@ -492,7 +500,8 @@ class PluginManager(object):
|
||||
def load_setuptools_entrypoints(self, entrypoint_name):
|
||||
""" Load modules from querying the specified setuptools entrypoint name.
|
||||
Return the number of loaded plugins. """
|
||||
from pkg_resources import iter_entry_points, DistributionNotFound
|
||||
from pkg_resources import (iter_entry_points, DistributionNotFound,
|
||||
VersionConflict)
|
||||
for ep in iter_entry_points(entrypoint_name):
|
||||
# is the plugin registered or blocked?
|
||||
if self.get_plugin(ep.name) or self.is_blocked(ep.name):
|
||||
@@ -501,6 +510,9 @@ class PluginManager(object):
|
||||
plugin = ep.load()
|
||||
except DistributionNotFound:
|
||||
continue
|
||||
except VersionConflict as e:
|
||||
raise PluginValidationError(
|
||||
"Plugin %r could not be loaded: %s!" % (ep.name, e))
|
||||
self.register(plugin, name=ep.name)
|
||||
self._plugin_distinfo.append((plugin, ep.dist))
|
||||
return len(self._plugin_distinfo)
|
||||
@@ -573,7 +585,7 @@ class _MultiCall:
|
||||
|
||||
# XXX note that the __multicall__ argument is supported only
|
||||
# for pytest compatibility reasons. It was never officially
|
||||
# supported there and is explicitly deprecated since 2.8
|
||||
# supported there and is explicitely deprecated since 2.8
|
||||
# so we can remove it soon, allowing to avoid the below recursion
|
||||
# in execute() and simplify/speed up the execute loop.
|
||||
|
||||
@@ -590,7 +602,13 @@ class _MultiCall:
|
||||
|
||||
while self.hook_impls:
|
||||
hook_impl = self.hook_impls.pop()
|
||||
args = [all_kwargs[argname] for argname in hook_impl.argnames]
|
||||
try:
|
||||
args = [all_kwargs[argname] for argname in hook_impl.argnames]
|
||||
except KeyError:
|
||||
for argname in hook_impl.argnames:
|
||||
if argname not in all_kwargs:
|
||||
raise HookCallError(
|
||||
"hook call must provide argument %r" % (argname,))
|
||||
if hook_impl.hookwrapper:
|
||||
return _wrapped_call(hook_impl.function(*args), self.execute)
|
||||
res = hook_impl.function(*args)
|
||||
@@ -629,7 +647,10 @@ def varnames(func, startindex=None):
|
||||
startindex = 1
|
||||
else:
|
||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||
func = getattr(func, '__call__', func)
|
||||
try:
|
||||
func = getattr(func, '__call__', func)
|
||||
except Exception:
|
||||
return ()
|
||||
if startindex is None:
|
||||
startindex = int(inspect.ismethod(func))
|
||||
|
||||
@@ -763,6 +784,10 @@ class PluginValidationError(Exception):
|
||||
""" plugin failed validation. """
|
||||
|
||||
|
||||
class HookCallError(Exception):
|
||||
""" Hook was called wrongly. """
|
||||
|
||||
|
||||
if hasattr(inspect, 'signature'):
|
||||
def _formatdef(func):
|
||||
return "%s%s" % (
|
||||
|
||||
@@ -8,7 +8,8 @@ environment:
|
||||
matrix:
|
||||
# create multiple jobs to execute a set of tox runs on each; this is to workaround having
|
||||
# builds timing out in AppVeyor
|
||||
- TOXENV: "linting,py26,py27,py33,py34,py35,pypy"
|
||||
# pypy is disabled until #1963 gets fixed
|
||||
- TOXENV: "linting,py26,py27,py33,py34,py35"
|
||||
- TOXENV: "py27-pexpect,py27-xdist,py27-trial,py35-pexpect,py35-xdist,py35-trial"
|
||||
- TOXENV: "py27-nobyte,doctesting,freeze,docs"
|
||||
|
||||
|
||||
@@ -19,10 +19,9 @@ REGENDOC_ARGS := \
|
||||
--normalize "@/tmp/pytest-of-.*/pytest-\d+@PYTEST_TMPDIR@" \
|
||||
|
||||
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@@ -36,22 +35,6 @@ help:
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
SITETARGET=$(shell ./_getdoctarget.py)
|
||||
|
||||
showtarget:
|
||||
@echo $(SITETARGET)
|
||||
|
||||
install: html
|
||||
# for access talk to someone with login rights to
|
||||
# pytest-dev@pytest.org to add your ssh key
|
||||
rsync -avz _build/html/ pytest-dev@pytest.org:pytest.org/$(SITETARGET)
|
||||
|
||||
installpdf: latexpdf
|
||||
@scp $(BUILDDIR)/latex/pytest.pdf pytest-dev@pytest.org:pytest.org/$(SITETARGET)
|
||||
|
||||
installall: clean install installpdf
|
||||
@echo "done"
|
||||
|
||||
regen:
|
||||
PYTHONDONTWRITEBYTECODE=1 COLUMNS=76 regendoc --update *.rst */*.rst ${REGENDOC_ARGS}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import py
|
||||
|
||||
def get_version_string():
|
||||
fn = py.path.local(__file__).join("..", "..", "..",
|
||||
"_pytest", "__init__.py")
|
||||
for line in fn.readlines():
|
||||
if "version" in line and not line.strip().startswith('#'):
|
||||
return eval(line.split("=")[-1])
|
||||
|
||||
def get_minor_version_string():
|
||||
return ".".join(get_version_string().split(".")[:2])
|
||||
|
||||
if __name__ == "__main__":
|
||||
print (get_minor_version_string())
|
||||
@@ -6,6 +6,6 @@
|
||||
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</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>
|
||||
<li><a href="https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf">PDF Documentation</a>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-3.0.3
|
||||
release-3.0.2
|
||||
release-3.0.1
|
||||
release-3.0.0
|
||||
|
||||
@@ -12,15 +12,13 @@ The changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Adam Chainz
|
||||
* Andrew Svetlov
|
||||
* Ahn Ki-Wook
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Dmitry Dygalo
|
||||
* Florian Bruhin
|
||||
* Marcin Bachry
|
||||
* Jordan Guymon
|
||||
* Raphael Pierzina
|
||||
* Ronny Pfannschmidt
|
||||
* matthiasha
|
||||
* mbyt
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
|
||||
27
doc/en/announce/release-3.0.3.rst
Normal file
27
doc/en/announce/release-3.0.3.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
pytest-3.0.3
|
||||
============
|
||||
|
||||
pytest 3.0.3 has just been released to PyPI.
|
||||
|
||||
This release fixes some regressions and bugs reported in the last version,
|
||||
being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Bruno Oliveira
|
||||
* Florian Bruhin
|
||||
* Floris Bruynooghe
|
||||
* Huayi Zhang
|
||||
* Lev Maximov
|
||||
* Raquel Alegre
|
||||
* Ronny Pfannschmidt
|
||||
* Roy Williams
|
||||
* Tyler Goodlet
|
||||
* mbyt
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -26,7 +26,7 @@ you will see the return value of the function call::
|
||||
|
||||
$ pytest test_assert1.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
@@ -170,7 +170,7 @@ if you run this module::
|
||||
|
||||
$ pytest test_assert2.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ If you then run it with ``--lf``::
|
||||
|
||||
$ pytest --lf
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
run-last-failure: rerun last 2 failures
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 50 items
|
||||
@@ -122,7 +122,7 @@ of ``FF`` and dots)::
|
||||
|
||||
$ pytest --ff
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
run-last-failure: rerun last 2 failures first
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 50 items
|
||||
@@ -227,7 +227,7 @@ You can always peek at the content of the cache using the
|
||||
|
||||
$ py.test --cache-show
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
cachedir: $REGENDOC_TMPDIR/.cache
|
||||
------------------------------- cache values -------------------------------
|
||||
|
||||
@@ -64,7 +64,7 @@ of the failing function and hide the other one::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
# The short X.Y version.
|
||||
|
||||
import os, sys
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
import _getdoctarget
|
||||
|
||||
version = _getdoctarget.get_minor_version_string()
|
||||
release = _getdoctarget.get_version_string()
|
||||
from _pytest import __version__ as version
|
||||
release = ".".join(version.split(".")[:2])
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
|
||||
@@ -49,7 +49,7 @@ then you can just invoke ``pytest`` without command line options::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
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``::
|
||||
|
||||
$ pytest -v -m webtest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items
|
||||
@@ -45,7 +45,7 @@ Or the inverse, running all tests except the webtest ones::
|
||||
|
||||
$ pytest -v -m "not webtest"
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items
|
||||
@@ -66,7 +66,7 @@ tests based on their module, class, method, or function name::
|
||||
|
||||
$ pytest -v test_server.py::TestClass::test_method
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 5 items
|
||||
@@ -79,7 +79,7 @@ You can also select on the class::
|
||||
|
||||
$ pytest -v test_server.py::TestClass
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items
|
||||
@@ -92,7 +92,7 @@ Or select multiple nodes::
|
||||
|
||||
$ pytest -v test_server.py::TestClass test_server.py::test_send_http
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 8 items
|
||||
@@ -130,7 +130,7 @@ select tests based on their names::
|
||||
|
||||
$ pytest -v -k http # running with the above defined example module
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
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::
|
||||
|
||||
$ pytest -k "not send_http" -v
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items
|
||||
@@ -160,7 +160,7 @@ Or to select "http" and "quick" tests::
|
||||
|
||||
$ pytest -k "http or quick" -v
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items
|
||||
@@ -352,7 +352,7 @@ the test needs::
|
||||
|
||||
$ pytest -E stage2
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
@@ -364,7 +364,7 @@ and here is one that specifies exactly the environment needed::
|
||||
|
||||
$ pytest -E stage1
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
@@ -485,7 +485,7 @@ then you will see two test skipped and two executed tests as expected::
|
||||
|
||||
$ pytest -rs # this option reports skip reasons
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 4 items
|
||||
|
||||
@@ -499,7 +499,7 @@ Note that if you specify a platform via the marker-command line option like this
|
||||
|
||||
$ pytest -m linux2
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 4 items
|
||||
|
||||
@@ -551,7 +551,7 @@ We can now use the ``-m option`` to select one set::
|
||||
|
||||
$ pytest -m interface --tb=short
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 4 items
|
||||
|
||||
@@ -573,7 +573,7 @@ or to select both "event" and "interface" tests::
|
||||
|
||||
$ pytest -m "interface or event" --tb=short
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 4 items
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ now execute the test specification::
|
||||
|
||||
nonpython $ pytest test_simple.yml
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
|
||||
collected 2 items
|
||||
|
||||
@@ -59,7 +59,7 @@ consulted when reporting in ``verbose`` mode::
|
||||
|
||||
nonpython $ pytest -v
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
|
||||
collecting ... collected 2 items
|
||||
@@ -81,7 +81,7 @@ interesting to just look at the collection tree::
|
||||
|
||||
nonpython $ pytest --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
|
||||
collected 2 items
|
||||
<YamlFile 'test_simple.yml'>
|
||||
|
||||
@@ -130,7 +130,7 @@ objects, they are still using the default pytest representation::
|
||||
|
||||
$ pytest test_time.py --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
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::
|
||||
|
||||
$ pytest test_scenarios.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
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
|
||||
|
||||
$ pytest --collect-only test_scenarios.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
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::
|
||||
|
||||
$ pytest test_backends.py --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
<Module 'test_backends.py'>
|
||||
@@ -320,7 +320,7 @@ The result of this test will be successful::
|
||||
|
||||
$ pytest test_indirect_list.py --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
<Module 'test_indirect_list.py'>
|
||||
@@ -447,7 +447,7 @@ If you run this with reporting for skips enabled::
|
||||
|
||||
$ pytest -rs test_module.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ then the test collection looks like this::
|
||||
|
||||
$ pytest --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
||||
collected 2 items
|
||||
<Module 'check_myapp.py'>
|
||||
@@ -163,7 +163,7 @@ You can always peek at the collection tree without running tests like this::
|
||||
|
||||
. $ pytest --collect-only pythoncollection.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
||||
collected 3 items
|
||||
<Module 'CWD/pythoncollection.py'>
|
||||
@@ -230,7 +230,7 @@ will be left out::
|
||||
|
||||
$ pytest --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
|
||||
collected 0 items
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ get on the terminal - we are working on that)::
|
||||
|
||||
assertion $ pytest failure_demo.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR/assertion, inifile:
|
||||
collected 42 items
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ directory with the above conftest.py::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 0 items
|
||||
|
||||
@@ -164,7 +164,7 @@ and when running it will see a skipped "slow" test::
|
||||
|
||||
$ pytest -rs # "-rs" means report details on the little 's'
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
@@ -178,7 +178,7 @@ Or run it including the ``slow`` marked test::
|
||||
|
||||
$ pytest --runslow
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
@@ -302,7 +302,7 @@ which will add the string to the test header accordingly::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
project deps: mylib-1.1
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 0 items
|
||||
@@ -327,7 +327,7 @@ which will add info only when run with "--v"::
|
||||
|
||||
$ pytest -v
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
info1: did you know that ...
|
||||
did you?
|
||||
@@ -340,7 +340,7 @@ and nothing when run plainly::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 0 items
|
||||
|
||||
@@ -374,7 +374,7 @@ Now we can profile which test functions execute the slowest::
|
||||
|
||||
$ pytest --durations=3
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 3 items
|
||||
|
||||
@@ -440,7 +440,7 @@ If we run this::
|
||||
|
||||
$ pytest -rx
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 4 items
|
||||
|
||||
@@ -519,7 +519,7 @@ We can run this::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 7 items
|
||||
|
||||
@@ -627,7 +627,7 @@ and run them::
|
||||
|
||||
$ pytest test_module.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
@@ -721,7 +721,7 @@ and run it::
|
||||
|
||||
$ pytest -s test_module.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 3 items
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
|
||||
$ pytest test_smtpsimple.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
@@ -188,7 +188,7 @@ inspect what is going on and can now run the tests::
|
||||
|
||||
$ pytest test_module.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
@@ -516,7 +516,7 @@ Running the above tests results in the following test IDs being used::
|
||||
|
||||
$ pytest --collect-only
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 11 items
|
||||
<Module 'test_anothersmtp.py'>
|
||||
@@ -569,7 +569,7 @@ Here we declare an ``app`` fixture which receives the previously defined
|
||||
|
||||
$ pytest -v test_appsetup.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 2 items
|
||||
@@ -638,7 +638,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
|
||||
|
||||
$ pytest -v -s test_module.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5
|
||||
cachedir: .cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 8 items
|
||||
|
||||
@@ -26,7 +26,7 @@ Installation::
|
||||
To check your installation has installed the correct version::
|
||||
|
||||
$ pytest --version
|
||||
This is pytest version 3.0.2, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py
|
||||
This is pytest version 3.0.3, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py
|
||||
|
||||
.. _`simpletest`:
|
||||
|
||||
@@ -46,7 +46,7 @@ That's it. You can execute the test function now::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ To execute it::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ Method reference of the monkeypatch fixture
|
||||
-------------------------------------------
|
||||
|
||||
.. autoclass:: MonkeyPatch
|
||||
:members:
|
||||
|
||||
``monkeypatch.setattr/delattr/delitem/delenv()`` all
|
||||
by default raise an Exception if the target does not exist.
|
||||
|
||||
@@ -55,7 +55,7 @@ them in turn::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 3 items
|
||||
|
||||
@@ -103,7 +103,7 @@ Let's run this::
|
||||
|
||||
$ pytest
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 3 items
|
||||
|
||||
@@ -216,6 +216,3 @@ The **metafunc** object
|
||||
.. currentmodule:: _pytest.python
|
||||
.. autoclass:: Metafunc
|
||||
:members:
|
||||
|
||||
.. automethod:: Metafunc.parametrize
|
||||
.. automethod:: Metafunc.addcall(funcargs=None,id=_notexists,param=_notexists)
|
||||
|
||||
@@ -224,7 +224,7 @@ Running it with the report-on-xfail option gives this output::
|
||||
|
||||
example $ pytest -rx xfail_demo.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR/example, inifile:
|
||||
collected 7 items
|
||||
|
||||
@@ -293,6 +293,20 @@ imperatively, in test or setup code::
|
||||
# or
|
||||
pytest.skip("unsupported configuration")
|
||||
|
||||
Note that calling ``pytest.skip`` at the module level
|
||||
is not allowed since pytest 3.0. If you are upgrading
|
||||
and ``pytest.skip`` was being used at the module level, you can set a
|
||||
``pytestmark`` variable:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# before pytest 3.0
|
||||
pytest.skip('skipping all tests because of reasons')
|
||||
# after pytest 3.0
|
||||
pytestmark = pytest.mark.skip('skipping all tests because of reasons')
|
||||
|
||||
``pytestmark`` applies a mark or list of marks to all tests in a module.
|
||||
|
||||
|
||||
Skipping on a missing import dependency
|
||||
--------------------------------------------------
|
||||
@@ -371,3 +385,27 @@ The equivalent with "boolean conditions" is::
|
||||
imported before pytest's argument parsing takes place. For example,
|
||||
``conftest.py`` files are imported before command line parsing and thus
|
||||
``config.getvalue()`` will not execute correctly.
|
||||
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
Here's a quick guide on how to skip tests in a module in different situations:
|
||||
|
||||
1. Skip all tests in a module unconditionally:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytestmark = pytest.mark.skip('all tests still WIP')
|
||||
|
||||
2. Skip all tests in a module based on some condition:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytestmark = pytest.mark.skipif(sys.platform == 'win32', 'tests for linux only')
|
||||
|
||||
3. Skip all tests in a module if some import is missing:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pexpect = pytest.importorskip('pexpect')
|
||||
|
||||
@@ -29,7 +29,7 @@ Running this would result in a passed test except for the last
|
||||
|
||||
$ pytest test_tmpdir.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 items
|
||||
|
||||
|
||||
@@ -38,7 +38,11 @@ the general ``pytest`` documentation for many more examples.
|
||||
Running tests from ``unittest.TestCase`` subclasses with ``--pdb`` will
|
||||
disable tearDown and cleanup methods for the case that an Exception
|
||||
occurs. This allows proper post mortem debugging for all applications
|
||||
which have significant logic in their tearDown machinery.
|
||||
which have significant logic in their tearDown machinery. However,
|
||||
supporting this feature has the following side effect: If people
|
||||
overwrite ``unittest.TestCase`` ``__call__`` or ``run``, they need to
|
||||
to overwrite ``debug`` in the same way (this is also true for standard
|
||||
unittest).
|
||||
|
||||
Mixing pytest fixtures into unittest.TestCase style tests
|
||||
-----------------------------------------------------------
|
||||
@@ -96,7 +100,7 @@ the ``self.db`` values in the traceback::
|
||||
|
||||
$ pytest test_unittest_db.py
|
||||
======= test session starts ========
|
||||
platform linux -- Python 3.5.2, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
|
||||
platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 2 items
|
||||
|
||||
|
||||
@@ -1063,6 +1063,22 @@ class TestFixtureUsages:
|
||||
"*1 error*"
|
||||
])
|
||||
|
||||
def test_invalid_scope(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
@pytest.fixture(scope="functions")
|
||||
def badscope():
|
||||
pass
|
||||
|
||||
def test_nothing(badscope):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest_inprocess()
|
||||
result.stdout.fnmatch_lines(
|
||||
("*ValueError: fixture badscope from test_invalid_scope.py has an unsupported"
|
||||
" scope value 'functions'")
|
||||
)
|
||||
|
||||
def test_funcarg_parametrized_and_used_twice(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
|
||||
@@ -96,6 +96,14 @@ class TestMetafunc:
|
||||
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
|
||||
pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6]))
|
||||
|
||||
def test_parametrize_bad_scope(self, testdir):
|
||||
def func(x): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
try:
|
||||
metafunc.parametrize("x", [1], scope='doggy')
|
||||
except ValueError as ve:
|
||||
assert "has an unsupported scope value 'doggy'" in str(ve)
|
||||
|
||||
def test_parametrize_and_id(self):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
@@ -105,6 +113,14 @@ class TestMetafunc:
|
||||
ids = [x.id for x in metafunc._calls]
|
||||
assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"]
|
||||
|
||||
def test_parametrize_and_id_unicode(self):
|
||||
"""Allow unicode strings for "ids" parameter in Python 2 (##1905)"""
|
||||
def func(x): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
metafunc.parametrize("x", [1, 2], ids=[u'basic', u'advanced'])
|
||||
ids = [x.id for x in metafunc._calls]
|
||||
assert ids == [u"basic", u"advanced"]
|
||||
|
||||
def test_parametrize_with_wrong_number_of_ids(self, testdir):
|
||||
def func(x, y): pass
|
||||
metafunc = self.Metafunc(func)
|
||||
|
||||
@@ -108,7 +108,8 @@ class TestImportHookInstallation:
|
||||
assert result.ret == 0
|
||||
|
||||
@pytest.mark.parametrize('mode', ['plain', 'rewrite'])
|
||||
def test_installed_plugin_rewrite(self, testdir, mode):
|
||||
@pytest.mark.parametrize('plugin_state', ['development', 'installed'])
|
||||
def test_installed_plugin_rewrite(self, testdir, mode, plugin_state):
|
||||
# Make sure the hook is installed early enough so that plugins
|
||||
# installed via setuptools are re-written.
|
||||
testdir.tmpdir.join('hampkg').ensure(dir=1)
|
||||
@@ -135,13 +136,22 @@ class TestImportHookInstallation:
|
||||
'mainwrapper.py': """
|
||||
import pytest, pkg_resources
|
||||
|
||||
plugin_state = "{plugin_state}"
|
||||
|
||||
class DummyDistInfo:
|
||||
project_name = 'spam'
|
||||
version = '1.0'
|
||||
|
||||
def _get_metadata(self, name):
|
||||
return ['spamplugin.py,sha256=abc,123',
|
||||
'hampkg/__init__.py,sha256=abc,123']
|
||||
# 'RECORD' meta-data only available in installed plugins
|
||||
if name == 'RECORD' and plugin_state == "installed":
|
||||
return ['spamplugin.py,sha256=abc,123',
|
||||
'hampkg/__init__.py,sha256=abc,123']
|
||||
# 'SOURCES.txt' meta-data only available for plugins in development mode
|
||||
elif name == 'SOURCES.txt' and plugin_state == "development":
|
||||
return ['spamplugin.py',
|
||||
'hampkg/__init__.py']
|
||||
return []
|
||||
|
||||
class DummyEntryPoint:
|
||||
name = 'spam'
|
||||
@@ -159,7 +169,7 @@ class TestImportHookInstallation:
|
||||
|
||||
pkg_resources.iter_entry_points = iter_entry_points
|
||||
pytest.main()
|
||||
""",
|
||||
""".format(plugin_state=plugin_state),
|
||||
'test_foo.py': """
|
||||
def test(check_first):
|
||||
check_first([10, 30], 30)
|
||||
@@ -854,3 +864,15 @@ def test_assert_with_unicode(monkeypatch, testdir):
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(['*AssertionError*'])
|
||||
|
||||
def test_issue_1944(testdir):
|
||||
testdir.makepyfile("""
|
||||
def f():
|
||||
return
|
||||
|
||||
assert f() == 10
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(["*1 error*"])
|
||||
assert "AttributeError: 'Module' object has no attribute '_obj'" not in result.stdout.str()
|
||||
|
||||
|
||||
11
tox.ini
11
tox.ini
@@ -10,8 +10,8 @@ envlist=
|
||||
[testenv]
|
||||
commands= pytest --lsof -rfsxX {posargs:testing}
|
||||
passenv = USER USERNAME
|
||||
deps=
|
||||
hypothesis
|
||||
deps=
|
||||
hypothesis>=3.5.2
|
||||
nose
|
||||
mock
|
||||
requests
|
||||
@@ -47,7 +47,7 @@ commands = flake8 pytest.py _pytest testing
|
||||
deps=pytest-xdist>=1.13
|
||||
mock
|
||||
nose
|
||||
hypothesis
|
||||
hypothesis>=3.5.2
|
||||
commands=
|
||||
pytest -n1 -rfsxX {posargs:testing}
|
||||
|
||||
@@ -71,8 +71,9 @@ commands=
|
||||
pytest -rfsxX test_pdb.py test_terminal.py test_unittest.py
|
||||
|
||||
[testenv:py27-nobyte]
|
||||
deps=pytest-xdist>=1.13
|
||||
hypothesis
|
||||
deps=
|
||||
pytest-xdist>=1.13
|
||||
hypothesis>=3.5.2
|
||||
distribute=true
|
||||
setenv=
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
Reference in New Issue
Block a user