[Checkins] SVN: grok/branches/philikon-grokking-tests/src/grok/ Support for finding tests in a grok-like manner:

Philipp von Weitershausen philikon at philikon.de
Wed Mar 28 04:16:24 EDT 2007


Log message for revision 73820:
  Support for finding tests in a grok-like manner:
  
  * We use a module-level grokker to create DocTestSuites for each module.
  
  * In the module you can use grok.doctest(**options) to specify some parameters
    for the doctest, such as setUp, tearDown, etc.
  
  * The grokker is employed using a separate grok function (grok_tests) and a separate
    grokker registry.  That way grokked tests and components grokked in those tests are
    completely separate (which is important because cleanup happens for components and tests
    at different times)
  
  * grok_tests() returns a list of DocTestSuite objects (perhaps it should already turn that
    into a unittest.TestSuite object?).  You can pass it the standard DocTestSuite parameters
    as well, they will be passed on to the grokker which will use them as default parameters
    if a grok.doctest() directive isn't there.
  
  

Changed:
  U   grok/branches/philikon-grokking-tests/src/grok/directive.py
  A   grok/branches/philikon-grokking-tests/src/grok/testing.py

-=-
Modified: grok/branches/philikon-grokking-tests/src/grok/directive.py
===================================================================
--- grok/branches/philikon-grokking-tests/src/grok/directive.py	2007-03-28 08:15:05 UTC (rev 73819)
+++ grok/branches/philikon-grokking-tests/src/grok/directive.py	2007-03-28 08:16:23 UTC (rev 73820)
@@ -262,6 +262,15 @@
             return func
         return decorator
 
+class DocTestDirective(OnceDirective):
+    # XXX pad out the exact args we take, from DocTestSuite (minus
+    # package, plus layer)
+    def check_arguments(self, **options):
+        pass
+
+    def value_factory(self, **options):
+        return options
+
 # Define grok directives
 name = SingleTextDirective('grok.name', ClassDirectiveContext())
 template = SingleTextDirective('grok.template', ClassDirectiveContext())
@@ -277,3 +286,4 @@
 define_permission = MultipleTextDirective('grok.define_permission',
                                           ModuleDirectiveContext())
 require = RequireDirective('grok.require', ClassDirectiveContext())
+doctest = DocTestDirective('grok.doctest', ModuleDirectiveContext())

Added: grok/branches/philikon-grokking-tests/src/grok/testing.py
===================================================================
--- grok/branches/philikon-grokking-tests/src/grok/testing.py	2007-03-28 08:15:05 UTC (rev 73819)
+++ grok/branches/philikon-grokking-tests/src/grok/testing.py	2007-03-28 08:16:23 UTC (rev 73820)
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+Grok testing facilities
+"""
+import re
+from zope.testing import doctest
+from grok import util, components, grokker, scan
+
+class DocTestGrokker(components.ModuleGrokker):
+
+    def __init__(self, **defaults):
+        self.defaults = defaults
+
+    def register(self, context, module_info, templates):
+        global found_tests
+
+        module = module_info.getModule()
+        options = util.class_annotation(module, 'grok.doctest', {})
+
+        options_w_defaults = self.defaults.copy()
+        options_w_defaults.update(options)
+        layer = options_w_defaults.pop('layer', None)
+
+        try:
+            suite = doctest.DocTestSuite(module_info.dotted_name,
+                                         **options_w_defaults)
+        except ValueError:
+            # The module contains no tests. That's fine, just skip it
+            return # XXX but not when grok.doctest() is called explicitly
+
+        if layer is not None:
+            suite.layer = layer
+        found_tests.append(suite)
+
+found_tests = []
+def grok_tests(dotted_name, ignore=[], **defaults):
+    global found_tests
+    ignore = [re.compile(expr).match for expr in ignore]
+
+    # Create a separate grokker registry just for the test grokker so
+    # separate concerns between test finding code and testing code
+    test_grokker_registry = grokker.GrokkerRegistry()
+    test_grokker_registry.registerGrokker(DocTestGrokker(**defaults))
+    module_info = scan.module_info_from_dotted_name(dotted_name)
+    grok_tree(test_grokker_registry, module_info, ignore)
+
+    # Make sure we clear the global list of tests before returning
+    # them (so that subsequent calls to this function don't end up
+    # returning old results as well)
+    return_tests, found_tests[:] = found_tests[:], []
+    return return_tests
+
+def grok_tree(registry, module_info, ignore):
+    for ignore_match in ignore:
+        if ignore_match(module_info.dotted_name):
+            return
+
+    registry.grok(module_info)
+
+    for sub_module_info in module_info.getSubModuleInfos():
+        grok_tree(registry, sub_module_info, ignore)


Property changes on: grok/branches/philikon-grokking-tests/src/grok/testing.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list