Mercurial > kallithea
annotate rhodecode/tests/nose_parametrized.py @ 3212:6c28533d122c beta
IP restrictions now also enabled for IPv6
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Wed, 23 Jan 2013 23:51:57 +0100 |
parents | 60c48410996e |
children | 2a7cbc53f65a |
rev | line source |
---|---|
2465
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
1 import re |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
2 import new |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
3 import inspect |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
4 import logging |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
5 import logging.handlers |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
6 from functools import wraps |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
7 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
8 from nose.tools import nottest |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
9 from unittest import TestCase |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
10 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
11 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
12 def _terrible_magic_get_defining_classes(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
13 """ Returns the set of parent classes of the class currently being defined. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
14 Will likely only work if called from the ``parameterized`` decorator. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
15 This function is entirely @brandon_rhodes's fault, as he suggested |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
16 the implementation: http://stackoverflow.com/a/8793684/71522 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
17 """ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
18 stack = inspect.stack() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
19 if len(stack) <= 4: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
20 return [] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
21 frame = stack[3] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
22 code_context = frame[4][0].strip() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
23 if not code_context.startswith("class "): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
24 return [] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
25 _, parents = code_context.split("(", 1) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
26 parents, _ = parents.rsplit(")", 1) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
27 return eval("[" + parents + "]", frame[0].f_globals, frame[0].f_locals) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
28 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
29 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
30 def parameterized(input): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
31 """ Parameterize a test case: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
32 >>> add1_tests = [(1, 2), (2, 3)] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
33 >>> class TestFoo(object): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
34 ... @parameterized(add1_tests) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
35 ... def test_add1(self, input, expected): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
36 ... assert_equal(add1(input), expected) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
37 >>> @parameterized(add1_tests) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
38 ... def test_add1(input, expected): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
39 ... assert_equal(add1(input), expected) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
40 >>> |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
41 """ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
42 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
43 if not hasattr(input, "__iter__"): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
44 raise ValueError("expected iterable input; got %r" % (input,)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
45 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
46 def parameterized_helper(f): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
47 attached_instance_method = [False] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
48 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
49 parent_classes = _terrible_magic_get_defining_classes() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
50 if any(issubclass(cls, TestCase) for cls in parent_classes): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
51 raise Exception("Warning: '@parameterized' tests won't work " |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
52 "inside subclasses of 'TestCase' - use " |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
53 "'@parameterized.expand' instead") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
54 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
55 @wraps(f) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
56 def parameterized_helper_method(self=None): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
57 if self is not None and not attached_instance_method[0]: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
58 # confusingly, we need to create a named instance method and |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
59 # attach that to the class... |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
60 cls = self.__class__ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
61 im_f = new.instancemethod(f, None, cls) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
62 setattr(cls, f.__name__, im_f) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
63 attached_instance_method[0] = True |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
64 for args in input: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
65 if isinstance(args, basestring): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
66 args = [args] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
67 # ... then pull that named instance method off, turning it into |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
68 # a bound method ... |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
69 if self is not None: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
70 args = [getattr(self, f.__name__)] + list(args) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
71 else: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
72 args = [f] + list(args) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
73 # ... then yield that as a tuple. If those steps aren't |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
74 # followed precicely, Nose gets upset and doesn't run the test |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
75 # or doesn't run setup methods. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
76 yield tuple(args) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
77 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
78 f.__name__ = "_helper_for_%s" % (f.__name__,) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
79 parameterized_helper_method.parameterized_input = input |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
80 parameterized_helper_method.parameterized_func = f |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
81 return parameterized_helper_method |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
82 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
83 return parameterized_helper |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
84 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
85 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
86 def to_safe_name(s): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
87 return re.sub("[^a-zA-Z0-9_]", "", s) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
88 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
89 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
90 def parameterized_expand_helper(func_name, func, args): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
91 def parameterized_expand_helper_helper(self=()): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
92 if self != (): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
93 self = (self,) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
94 return func(*(self + args)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
95 parameterized_expand_helper_helper.__name__ = func_name |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
96 return parameterized_expand_helper_helper |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
97 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
98 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
99 def parameterized_expand(input): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
100 """ A "brute force" method of parameterizing test cases. Creates new test |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
101 cases and injects them into the namespace that the wrapped function |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
102 is being defined in. Useful for parameterizing tests in subclasses |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
103 of 'UnitTest', where Nose test generators don't work. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
104 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
105 >>> @parameterized.expand([("foo", 1, 2)]) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
106 ... def test_add1(name, input, expected): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
107 ... actual = add1(input) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
108 ... assert_equal(actual, expected) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
109 ... |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
110 >>> locals() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
111 ... 'test_add1_foo_0': <function ...> ... |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
112 >>> |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
113 """ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
114 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
115 def parameterized_expand_wrapper(f): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
116 stack = inspect.stack() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
117 frame = stack[1] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
118 frame_locals = frame[0].f_locals |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
119 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
120 base_name = f.__name__ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
121 for num, args in enumerate(input): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
122 name_suffix = "_%s" % (num,) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
123 if len(args) > 0 and isinstance(args[0], basestring): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
124 name_suffix += "_" + to_safe_name(args[0]) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
125 name = base_name + name_suffix |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
126 new_func = parameterized_expand_helper(name, f, args) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
127 frame_locals[name] = new_func |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
128 return nottest(f) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
129 return parameterized_expand_wrapper |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
130 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
131 parameterized.expand = parameterized_expand |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
132 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
133 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
134 def assert_contains(haystack, needle): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
135 if needle not in haystack: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
136 raise AssertionError("%r not in %r" % (needle, haystack)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
137 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
138 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
139 def assert_not_contains(haystack, needle): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
140 if needle in haystack: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
141 raise AssertionError("%r in %r" % (needle, haystack)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
142 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
143 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
144 def imported_from_test(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
145 """ Returns true if it looks like this module is being imported by unittest |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
146 or nose. """ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
147 import re |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
148 import inspect |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
149 nose_re = re.compile(r"\bnose\b") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
150 unittest_re = re.compile(r"\bunittest2?\b") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
151 for frame in inspect.stack(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
152 file = frame[1] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
153 if nose_re.search(file) or unittest_re.search(file): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
154 return True |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
155 return False |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
156 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
157 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
158 def assert_raises(func, exc_type, str_contains=None, repr_contains=None): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
159 try: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
160 func() |
2556
60c48410996e
fixed nose_parametrized for py25 compat
Marcin Kuzminski <marcin@python-works.com>
parents:
2465
diff
changeset
|
161 except exc_type, e: |
2465
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
162 if str_contains is not None and str_contains not in str(e): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
163 raise AssertionError("%s raised, but %r does not contain %r" |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
164 % (exc_type, str(e), str_contains)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
165 if repr_contains is not None and repr_contains not in repr(e): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
166 raise AssertionError("%s raised, but %r does not contain %r" |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
167 % (exc_type, repr(e), repr_contains)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
168 return e |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
169 else: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
170 raise AssertionError("%s not raised" % (exc_type,)) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
171 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
172 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
173 log_handler = None |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
174 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
175 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
176 def setup_logging(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
177 """ Configures a log handler which will capure log messages during a test. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
178 The ``logged_messages`` and ``assert_no_errors_logged`` functions can be |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
179 used to make assertions about these logged messages. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
180 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
181 For example:: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
182 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
183 from ensi_common.testing import ( |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
184 setup_logging, teardown_logging, assert_no_errors_logged, |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
185 assert_logged, |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
186 ) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
187 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
188 class TestWidget(object): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
189 def setup(self): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
190 setup_logging() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
191 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
192 def teardown(self): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
193 assert_no_errors_logged() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
194 teardown_logging() |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
195 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
196 def test_that_will_fail(self): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
197 log.warning("this warning message will trigger a failure") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
198 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
199 def test_that_will_pass(self): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
200 log.info("but info messages are ok") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
201 assert_logged("info messages are ok") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
202 """ |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
203 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
204 global log_handler |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
205 if log_handler is not None: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
206 logging.getLogger().removeHandler(log_handler) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
207 log_handler = logging.handlers.BufferingHandler(1000) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
208 formatter = logging.Formatter("%(name)s: %(levelname)s: %(message)s") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
209 log_handler.setFormatter(formatter) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
210 logging.getLogger().addHandler(log_handler) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
211 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
212 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
213 def teardown_logging(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
214 global log_handler |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
215 if log_handler is not None: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
216 logging.getLogger().removeHandler(log_handler) |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
217 log_handler = None |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
218 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
219 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
220 def logged_messages(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
221 assert log_handler, "setup_logging not called" |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
222 return [(log_handler.format(record), record) for record in log_handler.buffer] |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
223 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
224 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
225 def assert_no_errors_logged(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
226 for _, record in logged_messages(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
227 if record.levelno >= logging.WARNING: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
228 # Assume that the nose log capture plugin is being used, so it will |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
229 # show the exception. |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
230 raise AssertionError("an unexpected error was logged") |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
231 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
232 |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
233 def assert_logged(expected_msg_contents): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
234 for msg, _ in logged_messages(): |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
235 if expected_msg_contents in msg: |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
236 return |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
237 raise AssertionError("no logged message contains %r" |
8a8805478312
Add nose paratetrized decorator for running configurable tests
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
238 % (expected_msg_contents,)) |