[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