Show More
@@ -1,150 +1,150 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 |
|
16 | |||
17 | # IPython changes: make this work if numpy not available |
|
17 | # IPython changes: make this work if numpy not available | |
18 | # Original code: |
|
18 | # Original code: | |
19 | try: |
|
19 | try: | |
20 | from ._numpy_testing_noseclasses import KnownFailureTest |
|
20 | from ._numpy_testing_noseclasses import KnownFailureTest | |
21 | except: |
|
21 | except: | |
22 | pass |
|
22 | pass | |
23 |
|
23 | |||
24 | # End IPython changes |
|
24 | # End IPython changes | |
25 |
|
25 | |||
26 |
|
26 | |||
27 | def skipif(skip_condition, msg=None): |
|
27 | def skipif(skip_condition, msg=None): | |
28 | """ |
|
28 | """ | |
29 | Make function raise SkipTest exception if a given condition is true. |
|
29 | Make function raise SkipTest exception if a given condition is true. | |
30 |
|
30 | |||
31 | If the condition is a callable, it is used at runtime to dynamically |
|
31 | If the condition is a callable, it is used at runtime to dynamically | |
32 | make the decision. This is useful for tests that may require costly |
|
32 | make the decision. This is useful for tests that may require costly | |
33 | imports, to delay the cost until the test suite is actually executed. |
|
33 | imports, to delay the cost until the test suite is actually executed. | |
34 |
|
34 | |||
35 | Parameters |
|
35 | Parameters | |
36 | ---------- |
|
36 | ---------- | |
37 | skip_condition : bool or callable |
|
37 | skip_condition : bool or callable | |
38 | Flag to determine whether to skip the decorated test. |
|
38 | Flag to determine whether to skip the decorated test. | |
39 | msg : str, optional |
|
39 | msg : str, optional | |
40 | Message to give on raising a SkipTest exception. Default is None. |
|
40 | Message to give on raising a SkipTest exception. Default is None. | |
41 |
|
41 | |||
42 | Returns |
|
42 | Returns | |
43 | ------- |
|
43 | ------- | |
44 | decorator : function |
|
44 | decorator : function | |
45 | Decorator which, when applied to a function, causes SkipTest |
|
45 | Decorator which, when applied to a function, causes SkipTest | |
46 | to be raised when `skip_condition` is True, and the function |
|
46 | to be raised when `skip_condition` is True, and the function | |
47 | to be called normally otherwise. |
|
47 | to be called normally otherwise. | |
48 |
|
48 | |||
49 | Notes |
|
49 | Notes | |
50 | ----- |
|
50 | ----- | |
51 | The decorator itself is decorated with the ``nose.tools.make_decorator`` |
|
51 | The decorator itself is decorated with the ``nose.tools.make_decorator`` | |
52 | function in order to transmit function name, and various other metadata. |
|
52 | function in order to transmit function name, and various other metadata. | |
53 |
|
53 | |||
54 | """ |
|
54 | """ | |
55 |
|
55 | |||
56 | def skip_decorator(f): |
|
56 | def skip_decorator(f): | |
57 | # Local import to avoid a hard nose dependency and only incur the |
|
57 | # Local import to avoid a hard nose dependency and only incur the | |
58 | # import time overhead at actual test-time. |
|
58 | # import time overhead at actual test-time. | |
59 | import nose |
|
59 | import nose | |
60 |
|
60 | |||
61 | # Allow for both boolean or callable skip conditions. |
|
61 | # Allow for both boolean or callable skip conditions. | |
62 | if callable(skip_condition): |
|
62 | if callable(skip_condition): | |
63 | skip_val = lambda : skip_condition() |
|
63 | skip_val = lambda : skip_condition() | |
64 | else: |
|
64 | else: | |
65 | skip_val = lambda : skip_condition |
|
65 | skip_val = lambda : skip_condition | |
66 |
|
66 | |||
67 | def get_msg(func,msg=None): |
|
67 | def get_msg(func,msg=None): | |
68 | """Skip message with information about function being skipped.""" |
|
68 | """Skip message with information about function being skipped.""" | |
69 | if msg is None: |
|
69 | if msg is None: | |
70 | out = 'Test skipped due to test condition' |
|
70 | out = 'Test skipped due to test condition' | |
71 | else: |
|
71 | else: | |
72 | out = '\n'+msg |
|
72 | out = '\n'+msg | |
73 |
|
73 | |||
74 | return "Skipping test: %s%s" % (func.__name__,out) |
|
74 | return "Skipping test: %s%s" % (func.__name__,out) | |
75 |
|
75 | |||
76 | # We need to define *two* skippers because Python doesn't allow both |
|
76 | # We need to define *two* skippers because Python doesn't allow both | |
77 | # return with value and yield inside the same function. |
|
77 | # return with value and yield inside the same function. | |
78 | def skipper_func(*args, **kwargs): |
|
78 | def skipper_func(*args, **kwargs): | |
79 | """Skipper for normal test functions.""" |
|
79 | """Skipper for normal test functions.""" | |
80 | if skip_val(): |
|
80 | if skip_val(): | |
81 | raise nose.SkipTest(get_msg(f,msg)) |
|
81 | raise nose.SkipTest(get_msg(f,msg)) | |
82 | else: |
|
82 | else: | |
83 | return f(*args, **kwargs) |
|
83 | return f(*args, **kwargs) | |
84 |
|
84 | |||
85 | def skipper_gen(*args, **kwargs): |
|
85 | def skipper_gen(*args, **kwargs): | |
86 | """Skipper for test generators.""" |
|
86 | """Skipper for test generators.""" | |
87 | if skip_val(): |
|
87 | if skip_val(): | |
88 | raise nose.SkipTest(get_msg(f,msg)) |
|
88 | raise nose.SkipTest(get_msg(f,msg)) | |
89 | else: |
|
89 | else: | |
90 | for x in f(*args, **kwargs): |
|
90 | for x in f(*args, **kwargs): | |
91 | yield x |
|
91 | yield x | |
92 |
|
92 | |||
93 | # Choose the right skipper to use when building the actual decorator. |
|
93 | # Choose the right skipper to use when building the actual decorator. | |
94 | if nose.util.isgenerator(f): |
|
94 | if nose.util.isgenerator(f): | |
95 | skipper = skipper_gen |
|
95 | skipper = skipper_gen | |
96 | else: |
|
96 | else: | |
97 | skipper = skipper_func |
|
97 | skipper = skipper_func | |
98 |
|
98 | |||
99 | return nose.tools.make_decorator(f)(skipper) |
|
99 | return nose.tools.make_decorator(f)(skipper) | |
100 |
|
100 | |||
101 | return skip_decorator |
|
101 | return skip_decorator | |
102 |
|
102 | |||
103 | def knownfailureif(fail_condition, msg=None): |
|
103 | def knownfailureif(fail_condition, msg=None): | |
104 | """ |
|
104 | """ | |
105 | Make function raise KnownFailureTest exception if given condition is true. |
|
105 | Make function raise KnownFailureTest exception if given condition is true. | |
106 |
|
106 | |||
107 | Parameters |
|
107 | Parameters | |
108 | ---------- |
|
108 | ---------- | |
109 | fail_condition : bool |
|
109 | fail_condition : bool | |
110 | Flag to determine whether to mark the decorated test as a known |
|
110 | Flag to determine whether to mark the decorated test as a known | |
111 | failure (if True) or not (if False). |
|
111 | failure (if True) or not (if False). | |
112 | msg : str, optional |
|
112 | msg : str, optional | |
113 | Message to give on raising a KnownFailureTest exception. |
|
113 | Message to give on raising a KnownFailureTest exception. | |
114 | Default is None. |
|
114 | Default is None. | |
115 |
|
115 | |||
116 | Returns |
|
116 | Returns | |
117 | ------- |
|
117 | ------- | |
118 | decorator : function |
|
118 | decorator : function | |
119 | Decorator, which, when applied to a function, causes KnownFailureTest to |
|
119 | Decorator, which, when applied to a function, causes KnownFailureTest to | |
120 | be raised when `fail_condition` is True and the test fails. |
|
120 | be raised when `fail_condition` is True and the test fails. | |
121 |
|
121 | |||
122 | Notes |
|
122 | Notes | |
123 | ----- |
|
123 | ----- | |
124 | The decorator itself is decorated with the ``nose.tools.make_decorator`` |
|
124 | The decorator itself is decorated with the ``nose.tools.make_decorator`` | |
125 | function in order to transmit function name, and various other metadata. |
|
125 | function in order to transmit function name, and various other metadata. | |
126 |
|
126 | |||
127 | """ |
|
127 | """ | |
128 | if msg is None: |
|
128 | if msg is None: | |
129 | msg = 'Test skipped due to known failure' |
|
129 | msg = 'Test skipped due to known failure' | |
130 |
|
130 | |||
131 | def knownfail_decorator(f): |
|
131 | def knownfail_decorator(f): | |
132 | # Local import to avoid a hard nose dependency and only incur the |
|
132 | # Local import to avoid a hard nose dependency and only incur the | |
133 | # import time overhead at actual test-time. |
|
133 | # import time overhead at actual test-time. | |
134 | import nose |
|
134 | import nose | |
135 |
|
135 | |||
136 | try: |
|
136 | try: | |
137 | from pytest import xfail |
|
137 | from pytest import xfail | |
138 | except ImportError: |
|
138 | except ImportError: | |
139 |
|
139 | |||
140 | def xfail(): |
|
140 | def xfail(msg): | |
141 | raise KnownFailureTest(msg) |
|
141 | raise KnownFailureTest(msg) | |
142 |
|
142 | |||
143 | def knownfailer(*args, **kwargs): |
|
143 | def knownfailer(*args, **kwargs): | |
144 | if fail_condition: |
|
144 | if fail_condition: | |
145 | xfail(msg) |
|
145 | xfail(msg) | |
146 | else: |
|
146 | else: | |
147 | return f(*args, **kwargs) |
|
147 | return f(*args, **kwargs) | |
148 | return nose.tools.make_decorator(f)(knownfailer) |
|
148 | return nose.tools.make_decorator(f)(knownfailer) | |
149 |
|
149 | |||
150 | return knownfail_decorator |
|
150 | return knownfail_decorator |
General Comments 0
You need to be logged in to leave comments.
Login now