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
|
||||
skip_if = _skip.skip_if
|
||||
skip_on_error = _skip.skip_on_error
|
||||
skip_test = _skip.skip_test
|
||||
skip_unless = _skip.skip_unless
|
||||
skip = _skip.skip
|
||||
|
|
|
@ -30,6 +30,10 @@ SkipTarget = typing.Union[typing.Callable,
|
|||
SkipDecorator = typing.Callable[[SkipTarget], SkipTarget]
|
||||
|
||||
|
||||
SkipOnErrorType = typing.Union[typing.Type[Exception],
|
||||
typing.Tuple[typing.Type[Exception], ...]]
|
||||
|
||||
|
||||
def skip_test(reason: str,
|
||||
cause: Exception = None,
|
||||
bugzilla: int = None) -> typing.NoReturn:
|
||||
|
@ -37,7 +41,7 @@ def skip_test(reason: str,
|
|||
if bugzilla is not None:
|
||||
reason += f'\nhttps://bugzilla.redhat.com/show_bug.cgi?id={bugzilla}\n'
|
||||
if cause is not None:
|
||||
reason += f"\n\n{cause}\n"
|
||||
reason += f"\n{cause}\n"
|
||||
raise SkipException(reason) from cause
|
||||
|
||||
|
||||
|
@ -75,12 +79,31 @@ def skip_unless(reason: str,
|
|||
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,
|
||||
unless: bool = True,
|
||||
unless: bool = None,
|
||||
error_type: SkipOnErrorType = None,
|
||||
bugzilla: int = None,
|
||||
predicate: typing.Callable = None) \
|
||||
-> SkipDecorator:
|
||||
"""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:
|
||||
method = _get_skip_method(obj)
|
||||
|
||||
|
@ -89,11 +112,18 @@ def _skip_decorator(reason: str,
|
|||
_reason = reason
|
||||
cause: typing.Optional[Exception] = None
|
||||
if predicate is not None:
|
||||
return_value = predicate()
|
||||
if unless is bool(return_value):
|
||||
return method(*args, **kwargs)
|
||||
return_value: typing.Any = None
|
||||
try:
|
||||
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:
|
||||
_reason = reason.format(return_value=return_value)
|
||||
if '{cause' in reason:
|
||||
_reason = reason.format(cause=cause)
|
||||
skip_test(reason=_reason, cause=cause, bugzilla=bugzilla)
|
||||
|
||||
if obj is method:
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import typing
|
||||
|
||||
import tobiko
|
||||
from tobiko.tests import unit
|
||||
|
||||
|
||||
def condition(value):
|
||||
def condition(value: typing.Any):
|
||||
return value
|
||||
|
||||
|
||||
|
@ -224,3 +226,45 @@ class NegativeSkipUnlessConditionCalledWithKwargsTest(NegativeSkipBase):
|
|||
|
||||
def test_fail(self):
|
||||
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