[Zope3-checkins] SVN: zope.testing/trunk/src/zope/testing/testrunner Fix ordering of testSetUp and testTearDown calls, and allow new style classes

Stuart Bishop stuart at stuartbishop.net
Fri Jun 30 07:49:38 EDT 2006


Log message for revision 68925:
  Fix ordering of testSetUp and testTearDown calls, and allow new style classes
  to be used as Layers by explicitly ignoring the object baseclass.
  

Changed:
  U   zope.testing/trunk/src/zope/testing/testrunner-layers-api.txt
  U   zope.testing/trunk/src/zope/testing/testrunner.py

-=-
Modified: zope.testing/trunk/src/zope/testing/testrunner-layers-api.txt
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner-layers-api.txt	2006-06-29 21:52:31 UTC (rev 68924)
+++ zope.testing/trunk/src/zope/testing/testrunner-layers-api.txt	2006-06-30 11:49:37 UTC (rev 68925)
@@ -193,3 +193,78 @@
 TopLayer.tearDown
 BaseLayer.tearDown
 
+Now lets stack a few more layers to ensure that our setUp and tearDown
+methods are called in the correct order.
+
+>>> from zope.testing.testrunner import name_from_layer
+>>> class A(object):
+...     def setUp(cls):
+...         log('%s.setUp' % name_from_layer(cls))
+...     setUp = classmethod(setUp)
+...
+...     def tearDown(cls):
+...         log('%s.tearDown' % name_from_layer(cls))
+...     tearDown = classmethod(tearDown)
+...
+...     def testSetUp(cls):
+...         log('%s.testSetUp' % name_from_layer(cls))
+...     testSetUp = classmethod(testSetUp)
+...
+...     def testTearDown(cls):
+...         log('%s.testTearDown' % name_from_layer(cls))
+...     testTearDown = classmethod(testTearDown)
+...         
+>>> class B(A): pass
+>>> class C(B): pass
+>>> class D(A): pass
+>>> class E(D): pass
+>>> class F(C,E): pass
+
+>>> class DeepTest(unittest.TestCase):
+...     layer = F
+...     def test(self):
+...         pass
+>>> suite = unittest.makeSuite(DeepTest)
+>>> log_handler.clear()
+>>> succeeded = testrunner.run_with_options(fresh_options(), [suite])
+  Set up A in 0.000 seconds.
+  Set up B in 0.000 seconds.
+  Set up C in 0.000 seconds.
+  Set up D in 0.000 seconds.
+  Set up E in 0.000 seconds.
+  Set up F in 0.000 seconds.
+  Ran 1 tests with 0 failures and 0 errors in 0.003 seconds.
+Tearing down left over layers:
+  Tear down F in 0.000 seconds.
+  Tear down E in 0.000 seconds.
+  Tear down D in 0.000 seconds.
+  Tear down C in 0.000 seconds.
+  Tear down B in 0.000 seconds.
+  Tear down A in 0.000 seconds.
+
+>>> report()
+A.setUp
+B.setUp
+C.setUp
+D.setUp
+E.setUp
+F.setUp
+A.testSetUp
+B.testSetUp
+C.testSetUp
+D.testSetUp
+E.testSetUp
+F.testSetUp
+F.testTearDown
+E.testTearDown
+D.testTearDown
+C.testTearDown
+B.testTearDown
+A.testTearDown
+F.tearDown
+E.tearDown
+D.tearDown
+C.tearDown
+B.tearDown
+A.tearDown
+

Modified: zope.testing/trunk/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner.py	2006-06-29 21:52:31 UTC (rev 68924)
+++ zope.testing/trunk/src/zope/testing/testrunner.py	2006-06-30 11:49:37 UTC (rev 68925)
@@ -655,7 +655,8 @@
         print "  Tear down %s" % name_from_layer(l),
         t = time.time()
         try:
-            l.tearDown()
+            if hasattr(l, 'tearDown'):
+                l.tearDown()
         except NotImplementedError:
             print "... not supported"
             if not optional:
@@ -665,12 +666,15 @@
         del setup_layers[l]
 
 def setup_layer(layer, setup_layers):
+    assert layer is not object
     if layer not in setup_layers:
         for base in layer.__bases__:
-            setup_layer(base, setup_layers)
+            if base is not object:
+                setup_layer(base, setup_layers)
         print "  Set up %s" % name_from_layer(layer),
         t = time.time()
-        layer.setUp()
+        if hasattr(layer, 'setUp'):
+            layer.setUp()
         print "in %.3f seconds." % (time.time() - t)
         setup_layers[layer] = 1
 
@@ -688,9 +692,12 @@
         self.options = options
         # Calculate our list of relevant layers we need to call testSetUp
         # and testTearDown on.
-        self.layers = []
         if layer_name != 'unit':
-            gather_layers(layer_from_name(layer_name), self.layers)
+            layers = []
+            gather_layers(layer_from_name(layer_name), layers)
+            self.layers = order_by_bases(layers)
+        else:
+            self.layers = []
         if options.progress:
             count = 0
             for test in tests:
@@ -737,7 +744,7 @@
         """A layer may define a setup method to be called before each
         individual test.
         """
-        for layer in self.layers[-1::-1]:
+        for layer in self.layers:
             if hasattr(layer, 'testSetUp'):
                 layer.testSetUp()
 
@@ -749,7 +756,7 @@
            resources or resetting external systems such as relational
            databases or daemons.
         """
-        for layer in self.layers:
+        for layer in self.layers[-1::-1]:
             if hasattr(layer, 'testTearDown'):
                 layer.testTearDown()
 
@@ -957,7 +964,8 @@
         yield layer_name, layer, tests_by_layer_name[layer_name]
 
 def gather_layers(layer, result):
-    result.append(layer)
+    if layer is not object:
+        result.append(layer)
     for b in layer.__bases__:
         gather_layers(b, result)
 



More information about the Zope3-Checkins mailing list