[Zope3-checkins] SVN: zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner Doctests demonstrating layers from a users point of view, including tests of the proposed layer.testSetUp and layer.testTearDown feature soon to be implemented.

Stuart Bishop cvs-admin at zope.org
Fri Jun 16 02:30:05 EDT 2006


Log message for revision 68686:
  Doctests demonstrating layers from a users point of view, including tests of the proposed layer.testSetUp and layer.testTearDown feature soon to be implemented.
  

Changed:
  A   zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner-layers-api.txt
  U   zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner.py

-=-
Added: zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner-layers-api.txt
===================================================================
--- zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner-layers-api.txt	2006-06-16 06:26:47 UTC (rev 68685)
+++ zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner-layers-api.txt	2006-06-16 06:30:00 UTC (rev 68686)
@@ -0,0 +1,220 @@
+Test Runner
+===========
+
+The Layers API
+--------------
+
+A Layer is an object providing setup and teardown methods used to setup
+and teardown the environment provided by the layer. It may also provide
+setup and teardown methods used to reset the environment provided by the
+layer between each test.
+
+Layers are generally implemented as classes using class methods.
+
+>>> class BaseLayer:
+...     @classmethod
+...     def setUp(cls):
+...         log('BaseLayer.setUp')
+...
+...     @classmethod
+...     def tearDown(cls):
+...         log('BaseLayer.tearDown')
+...
+...     @classmethod
+...     def testSetUp(cls):
+...         log('BaseLayer.testSetUp')
+...
+...     @classmethod
+...     def testTearDown(cls):
+...         log('BaseLayer.testTearDown')
+
+Layers can extend other layers. Note that they do not explicitly
+invoke the setup and teardown methods of other layers - the test runner
+does this for us in order to minimize the number of invokations.
+
+>>> class TopLayer(BaseLayer):
+...     @classmethod
+...     def setUp(cls):
+...         log('TopLayer.setUp')
+...
+...     @classmethod
+...     def tearDown(cls):
+...         log('TopLayer.tearDown')
+...
+...     @classmethod
+...     def testSetUp(cls):
+...         log('TopLayer.testSetUp')
+...
+...     def testTearDown(cls):
+...         log('TopLayer.testTearDown')
+
+Tests or test suites specify what layer they need by storing a reference
+in the 'layer' attribute.
+
+>>> import unittest
+>>> class TestSpecifyingBaseLayer(unittest.TestCase):
+...     'This TestCase explicitly specifies its layer'
+...     layer = BaseLayer
+...     name = 'TestSpecifyingBaseLayer' # For testing only
+...
+...     def setUp(self):
+...         log('TestSpecifyingBaseLayer.setUp')
+...
+...     def tearDown(self):
+...         log('TestSpecifyingBaseLayer.tearDown')
+...
+...     def test1(self):
+...         log('TestSpecifyingBaseLayer.test1')
+...
+...     def test2(self):
+...         log('TestSpecifyingBaseLayer.test2')
+...
+>>> class TestSpecifyingNoLayer(unittest.TestCase):
+...     'This TestCase specifies no layer'
+...     name = 'TestSpecifyingNoLayer' # For testing only
+...     def setUp(self):
+...         log('TestSpecifyingNoLayer.setUp')
+...
+...     def tearDown(self):
+...         log('TestSpecifyingNoLayer.tearDown')
+...
+...     def test1(self):
+...         log('TestSpecifyingNoLayer.test')
+...
+...     def test2(self):
+...         log('TestSpecifyingNoLayer.test')
+...
+>>> umbrella_suite = unittest.TestSuite()
+>>> umbrella_suite.addTest(unittest.makeSuite(TestSpecifyingBaseLayer))
+>>> no_layer_suite = unittest.makeSuite(TestSpecifyingNoLayer)
+>>> umbrella_suite.addTest(no_layer_suite)
+
+Before we can run the tests, we need to setup some helpers.
+
+>>> from zope.testing import testrunner
+>>> from zope.testing.loggingsupport import InstalledHandler
+>>> import logging
+>>> log_handler = InstalledHandler('zope.testing.tests')
+>>> def log(msg):
+...     logging.getLogger('zope.testing.tests').info(msg)
+>>> def report():
+...     for record in log_handler.records:
+...         print record.getMessage()
+>>> def fresh_options():
+...     options = testrunner.get_options(['--test-filter', '.*'])
+...     options.resume_layer = None
+...     options.resume_number = 0
+...     return options
+
+Now we run the tests. Note that the BaseLayer was not setup when
+the TestSpecifyingNoLayer was run and setup/torn down around the
+TestSpecifyingBaseLayer tests.
+
+>>> succeeded = testrunner.run_with_options(fresh_options(), [umbrella_suite])
+Running unit tests:
+    Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
+    Set up BaseLayer in N.NNN seconds.
+    Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
+Tearing down left over layers:
+    Tear down BaseLayer in N.NNN seconds.
+Total: 4 tests, 0 failures, 0 errors
+
+Now lets specify a layer in the suite containing TestSpecifyingNoLayer
+and run the tests again. This demonstrates the other method of specifying
+a layer. This is generally how you specify what layer doctests need.
+
+>>> no_layer_suite.layer = BaseLayer
+>>> succeeded = testrunner.run_with_options(fresh_options(), [umbrella_suite])
+  Set up BaseLayer in N.NNN seconds.
+  Ran 4 tests with 0 failures and 0 errors in N.NNN seconds.
+Tearing down left over layers:
+  Tear down BaseLayer in N.NNN seconds.
+
+Clear our logged output, as we want to inpect it shortly.
+
+>>> log_handler.clear()
+
+Now lets also specify a layer in the TestSpecifyingNoLayer class and rerun
+the tests. This demonstrates that the most specific layer is used. It also
+shows the behavior of nested layers - because TopLayer extends BaseLayer,
+both the BaseLayer and TopLayer environments are setup when the
+TestSpecifyingNoLayer tests are run.
+
+>>> TestSpecifyingNoLayer.layer = TopLayer
+>>> succeeded = testrunner.run_with_options(fresh_options(), [umbrella_suite])
+  Set up BaseLayer in N.NNN seconds.
+  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
+  Set up TopLayer in N.NNN seconds.
+  Ran 2 tests with 0 failures and 0 errors in N.NNN seconds.
+Tearing down left over layers:
+  Tear down TopLayer in N.NNN seconds.
+  Tear down BaseLayer in N.NNN seconds.
+Total: 4 tests, 0 failures, 0 errors
+
+If we inspect our trace of what methods got called in what order, we can
+see that the layer setup and teardown methods only got called once. We can
+also see that the layer's test setup and teardown methods got called for
+each test using that layer in the right order.
+
+>>> report()
+BaseLayer.setUp
+BaseLayer.testSetup
+TestSpecifyingBaseLayer.setUp
+TestSpecifyingBaseLayer.test1
+TestSpecifyingBaseLayer.tearDown
+BaseLayer.testTearDown
+BaseLayer.testSetUp
+TestSpecifyingBaseLayer.setUp
+TestSpecifyingBaseLayer.test2
+TestSpecifyingBaseLayer.tearDown
+BaseLayer.testTearDown
+TopLayer.setUp
+BaseLayer.testSetUp
+TopLayer.testSetUp
+TestSpecifyingNoLayer.setUp
+TestSpecifyingNoLayer.test
+TestSpecifyingNoLayer.tearDown
+TopLayer.testTearDown
+BaseLayer.testTearDown
+BaseLayer.testSetUp
+TopLayer.testSetUp
+TestSpecifyingNoLayer.setUp
+TestSpecifyingNoLayer.test
+TestSpecifyingNoLayer.tearDown
+TopLayer.testTearDown
+BaseLayer.testTearDown
+TopLayer.tearDown
+BaseLayer.tearDown
+
+
+Test some testrunner.py internals
+=================================
+
+These are unit tests of the almost totally undocumented testrunner.py
+internals. They should be moved to a seperate file and more unit tests
+added as more of testrunner.py is decoded and refactored to make it unit
+testable.
+
+>>> del no_layer_suite.layer
+>>> del TestSpecifyingNoLayer.layer
+
+>>> tests_and_layers = sorted(testrunner.tests_from_suite(
+...     umbrella_suite, fresh_options()
+...     ))
+>>> for test, layer_name in tests_and_layers:
+...     print layer_name, '-', str(test.name)
+BaseLayer - TestSpecifyingBaseLayer 
+BaseLayer - TestSpecifyingBaseLayer 
+unit - TestSpecifyingNoLayer
+unit - TestSpecifyingNoLayer
+
+>>> found_tests = testrunner.find_tests(fresh_options(), [umbrella_suite])
+>>> for layer_name, suite in sorted(found_tests.items()):
+...     for test_name in sorted(test.name for test in suite):
+...         print layer_name, '-', test_name
+BaseLayer - TestSpecifyingBaseLayer 
+BaseLayer - TestSpecifyingBaseLayer 
+unit - TestSpecifyingNoLayer
+unit - TestSpecifyingNoLayer
+
+


Property changes on: zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner-layers-api.txt
___________________________________________________________________
Name: svn:keywords "LastChangedDate Author Id LastChangedRevision LastChangedBy HeadURL"
   + 
Name: svn:eol-style
   + native

Modified: zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner.py	2006-06-16 06:26:47 UTC (rev 68685)
+++ zope.testing/branches/stub-testSetUp_in_layer/src/zope/testing/testrunner.py	2006-06-16 06:30:00 UTC (rev 68686)
@@ -1874,6 +1874,7 @@
         'testrunner-errors.txt',
         'testrunner-layers-ntd.txt',
         'testrunner-layers.txt',
+        'testrunner-layers-api.txt',
         'testrunner-progress.txt',
         'testrunner-simple.txt',
         'testrunner-test-selection.txt',



More information about the Zope3-Checkins mailing list