Merge branch 'master' into allow_skipping_unittests_with_pdb_active
This commit is contained in:
commit
6a097aa0f1
3
AUTHORS
3
AUTHORS
|
@ -16,6 +16,7 @@ Antony Lee
|
||||||
Armin Rigo
|
Armin Rigo
|
||||||
Aron Curzon
|
Aron Curzon
|
||||||
Aviv Palivoda
|
Aviv Palivoda
|
||||||
|
Barney Gale
|
||||||
Ben Webb
|
Ben Webb
|
||||||
Benjamin Peterson
|
Benjamin Peterson
|
||||||
Bernard Pratz
|
Bernard Pratz
|
||||||
|
@ -117,6 +118,7 @@ Piotr Banaszkiewicz
|
||||||
Punyashloka Biswal
|
Punyashloka Biswal
|
||||||
Quentin Pradet
|
Quentin Pradet
|
||||||
Ralf Schmitt
|
Ralf Schmitt
|
||||||
|
Ran Benita
|
||||||
Raphael Pierzina
|
Raphael Pierzina
|
||||||
Raquel Alegre
|
Raquel Alegre
|
||||||
Roberto Polli
|
Roberto Polli
|
||||||
|
@ -141,5 +143,6 @@ Trevor Bekolay
|
||||||
Tyler Goodlet
|
Tyler Goodlet
|
||||||
Vasily Kuznetsov
|
Vasily Kuznetsov
|
||||||
Victor Uriarte
|
Victor Uriarte
|
||||||
|
Vidar T. Fauske
|
||||||
Wouter van Ackooy
|
Wouter van Ackooy
|
||||||
Xuecong Liao
|
Xuecong Liao
|
||||||
|
|
|
@ -4,19 +4,36 @@
|
||||||
* Fix regression, pytest now skips unittest correctly if run with ``--pdb``
|
* Fix regression, pytest now skips unittest correctly if run with ``--pdb``
|
||||||
(`#2137`_). Thanks to `@gst`_ for the report and `@mbyt`_ for the PR.
|
(`#2137`_). Thanks to `@gst`_ for the report and `@mbyt`_ for the PR.
|
||||||
|
|
||||||
|
* Ignore exceptions raised from descriptors (e.g. properties) during Python test collection (`#2234`_).
|
||||||
|
Thanks to `@bluetech`_.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
* Replace ``raise StopIteration`` usages in the code by simple ``returns`` to finish generators, in accordance to `PEP-479`_ (`#2160`_).
|
* Replace ``raise StopIteration`` usages in the code by simple ``returns`` to finish generators, in accordance to `PEP-479`_ (`#2160`_).
|
||||||
Thanks `@tgoodlet`_ for the report and `@nicoddemus`_ for the PR.
|
Thanks `@tgoodlet`_ for the report and `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
*
|
* Skipping plugin now also works with test items generated by custom collectors (`#2231`_).
|
||||||
|
Thanks to `@vidartf`_.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
* Conditionless ``xfail`` markers no longer rely on the underlying test item
|
||||||
|
being an instance of ``PyobjMixin``, and can therefore apply to tests not
|
||||||
|
collected by the built-in python test collector. Thanks `@barneygale`_ for the
|
||||||
|
PR.
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
.. _@bluetech: https://github.com/bluetech
|
||||||
.. _@gst: https://github.com/gst
|
.. _@gst: https://github.com/gst
|
||||||
|
.. _@vidartf: https://github.com/vidartf
|
||||||
|
|
||||||
.. _#2137: https://github.com/pytest-dev/pytest/issues/2137
|
.. _#2137: https://github.com/pytest-dev/pytest/issues/2137
|
||||||
.. _#2160: https://github.com/pytest-dev/pytest/issues/2160
|
.. _#2160: https://github.com/pytest-dev/pytest/issues/2160
|
||||||
|
.. _#2231: https://github.com/pytest-dev/pytest/issues/2231
|
||||||
|
.. _#2234: https://github.com/pytest-dev/pytest/issues/2234
|
||||||
|
|
||||||
.. _PEP-479: https://www.python.org/dev/peps/pep-0479/
|
.. _PEP-479: https://www.python.org/dev/peps/pep-0479/
|
||||||
|
|
||||||
|
@ -53,6 +70,7 @@
|
||||||
terminal output it relies on is missing. Thanks to `@eli-b`_ for the PR.
|
terminal output it relies on is missing. Thanks to `@eli-b`_ for the PR.
|
||||||
|
|
||||||
|
|
||||||
|
.. _@barneygale: https://github.com/barneygale
|
||||||
.. _@lesteve: https://github.com/lesteve
|
.. _@lesteve: https://github.com/lesteve
|
||||||
.. _@malinoff: https://github.com/malinoff
|
.. _@malinoff: https://github.com/malinoff
|
||||||
.. _@pelme: https://github.com/pelme
|
.. _@pelme: https://github.com/pelme
|
||||||
|
|
|
@ -14,6 +14,7 @@ from _pytest.compat import (
|
||||||
getfslineno, get_real_func,
|
getfslineno, get_real_func,
|
||||||
is_generator, isclass, getimfunc,
|
is_generator, isclass, getimfunc,
|
||||||
getlocation, getfuncargnames,
|
getlocation, getfuncargnames,
|
||||||
|
safe_getattr,
|
||||||
)
|
)
|
||||||
|
|
||||||
def pytest_sessionstart(session):
|
def pytest_sessionstart(session):
|
||||||
|
@ -124,8 +125,6 @@ def getfixturemarker(obj):
|
||||||
exceptions."""
|
exceptions."""
|
||||||
try:
|
try:
|
||||||
return getattr(obj, "_pytestfixturefunction", None)
|
return getattr(obj, "_pytestfixturefunction", None)
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# some objects raise errors like request (from flask import request)
|
# some objects raise errors like request (from flask import request)
|
||||||
# we don't expect them to be fixture functions
|
# we don't expect them to be fixture functions
|
||||||
|
@ -1068,7 +1067,9 @@ class FixtureManager:
|
||||||
self._holderobjseen.add(holderobj)
|
self._holderobjseen.add(holderobj)
|
||||||
autousenames = []
|
autousenames = []
|
||||||
for name in dir(holderobj):
|
for name in dir(holderobj):
|
||||||
obj = getattr(holderobj, name, None)
|
# The attribute can be an arbitrary descriptor, so the attribute
|
||||||
|
# access below can raise. safe_getatt() ignores such exceptions.
|
||||||
|
obj = safe_getattr(holderobj, name, None)
|
||||||
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
|
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)
|
||||||
# or are "@pytest.fixture" marked
|
# or are "@pytest.fixture" marked
|
||||||
marker = getfixturemarker(obj)
|
marker = getfixturemarker(obj)
|
||||||
|
|
|
@ -112,6 +112,7 @@ class MarkEvaluator:
|
||||||
|
|
||||||
def _getglobals(self):
|
def _getglobals(self):
|
||||||
d = {'os': os, 'sys': sys, 'config': self.item.config}
|
d = {'os': os, 'sys': sys, 'config': self.item.config}
|
||||||
|
if hasattr(self.item, 'obj'):
|
||||||
d.update(self.item.obj.__globals__)
|
d.update(self.item.obj.__globals__)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@ -119,7 +120,6 @@ class MarkEvaluator:
|
||||||
if hasattr(self, 'result'):
|
if hasattr(self, 'result'):
|
||||||
return self.result
|
return self.result
|
||||||
if self.holder:
|
if self.holder:
|
||||||
d = self._getglobals()
|
|
||||||
if self.holder.args or 'condition' in self.holder.kwargs:
|
if self.holder.args or 'condition' in self.holder.kwargs:
|
||||||
self.result = False
|
self.result = False
|
||||||
# "holder" might be a MarkInfo or a MarkDecorator; only
|
# "holder" might be a MarkInfo or a MarkDecorator; only
|
||||||
|
@ -135,6 +135,7 @@ class MarkEvaluator:
|
||||||
for expr in args:
|
for expr in args:
|
||||||
self.expr = expr
|
self.expr = expr
|
||||||
if isinstance(expr, py.builtin._basestring):
|
if isinstance(expr, py.builtin._basestring):
|
||||||
|
d = self._getglobals()
|
||||||
result = cached_eval(self.item.config, expr, d)
|
result = cached_eval(self.item.config, expr, d)
|
||||||
else:
|
else:
|
||||||
if "reason" not in kwargs:
|
if "reason" not in kwargs:
|
||||||
|
|
|
@ -166,6 +166,16 @@ class TestClass:
|
||||||
"because it has a __new__ constructor*"
|
"because it has a __new__ constructor*"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_issue2234_property(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
class TestCase(object):
|
||||||
|
@property
|
||||||
|
def prop(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
assert result.ret == EXIT_NOTESTSCOLLECTED
|
||||||
|
|
||||||
|
|
||||||
class TestGenerator:
|
class TestGenerator:
|
||||||
def test_generative_functions(self, testdir):
|
def test_generative_functions(self, testdir):
|
||||||
|
|
|
@ -969,3 +969,26 @@ def test_module_level_skip_error(testdir):
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
"*Using pytest.skip outside of a test is not allowed*"
|
"*Using pytest.skip outside of a test is not allowed*"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mark_xfail_item(testdir):
|
||||||
|
# Ensure pytest.mark.xfail works with non-Python Item
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
class MyItem(pytest.Item):
|
||||||
|
nodeid = 'foo'
|
||||||
|
def setup(self):
|
||||||
|
marker = pytest.mark.xfail(True, reason="Expected failure")
|
||||||
|
self.add_marker(marker)
|
||||||
|
def runtest(self):
|
||||||
|
assert False
|
||||||
|
|
||||||
|
def pytest_collect_file(path, parent):
|
||||||
|
return MyItem("foo", parent)
|
||||||
|
""")
|
||||||
|
result = testdir.inline_run()
|
||||||
|
passed, skipped, failed = result.listoutcomes()
|
||||||
|
assert not failed
|
||||||
|
xfailed = [r for r in skipped if hasattr(r, 'wasxfail')]
|
||||||
|
assert xfailed
|
||||||
|
|
Loading…
Reference in New Issue