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