[Python-Dev] Avoiding cascading test failures
Alexandre Vassalotti
alexandre at peadrop.com
Sun Aug 26 02:23:02 CEST 2007
On 8/25/07, Gregory P. Smith <greg at krypto.org> wrote:
> I like this idea.
Yay! Now, I ain't the only one. ;)
> Be sure to have an option to ignore dependancies and run all tests.
Yes, I planned to add a such option.
> Also when skipping tests because a depedancy failed have unittest
> print out an indication that a test was skipped due to a dependancy
> rather than silently running fewer tests. Otherwise it could be
> deceptive and appear that only one test was affected.
However, that was never planned.
I added the ignore_dependencies option. Also, I fixed the sub-optimal
dependency resolution algorithm that was in my original example
implementation.
-- Alexandre
--- dep.py.old 2007-08-25 19:54:27.000000000 -0400
+++ dep.py 2007-08-25 20:02:55.000000000 -0400
@@ -2,8 +2,9 @@
class CycleError(Exception):
pass
+class TestGraph:
-class TestCase:
+ ignore_dependencies = False
def __init__(self):
self.graph = {}
@@ -19,16 +20,16 @@
graph = self.graph
toskip = set()
msgs = []
- while graph:
+ if self.ignore_dependencies:
+ for test in graph:
+ graph[test].clear()
# find tests without any pending dependencies
- source = [test for test, deps in graph.items() if not deps]
- if not source:
- raise CycleError
- for testname in source:
+ queue = [test for test, deps in graph.items() if not deps]
+ while queue:
+ testname = queue.pop()
if testname in toskip:
msgs.append("%s... skipped" % testname)
- resolvedeps(graph, testname)
- del graph[testname]
+ queue.extend(resolve(graph, testname))
continue
test = getattr(self, testname)
try:
@@ -42,8 +43,9 @@
else:
msgs.append("%s... ok" % testname)
finally:
- resolvedeps(graph, testname)
- del graph[testname]
+ queue.extend(resolve(graph, testname))
+ if graph:
+ raise CycleError
for msg in sorted(msgs):
print(msg)
@@ -60,10 +62,15 @@
rdeps.update(getrevdeps(graph, x))
return rdeps
- def resolvedeps(graph, testname):
+def resolve(graph, testname):
+ toqueue = []
for test in graph:
if testname in graph[test]:
graph[test].remove(testname)
+ if not graph[test]:
+ toqueue.append(test)
+ del graph[testname]
+ return toqueue
def depends(*args):
def decorator(test):
@@ -75,7 +82,9 @@
return decorator
-class MyTest(TestCase):
+class MyTest(TestGraph):
+
+ ignore_dependencies = True
@depends('test_foo')
def test_nah(self):
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dep.py
Type: text/x-python
Size: 2884 bytes
Desc: not available
Url : http://mail.python.org/pipermail/python-dev/attachments/20070825/df266f1e/attachment.py
More information about the Python-Dev
mailing list