##// END OF EJS Templates
don't unconditionally import nose...
MinRK -
Show More
@@ -1,6 +1,9 b''
1 1 try:
2 2 from numpy.testing.decorators import *
3 3 from numpy.testing.noseclasses import KnownFailure
4 4 except ImportError:
5 5 from _decorators import *
6 from _numpy_testing_noseclasses import KnownFailure
6 try:
7 from _numpy_testing_noseclasses import KnownFailure
8 except ImportError:
9 pass
@@ -1,278 +1,281 b''
1 1 """
2 2 Decorators for labeling and modifying behavior of test objects.
3 3
4 4 Decorators that merely return a modified version of the original
5 5 function object are straightforward. Decorators that return a new
6 6 function object need to use
7 7 ::
8 8
9 9 nose.tools.make_decorator(original_function)(decorator)
10 10
11 11 in returning the decorator, in order to preserve meta-data such as
12 12 function name, setup and teardown functions and so on - see
13 13 ``nose.tools`` for more information.
14 14
15 15 """
16 16 import warnings
17 17
18 18 # IPython changes: make this work if numpy not available
19 19 # Original code:
20 20 #from numpy.testing.utils import \
21 21 # WarningManager, WarningMessage
22 22 # Our version:
23 23 from _numpy_testing_utils import WarningManager
24 from _numpy_testing_noseclasses import KnownFailureTest
24 try:
25 from _numpy_testing_noseclasses import KnownFailureTest
26 except:
27 pass
25 28
26 29 # End IPython changes
27 30
28 31 def slow(t):
29 32 """
30 33 Label a test as 'slow'.
31 34
32 35 The exact definition of a slow test is obviously both subjective and
33 36 hardware-dependent, but in general any individual test that requires more
34 37 than a second or two should be labeled as slow (the whole suite consists of
35 38 thousands of tests, so even a second is significant).
36 39
37 40 Parameters
38 41 ----------
39 42 t : callable
40 43 The test to label as slow.
41 44
42 45 Returns
43 46 -------
44 47 t : callable
45 48 The decorated test `t`.
46 49
47 50 Examples
48 51 --------
49 52 The `numpy.testing` module includes ``import decorators as dec``.
50 53 A test can be decorated as slow like this::
51 54
52 55 from numpy.testing import *
53 56
54 57 @dec.slow
55 58 def test_big(self):
56 59 print 'Big, slow test'
57 60
58 61 """
59 62
60 63 t.slow = True
61 64 return t
62 65
63 66 def setastest(tf=True):
64 67 """
65 68 Signals to nose that this function is or is not a test.
66 69
67 70 Parameters
68 71 ----------
69 72 tf : bool
70 73 If True, specifies that the decorated callable is a test.
71 74 If False, specifies that the decorated callable is not a test.
72 75 Default is True.
73 76
74 77 Notes
75 78 -----
76 79 This decorator can't use the nose namespace, because it can be
77 80 called from a non-test module. See also ``istest`` and ``nottest`` in
78 81 ``nose.tools``.
79 82
80 83 Examples
81 84 --------
82 85 `setastest` can be used in the following way::
83 86
84 87 from numpy.testing.decorators import setastest
85 88
86 89 @setastest(False)
87 90 def func_with_test_in_name(arg1, arg2):
88 91 pass
89 92
90 93 """
91 94 def set_test(t):
92 95 t.__test__ = tf
93 96 return t
94 97 return set_test
95 98
96 99 def skipif(skip_condition, msg=None):
97 100 """
98 101 Make function raise SkipTest exception if a given condition is true.
99 102
100 103 If the condition is a callable, it is used at runtime to dynamically
101 104 make the decision. This is useful for tests that may require costly
102 105 imports, to delay the cost until the test suite is actually executed.
103 106
104 107 Parameters
105 108 ----------
106 109 skip_condition : bool or callable
107 110 Flag to determine whether to skip the decorated test.
108 111 msg : str, optional
109 112 Message to give on raising a SkipTest exception. Default is None.
110 113
111 114 Returns
112 115 -------
113 116 decorator : function
114 117 Decorator which, when applied to a function, causes SkipTest
115 118 to be raised when `skip_condition` is True, and the function
116 119 to be called normally otherwise.
117 120
118 121 Notes
119 122 -----
120 123 The decorator itself is decorated with the ``nose.tools.make_decorator``
121 124 function in order to transmit function name, and various other metadata.
122 125
123 126 """
124 127
125 128 def skip_decorator(f):
126 129 # Local import to avoid a hard nose dependency and only incur the
127 130 # import time overhead at actual test-time.
128 131 import nose
129 132
130 133 # Allow for both boolean or callable skip conditions.
131 134 if callable(skip_condition):
132 135 skip_val = lambda : skip_condition()
133 136 else:
134 137 skip_val = lambda : skip_condition
135 138
136 139 def get_msg(func,msg=None):
137 140 """Skip message with information about function being skipped."""
138 141 if msg is None:
139 142 out = 'Test skipped due to test condition'
140 143 else:
141 144 out = '\n'+msg
142 145
143 146 return "Skipping test: %s%s" % (func.__name__,out)
144 147
145 148 # We need to define *two* skippers because Python doesn't allow both
146 149 # return with value and yield inside the same function.
147 150 def skipper_func(*args, **kwargs):
148 151 """Skipper for normal test functions."""
149 152 if skip_val():
150 153 raise nose.SkipTest(get_msg(f,msg))
151 154 else:
152 155 return f(*args, **kwargs)
153 156
154 157 def skipper_gen(*args, **kwargs):
155 158 """Skipper for test generators."""
156 159 if skip_val():
157 160 raise nose.SkipTest(get_msg(f,msg))
158 161 else:
159 162 for x in f(*args, **kwargs):
160 163 yield x
161 164
162 165 # Choose the right skipper to use when building the actual decorator.
163 166 if nose.util.isgenerator(f):
164 167 skipper = skipper_gen
165 168 else:
166 169 skipper = skipper_func
167 170
168 171 return nose.tools.make_decorator(f)(skipper)
169 172
170 173 return skip_decorator
171 174
172 175 def knownfailureif(fail_condition, msg=None):
173 176 """
174 177 Make function raise KnownFailureTest exception if given condition is true.
175 178
176 179 If the condition is a callable, it is used at runtime to dynamically
177 180 make the decision. This is useful for tests that may require costly
178 181 imports, to delay the cost until the test suite is actually executed.
179 182
180 183 Parameters
181 184 ----------
182 185 fail_condition : bool or callable
183 186 Flag to determine whether to mark the decorated test as a known
184 187 failure (if True) or not (if False).
185 188 msg : str, optional
186 189 Message to give on raising a KnownFailureTest exception.
187 190 Default is None.
188 191
189 192 Returns
190 193 -------
191 194 decorator : function
192 195 Decorator, which, when applied to a function, causes SkipTest
193 196 to be raised when `skip_condition` is True, and the function
194 197 to be called normally otherwise.
195 198
196 199 Notes
197 200 -----
198 201 The decorator itself is decorated with the ``nose.tools.make_decorator``
199 202 function in order to transmit function name, and various other metadata.
200 203
201 204 """
202 205 if msg is None:
203 206 msg = 'Test skipped due to known failure'
204 207
205 208 # Allow for both boolean or callable known failure conditions.
206 209 if callable(fail_condition):
207 210 fail_val = lambda : fail_condition()
208 211 else:
209 212 fail_val = lambda : fail_condition
210 213
211 214 def knownfail_decorator(f):
212 215 # Local import to avoid a hard nose dependency and only incur the
213 216 # import time overhead at actual test-time.
214 217 import nose
215 218 def knownfailer(*args, **kwargs):
216 219 if fail_val():
217 220 raise KnownFailureTest, msg
218 221 else:
219 222 return f(*args, **kwargs)
220 223 return nose.tools.make_decorator(f)(knownfailer)
221 224
222 225 return knownfail_decorator
223 226
224 227 def deprecated(conditional=True):
225 228 """
226 229 Filter deprecation warnings while running the test suite.
227 230
228 231 This decorator can be used to filter DeprecationWarning's, to avoid
229 232 printing them during the test suite run, while checking that the test
230 233 actually raises a DeprecationWarning.
231 234
232 235 Parameters
233 236 ----------
234 237 conditional : bool or callable, optional
235 238 Flag to determine whether to mark test as deprecated or not. If the
236 239 condition is a callable, it is used at runtime to dynamically make the
237 240 decision. Default is True.
238 241
239 242 Returns
240 243 -------
241 244 decorator : function
242 245 The `deprecated` decorator itself.
243 246
244 247 Notes
245 248 -----
246 249 .. versionadded:: 1.4.0
247 250
248 251 """
249 252 def deprecate_decorator(f):
250 253 # Local import to avoid a hard nose dependency and only incur the
251 254 # import time overhead at actual test-time.
252 255 import nose
253 256
254 257 def _deprecated_imp(*args, **kwargs):
255 258 # Poor man's replacement for the with statement
256 259 ctx = WarningManager(record=True)
257 260 l = ctx.__enter__()
258 261 warnings.simplefilter('always')
259 262 try:
260 263 f(*args, **kwargs)
261 264 if not len(l) > 0:
262 265 raise AssertionError("No warning raised when calling %s"
263 266 % f.__name__)
264 267 if not l[0].category is DeprecationWarning:
265 268 raise AssertionError("First warning for %s is not a " \
266 269 "DeprecationWarning( is %s)" % (f.__name__, l[0]))
267 270 finally:
268 271 ctx.__exit__()
269 272
270 273 if callable(conditional):
271 274 cond = conditional()
272 275 else:
273 276 cond = conditional
274 277 if cond:
275 278 return nose.tools.make_decorator(f)(_deprecated_imp)
276 279 else:
277 280 return f
278 281 return deprecate_decorator
General Comments 0
You need to be logged in to leave comments. Login now