-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathcase.py
More file actions
164 lines (142 loc) · 5.64 KB
/
case.py
File metadata and controls
164 lines (142 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import sys
import warnings
from collections.abc import Iterable as DeferrableMethod
from functools import wraps
from unittest import TestCase
from unittest.case import _ExpectedFailure
from unittest.case import _Outcome
from unittest.case import _UnexpectedSuccess
from unittest.case import SkipTest
from .runner import defer
__all__ = [
"DeferrableMethod",
"DeferrableTestCase",
"IsolatedAsyncioTestCase",
"TestCase",
"expectedFailure",
]
def expectedFailure(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
deferred = func(*args, **kwargs)
if isinstance(deferred, DeferrableMethod):
yield from deferred
except Exception:
raise _ExpectedFailure(sys.exc_info())
raise _UnexpectedSuccess
return wrapper
class IsolatedAsyncioTestCase:
def __init__(self, *args, **kwargs):
raise RuntimeError("Asyncio not supported by python 3.3!")
class DeferrableTestCase(TestCase):
def _executeTestPart(self, function, outcome, isTest=False):
try:
deferred = function()
if isinstance(deferred, DeferrableMethod):
yield from deferred
except KeyboardInterrupt:
raise
except SkipTest as e:
outcome.success = False
outcome.skipped = str(e)
except _UnexpectedSuccess:
exc_info = sys.exc_info()
outcome.success = False
if isTest:
outcome.unexpectedSuccess = exc_info
else:
outcome.errors.append(exc_info)
except _ExpectedFailure:
outcome.success = False
exc_info = sys.exc_info()
if isTest:
outcome.expectedFailure = exc_info
else:
outcome.errors.append(exc_info)
except self.failureException:
outcome.success = False
outcome.failures.append(sys.exc_info())
except Exception:
outcome.success = False
outcome.errors.append(sys.exc_info())
@staticmethod
def defer(delay, callback, *args, **kwargs):
defer(delay, callback, *args, **kwargs)
def run(self, result=None):
orig_result = result
if result is None:
result = self.defaultTestResult()
startTestRun = getattr(result, "startTestRun", None)
if startTestRun is not None:
startTestRun()
result.startTest(self)
testMethod = getattr(self, self._testMethodName)
if getattr(self.__class__, "__unittest_skip__", False) or getattr(
testMethod, "__unittest_skip__", False
):
# If the class or method was skipped.
try:
skip_why = getattr(
self.__class__, "__unittest_skip_why__", ""
) or getattr(testMethod, "__unittest_skip_why__", "")
self._addSkip(result, skip_why)
finally:
result.stopTest(self)
return
try:
outcome = _Outcome()
self._outcomeForDoCleanups = outcome
yield from self._executeTestPart(self.setUp, outcome)
if outcome.success:
yield from self._executeTestPart(testMethod, outcome, isTest=True)
yield from self._executeTestPart(self.tearDown, outcome)
yield from self.doCleanups()
if outcome.success:
result.addSuccess(self)
else:
if outcome.skipped is not None:
self._addSkip(result, outcome.skipped)
for exc_info in outcome.errors:
result.addError(self, exc_info)
for exc_info in outcome.failures:
result.addFailure(self, exc_info)
if outcome.unexpectedSuccess is not None:
addUnexpectedSuccess = getattr(result, "addUnexpectedSuccess", None)
if addUnexpectedSuccess is not None:
addUnexpectedSuccess(self)
else:
warnings.warn(
"TestResult has no addUnexpectedSuccess method, reporting as failures",
RuntimeWarning,
)
result.addFailure(self, outcome.unexpectedSuccess)
if outcome.expectedFailure is not None:
addExpectedFailure = getattr(result, "addExpectedFailure", None)
if addExpectedFailure is not None:
addExpectedFailure(self, outcome.expectedFailure)
else:
warnings.warn(
"TestResult has no addExpectedFailure method, reporting as passes",
RuntimeWarning,
)
result.addSuccess(self)
return result
finally:
result.stopTest(self)
if orig_result is None:
stopTestRun = getattr(result, "stopTestRun", None)
if stopTestRun is not None:
stopTestRun()
def doCleanups(self):
"""Execute all cleanup functions.
Normally called for you after tearDown.
"""
outcome = self._outcomeForDoCleanups or _Outcome()
while self._cleanups:
function, args, kwargs = self._cleanups.pop()
part = lambda: function(*args, **kwargs) # noqa: E731
yield from self._executeTestPart(part, outcome)
# return this for backwards compatibility
# even though we no longer us it internally
return outcome.success