Add skip_on_error decorator
Change-Id: I1e3b7614313ae24d4c399f71a66098e0a363a29d
This commit is contained in:
parent
534329600d
commit
f14ad2a1b7
|
@ -124,6 +124,7 @@ MultipleObjectsFound = _select.MultipleObjectsFound
|
||||||
|
|
||||||
SkipException = _skip.SkipException
|
SkipException = _skip.SkipException
|
||||||
skip_if = _skip.skip_if
|
skip_if = _skip.skip_if
|
||||||
|
skip_on_error = _skip.skip_on_error
|
||||||
skip_test = _skip.skip_test
|
skip_test = _skip.skip_test
|
||||||
skip_unless = _skip.skip_unless
|
skip_unless = _skip.skip_unless
|
||||||
skip = _skip.skip
|
skip = _skip.skip
|
||||||
|
|
|
@ -30,6 +30,10 @@ SkipTarget = typing.Union[typing.Callable,
|
||||||
SkipDecorator = typing.Callable[[SkipTarget], SkipTarget]
|
SkipDecorator = typing.Callable[[SkipTarget], SkipTarget]
|
||||||
|
|
||||||
|
|
||||||
|
SkipOnErrorType = typing.Union[typing.Type[Exception],
|
||||||
|
typing.Tuple[typing.Type[Exception], ...]]
|
||||||
|
|
||||||
|
|
||||||
def skip_test(reason: str,
|
def skip_test(reason: str,
|
||||||
cause: Exception = None,
|
cause: Exception = None,
|
||||||
bugzilla: int = None) -> typing.NoReturn:
|
bugzilla: int = None) -> typing.NoReturn:
|
||||||
|
@ -37,7 +41,7 @@ def skip_test(reason: str,
|
||||||
if bugzilla is not None:
|
if bugzilla is not None:
|
||||||
reason += f'\nhttps://bugzilla.redhat.com/show_bug.cgi?id={bugzilla}\n'
|
reason += f'\nhttps://bugzilla.redhat.com/show_bug.cgi?id={bugzilla}\n'
|
||||||
if cause is not None:
|
if cause is not None:
|
||||||
reason += f"\n\n{cause}\n"
|
reason += f"\n{cause}\n"
|
||||||
raise SkipException(reason) from cause
|
raise SkipException(reason) from cause
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,12 +79,31 @@ def skip_unless(reason: str,
|
||||||
predicate=predicate)
|
predicate=predicate)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_on_error(reason: str,
|
||||||
|
predicate: typing.Callable,
|
||||||
|
*args,
|
||||||
|
error_type: SkipOnErrorType = None,
|
||||||
|
bugzilla: int = None,
|
||||||
|
**kwargs) -> \
|
||||||
|
SkipDecorator:
|
||||||
|
predicate = _get_skip_predicate(predicate, *args, **kwargs)
|
||||||
|
return _skip_decorator(reason=reason,
|
||||||
|
error_type=error_type,
|
||||||
|
bugzilla=bugzilla,
|
||||||
|
predicate=predicate)
|
||||||
|
|
||||||
|
|
||||||
def _skip_decorator(reason: str,
|
def _skip_decorator(reason: str,
|
||||||
unless: bool = True,
|
unless: bool = None,
|
||||||
|
error_type: SkipOnErrorType = None,
|
||||||
bugzilla: int = None,
|
bugzilla: int = None,
|
||||||
predicate: typing.Callable = None) \
|
predicate: typing.Callable = None) \
|
||||||
-> SkipDecorator:
|
-> SkipDecorator:
|
||||||
"""Mark test case for being skipped for a given reason unless it matches"""
|
"""Mark test case for being skipped for a given reason unless it matches"""
|
||||||
|
|
||||||
|
if error_type is None:
|
||||||
|
error_type = tuple()
|
||||||
|
|
||||||
def decorator(obj: SkipTarget) -> SkipTarget:
|
def decorator(obj: SkipTarget) -> SkipTarget:
|
||||||
method = _get_skip_method(obj)
|
method = _get_skip_method(obj)
|
||||||
|
|
||||||
|
@ -89,11 +112,18 @@ def _skip_decorator(reason: str,
|
||||||
_reason = reason
|
_reason = reason
|
||||||
cause: typing.Optional[Exception] = None
|
cause: typing.Optional[Exception] = None
|
||||||
if predicate is not None:
|
if predicate is not None:
|
||||||
return_value = predicate()
|
return_value: typing.Any = None
|
||||||
if unless is bool(return_value):
|
try:
|
||||||
return method(*args, **kwargs)
|
return_value = predicate()
|
||||||
|
except error_type as ex:
|
||||||
|
cause = ex
|
||||||
|
else:
|
||||||
|
if unless in [None, bool(return_value)]:
|
||||||
|
return method(*args, **kwargs)
|
||||||
if '{return_value' in reason:
|
if '{return_value' in reason:
|
||||||
_reason = reason.format(return_value=return_value)
|
_reason = reason.format(return_value=return_value)
|
||||||
|
if '{cause' in reason:
|
||||||
|
_reason = reason.format(cause=cause)
|
||||||
skip_test(reason=_reason, cause=cause, bugzilla=bugzilla)
|
skip_test(reason=_reason, cause=cause, bugzilla=bugzilla)
|
||||||
|
|
||||||
if obj is method:
|
if obj is method:
|
||||||
|
|
|
@ -14,11 +14,13 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import typing
|
||||||
|
|
||||||
import tobiko
|
import tobiko
|
||||||
from tobiko.tests import unit
|
from tobiko.tests import unit
|
||||||
|
|
||||||
|
|
||||||
def condition(value):
|
def condition(value: typing.Any):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,3 +226,45 @@ class NegativeSkipUnlessConditionCalledWithKwargsTest(NegativeSkipBase):
|
||||||
|
|
||||||
def test_fail(self):
|
def test_fail(self):
|
||||||
self.test_method_called = True
|
self.test_method_called = True
|
||||||
|
|
||||||
|
|
||||||
|
def raise_an_error(error: Exception):
|
||||||
|
raise error
|
||||||
|
|
||||||
|
|
||||||
|
def raise_any_error():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@tobiko.skip_on_error('error raised: {cause}',
|
||||||
|
raise_an_error,
|
||||||
|
error_type=ValueError,
|
||||||
|
error=ValueError("It is all right"))
|
||||||
|
class PositiveSkipOnErrorTest(unit.TobikoUnitTest):
|
||||||
|
|
||||||
|
def test_skip_on_error(self):
|
||||||
|
self.fail('Not skipped')
|
||||||
|
|
||||||
|
|
||||||
|
class PositiveSkipOnErrorMethodTest(unit.TobikoUnitTest):
|
||||||
|
|
||||||
|
@tobiko.skip_on_error('error raised: {cause}',
|
||||||
|
raise_an_error,
|
||||||
|
error_type=RuntimeError,
|
||||||
|
error=RuntimeError("It is all right"))
|
||||||
|
def test_skip_on_error(self):
|
||||||
|
self.fail('Not skipped')
|
||||||
|
|
||||||
|
|
||||||
|
@tobiko.skip_on_error('error not raised', raise_any_error,
|
||||||
|
error_type=ValueError)
|
||||||
|
class NegativeSkipOnErrorTest(NegativeSkipBase):
|
||||||
|
def test_skip_on_error(self):
|
||||||
|
self.test_method_called = True
|
||||||
|
|
||||||
|
|
||||||
|
class NegativeSkipOnErrorMethodTest(NegativeSkipBase):
|
||||||
|
@tobiko.skip_on_error('error not raised', raise_any_error,
|
||||||
|
error_type=ValueError)
|
||||||
|
def test_skip_on_error(self):
|
||||||
|
self.test_method_called = True
|
||||||
|
|
Loading…
Reference in New Issue