[Checkins] SVN: z3c.testsetup/tags/0.2.0/ Prepare release.
Uli Fouquet
uli at gnufix.de
Sat Feb 16 20:36:55 EST 2008
Log message for revision 83969:
Prepare release.
Changed:
A z3c.testsetup/tags/0.2.0/
D z3c.testsetup/tags/0.2.0/CHANGES.txt
A z3c.testsetup/tags/0.2.0/CHANGES.txt
D z3c.testsetup/tags/0.2.0/setup.py
A z3c.testsetup/tags/0.2.0/setup.py
D z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt
A z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt
D z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py
A z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py
D z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt
A z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt
A z3c.testsetup/tags/0.2.0/src/z3c/testsetup/tests/cave_to_let/
-=-
Copied: z3c.testsetup/tags/0.2.0 (from rev 83862, z3c.testsetup/trunk)
Deleted: z3c.testsetup/tags/0.2.0/CHANGES.txt
===================================================================
--- z3c.testsetup/trunk/CHANGES.txt 2008-02-15 14:03:12 UTC (rev 83862)
+++ z3c.testsetup/tags/0.2.0/CHANGES.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -1,8 +0,0 @@
-=======
-CHANGES
-=======
-
-0.1.0 (2008-02-15)
-------------------
-
-- Initial Release
Copied: z3c.testsetup/tags/0.2.0/CHANGES.txt (from rev 83967, z3c.testsetup/trunk/CHANGES.txt)
===================================================================
--- z3c.testsetup/tags/0.2.0/CHANGES.txt (rev 0)
+++ z3c.testsetup/tags/0.2.0/CHANGES.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -0,0 +1,23 @@
+CHANGES
+*******
+
+0.2 (unreleased)
+==================
+
+Feature Changes
+---------------
+
+* An `ftesting.zcml` in the root of a handled package is now taken as
+ default layer for functional doctests if it exists.
+
+Bug fixes
+---------
+
+
+0.1 (2008-02-15)
+================
+
+Feature changes
+---------------
+
+- Initial Release
Deleted: z3c.testsetup/tags/0.2.0/setup.py
===================================================================
--- z3c.testsetup/trunk/setup.py 2008-02-15 14:03:12 UTC (rev 83862)
+++ z3c.testsetup/tags/0.2.0/setup.py 2008-02-17 01:36:53 UTC (rev 83969)
@@ -1,49 +0,0 @@
-from setuptools import setup, find_packages
-import os
-
-def read(*rnames):
- return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-long_description = (
- read('README.txt')
- + '\n\n'
- + 'Detailed Documentation\n'
- + '----------------------\n'
- + read('src', 'z3c', 'testsetup', 'README.txt')
- + '\n\n'
- + read('CHANGES.txt')
- + '\n\n'
- )
-
-setup(
- name='z3c.testsetup',
- version='0.1.0',
- author='Uli Fouquet and the Zope Community',
- author_email='uli at gnufix.de',
- url = 'http://pypi.python.org/pypi/z3c.testsetup',
- description='Easier test setup for Zope 3 projects and '
- 'other Python packages.',
- long_description=long_description,
- license='ZPL 2.1',
- keywords="zope3 zope tests unittest doctest testsetup",
- classifiers=['Development Status :: 3 - Alpha',
- 'Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Zope Public License',
- 'Programming Language :: Python',
- 'Operating System :: OS Independent',
- 'Framework :: Zope3',
- ],
-
- packages=find_packages('src'),
- package_dir = {'': 'src'},
- namespace_packages = ['z3c'],
- include_package_data = True,
- zip_safe=False,
- install_requires=['setuptools',
- 'zope.component',
- 'zope.testing',
- 'zope.app.testing',
- 'martian',
- ],
-)
Copied: z3c.testsetup/tags/0.2.0/setup.py (from rev 83968, z3c.testsetup/trunk/setup.py)
===================================================================
--- z3c.testsetup/tags/0.2.0/setup.py (rev 0)
+++ z3c.testsetup/tags/0.2.0/setup.py 2008-02-17 01:36:53 UTC (rev 83969)
@@ -0,0 +1,51 @@
+from setuptools import setup, find_packages
+import os
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description = (
+ read('README.txt')
+ + '\n\n'
+ + 'Detailed Documentation\n'
+ + '**********************\n'
+ + read('src', 'z3c', 'testsetup', 'README.txt')
+ + '\n\n'
+ + read('CHANGES.txt')
+ + '\n\n'
+ + 'Download\n'
+ + '********\n'
+ )
+
+setup(
+ name='z3c.testsetup',
+ version='0.2dev',
+ author='Uli Fouquet and the Zope Community',
+ author_email='uli at gnufix.de',
+ url = 'http://pypi.python.org/pypi/z3c.testsetup',
+ description='Easier test setup for Zope 3 projects and '
+ 'other Python packages.',
+ long_description=long_description,
+ license='ZPL 2.1',
+ keywords="zope3 zope tests unittest doctest testsetup",
+ classifiers=['Development Status :: 3 - Alpha',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Operating System :: OS Independent',
+ 'Framework :: Zope3',
+ ],
+
+ packages=find_packages('src'),
+ package_dir = {'': 'src'},
+ namespace_packages = ['z3c'],
+ include_package_data = True,
+ zip_safe=False,
+ install_requires=['setuptools',
+ 'zope.component',
+ 'zope.testing',
+ 'zope.app.testing',
+ 'martian',
+ ],
+)
Deleted: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt
===================================================================
--- z3c.testsetup/trunk/src/z3c/testsetup/README.txt 2008-02-15 14:03:12 UTC (rev 83862)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -1,526 +0,0 @@
-=============
-z3c.testsetup
-=============
-
-Easy testsetups for Zope 3 and Python projects.
-
-Setting up tests for Zope 3 projects sometimes tends to be
-cumbersome. ``z3c.testsetup`` jumps in here, to support much flatter
-test setups. The package supports three kinds of tests:
-
-- normal python tests: i.e. tests, that consist of python modules
- which in turn contain ``unittest.TestCase`` classes.
-
-- unit doctests: i.e. tests, that are written as doctests, but require
- no complicated layer setup etc.
-
-- functional doctests: i.e. tests, that are written as doctests, but
- also require a more or less complex framework to test for example
- browser requests.
-
-``z3c.testsetup`` is package-oriented. That means, it registers more or
-less automatically all the three kinds of tests mentioned above
-insofar they are part of a certain package.
-
-This is a general introduction to ``z3c.testsetup``. For setup
-examples you might see the ``cave`` package contained in the `tests/`
-directory. More details on special topics can be found in the
-appropriate .txt files in this directory.
-
-
-Basic Example
--------------
-
-The shortest test setup possible with ``z3c.testsetup`` looks like
-this::
-
- >>> import z3c.testsetup
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave')
-
-It is sufficient to put this lines into a python module which is found
-by your testrunner (see `samplesetup_short` examples in the ``cave``
-package and `testrunner.txt`).
-
-To sum it up, testsetup with ``z3c.testsetup`` is done in two steps:
-
-1) Make sure your testfiles are named properly (.txt/.rst for
- doctests, valid python modules for usual unit tests) and provide a
- suitable marker string as explained below_.
-
-2) Write a test setup module which is named so that your testrunner
- finds it and in this module call::
-
- test_suite = z3c.testsetup.register_all_tests(<package>)
-
- where `<package>` must be a package object. Instead of a package
- object you can also pass the package's dotted name as string like
- `'z3c.testsetup.tests.cave'`.
-
-Given that, this setup should find all doctests (unit and functional)
-as well as python tests in the package and register them.
-
-
-Customized Setups
------------------
-
-The `register_all_tests` function mentioned above accepts a bunch of
-keyword parameters::
-
- register_all_tests(pkg_or_dotted_name, filter_func, extensions,
- encoding, checker,
- globs, setup, teardown, optionflags
- zcml_config, layer_name, layer)
-
-where all but the first parameter are keyword paramters and all but
-the package parameter are optional.
-
-While `filter_func` and `extensions` determine the set of testfiles to
-be found, the other paramters tell how to setup single tests.
-
-
-- `filter_func` (`ufilter_func`, `ffilter_func`):
-
- a function that takes an absolute filepath and returns `True` or
- `False`, depending on whether the file should be included in the
- test suite as doctest or not. `filter_func` applies only to
- doctests.
-
- We setup a few things to check that::
-
- >>> import os
- >>> import unittest
- >>> suite = test_suite()
- >>> suite.countTestCases()
- 4
-
- Okay, the callable in `test_suite` we created above with
- `register_all_tests` apparently delivered four testcases. This is
- normally also the number of files involved, but let's check that
- correctly.
-
- We did setup a function `get_basenames_from_suite` in this testing
- environment (as a `globs` entry) which determines the basenames of
- the paths of all testcases contained in a `TestSuite`::
-
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.rst', 'file1.txt', 'subdirfile.txt']
-
- Ah, okay. There are in fact four files, in which testcases were
- found. Now, we define a plain filter function::
-
- >>> def custom_file_filter(path):
- ... """Accept all txt files."""
- ... return path.endswith('.txt')
-
- This one accepts all '.txt' files. We run `register_all_tests`
- again, but this time with a `filter_func` parameter::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... filter_func=custom_file_filter)
-
- To get the resulting test suite, we again call the returned
- callable::
-
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.txt', 'file1.txt', 'subdirfile.txt',
- 'subdirfile.txt']
-
- Compared with the first call to `register_all_tests` we got some
- strange results here: there is a '.py' file, which should have been
- refused by our filter function and the other two files appear
- twice. What happened?
-
- The python module is included, because python tests are not
- filtered by `filter_func`. Instead this value applies only to
- doctests.
-
- The second strange result, that every .txt file appears twice in
- the list, comes from the fact, that the filter is valid for unit
- and functional doctests at the same time. In other words: the tests
- in those .txt files are registered twice, as unittests and a second
- time as functional tests as well.
-
- If you want a filter function for functional doctests or unit
- doctests only, then you can use `ffilter_func` and `ufilter_func`
- respectively::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... ffilter_func=custom_file_filter,
- ... ufilter_func=lambda x: False)
-
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.txt', 'subdirfile.txt']
-
- As expected, every .txt file was only registered once. The same
- happens, when we switch and accept only unit doctests::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... ffilter_func=lambda x: False,
- ... ufilter_func=custom_file_filter)
-
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.txt', 'subdirfile.txt']
-
- If you specify both, a `filter_func` and a more specialized
- `ufilter_func` or `ffilter_func`, then this has the same effect as
- passing both, `ufilter_func` and `ffilter_func`::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... ffilter_func=lambda x: False,
- ... filter_func=custom_file_filter)
-
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.txt', 'subdirfile.txt']
-
-
-- `pfilter_func`:
-
- Does basically the same as the `filter_func`s above, but handles
- Python modules instead of file paths. It therefore determines the
- set of 'normal' Python tests accepted and does not touch the set
- of doctests accepted.
-
- We define a simple custom filter::
-
- >>> def custom_module_filter(module):
- ... return 'Tests with real' in str(module.__doc__)
-
- that checks for a certain string in modules' doc strings.
-
- Now we start again with `pfilter_func` set::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... pfilter_func=custom_module_filter)
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.rst', 'file1.txt', 'notatest2.py', 'subdirfile.txt']
-
- Because file1.py and notatest2.py in the cave package contain the
- required string, this is correct. Because the default function
- checks for the string `:Test-Layer: python`, the second module was
- omitted by default.
-
- Now let's use a filter, that refuses all modules::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... pfilter_func=lambda x: False)
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.rst', 'file1.txt', 'subdirfile.txt']
-
- All Python modules vanished from the list.
-
- In case you wonder, why not all the other Python files of the
- `cave` package (`__init__.py`, for example) appear in one of the
- lists: we get only the result list, which contains only such
- modules, which provide `unittest.TestCase` definitions. Because
- most modules of the `cave` package don't define test cases, they
- do not appear in the list. This automatism is driven by a
- `unittest.TestLoader`. See
- http://docs.python.org/lib/testloader-objects.html to learn more
- about test loaders.
-
-
-- `extensions` (`uextensions`, `fextensions`):
-
- a list of filename extensions to be considered during test
- search. Default value is `['.txt', '.rst']`. Python tests are not
- touched by this (they have to be regular Python modules with '.py'
- extension).
-
- Note, that the `extensions` attribute is used by the default
- filter function. If you pass your own filter function using
- `[u|f]filter_func`, then the extensions filtering won't work any
- more.
-
- If we want to register .foo files, we can do so::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... extensions=['.foo'])
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'notatest1.foo', 'notatest1.foo']
-
- Note, that only files that contain an appropriate marker are
- found, regardless of the filename extension. The new .foo file
- contains a marker for unit doctests and functional doctests, such
- it is included twice in the list.
-
- As we can see, the new file appears twice. This is, because it is
- registered as functional doctest and unitdoctest as well.
-
- To collect only functional doctests with a certain set of filename
- extensions you can use: `fextensions`::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... fextensions=['.foo'])
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.rst', 'notatest1.foo']
-
- Here the .rst file were registered as unit doctest, while the .foo
- file was registered as functional doctest.
-
- To collect only unit doctests with a different set of filename
- extensions you can use `uextensions`::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... uextensions=['.foo'])
- >>> suite = test_suite()
- >>> get_basenames_from_suite(suite)
- ['file1.py', 'file1.txt', 'notatest1.foo', 'subdirfile.txt']
-
- Here the .foo file was registered as unit doctest and the .txt
- files as functional ones.
-
-
-- `encoding`:
-
- the encoding of testfiles. 'utf-8' by default. Setting this to `None`
- means using the default value. We've hidden one doctest file, that
- contains umlauts. If we set the encoding to `ascii`, we get an
- error::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... encoding='ascii')
- >>> suite = test_suite()
- Traceback (most recent call last):
- ...
- UnicodeDecodeError: 'ascii' codec can't decode ...: ordinal
- not in range(128)
-
- While using 'latin-1' will work::
-
- >>> test_suite = z3c.testsetup.register_all_tests(
- ... 'z3c.testsetup.tests.cave',
- ... encoding='latin-1')
- >>> suite = test_suite()
-
- No traceback here.
-
- You can always overwrite an encoding setting for a certain file by
- following PEP 0263 ( http://www.python.org/dev/peps/pep-0263/ ).
-
-
-- `checker`:
-
- An output checker for functional doctests. `None` by default. A
- typical output checker can be created like this::
-
- >>> import re
- >>> from zope.testing import renormalizing
- >>> mychecker = renormalizing.RENormalizing([
- ... (re.compile('[0-9]*[.][0-9]* seconds'),
- ... '<SOME NUMBER OF> seconds'),
- ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
- ... ])
-
- This would match for example output like `0.123 seconds` if you
- write in your doctest::
-
- <SOME NUBMER OF> seconds
-
- Please see ``testrunner.txt`` for examples of usage.
-
- Checkers are applied to functional doctests only!
-
-- `globs`:
-
- A dictionary of things that should be available immediately
- (without imports) during tests. Defaults are::
-
- dict(http=HTTPCaller(),
- getRootFolder=getRootFolder,
- sync=sync)
-
- for functional doctests and an empty dict for unit
- doctests. Python test globals can't be set this way.
-
- If you want to register special globals for functional doctest or
- unit doctests only, then you can use the `fglobs` and/or `uglobs`
- keyword respectively. These keywords replace any `globs` value for
- the respective kind of tests.
-
- For more extensive examples see ``testrunner.txt``.
-
-- `setup`:
-
- A function that takes a `test` argument and is executed before
- every single doctest. By default it runs::
-
- zope.app.testing.functional.FunctionalTestSetup().setUp()
-
- for functional doctests and an empty function for unit
- doctests. Python tests provide their own setups.
-
- If you want to register special setup-functions for either
- functional or unit doctests, then you can pass keyword parameters
- `fsetup` or `usetup` respectively.
-
-- `teardown`:
-
- The equivalent to `setup`. Runs by default::
-
- FunctionalTestSetup().tearDown()
-
- for functional doctests and::
-
- zope.testing.cleanup.cleanUp()
-
- for unit doctests. Python tests have to provide their own teardown
- functions in TestCases.
-
-- `optionflags`:
-
- Optionflags influence the behaviour of the testrunner. They are
- logically or'd so that you can add them arithmetically. See
-
- http://svn.zope.org/zope.testing/trunk/src/zope/testing/doctest.py
-
- for details.
-
-- `zcml_config`:
-
- A filepath of a ZCML file which is registered with functional
- doctests. In the ZCML file you can for example register principals
- (users) usable by functional doctests.
-
- By default an empty ZCML file of the z3c.testsetup package is
- used (``ftesting.zcml``).
-
- This parameter has no effect, if also a ``layer`` parameter is
- given.
-
-- `layer_name`:
-
- You can name your layer, to distinguish different setups of
- functional doctests. The layer name can be an arbitrary string.
-
- This parameter has no effect, if also a ``layer`` parameter is
- given.
-
-- `layer`:
-
- You can register a ZCML layer yourself and pass it as the
- ``layer`` parameter. If you only have a filepath to the according
- ZCML file, use the ``zcml_config`` paramter instead.
-
- This parameter overrides any ``zcml_config`` and ``layer_name``
- parameter.
-
-
-.. below:
-
-How to mark testfiles/modules
------------------------------
-
-To avoid non-wanted files and modules to be registered, you have to
-mark your wanted test files/modules with a special string explicitly:
-
-- python modules you want to register must provide a module docstring
- that contains a line::
-
- :Test-Layer: python
-
- A module doctring is written at the top of file like this:
-
- **Python Unit Test Example:**::
-
- """
- A module that tests things.
-
- :Test-Layer: python
-
- """
- import unittest
- class MyTest(unittest.TestCase):
- def testFoo(self):
- pass
-
-
-- doctest files that contain unit tests must provide a string::
-
- :Test-Layer: unit
-
- to be registered. Futhermore, their filename extension must be by
- default '.txt' or '.rst'. A file `sampletest.txt` with a unit
- doctest therefore might look like this:
-
- **Unit Doctest Example 1:**::
-
- ==========
- My package
- ==========
-
- :Test-Layer: unit
-
- This is documentation for the MyPackage package.
-
- >>> 1+1
- 2
-
- Also python modules which contain tests in doctests notation are
- doctests. As rule of thumb you can say: if a module contains tests
- that are written preceeded by '>>>', then this is a doctest. If
- ``unittest.TestCase`` classes are defined, then it is a 'normal'
- python testfile. Another valid unit doctest module therefore can
- look like this:
-
- **Unit Doctest Example 2:**::
-
- """
- ==========
- My package
- ==========
-
- A package for doing things.
-
- :Test-Layer: unit
-
- We check for basic things::
-
- >>> 1+1
- 2
-
- """
- class MyClass:
- pass
-
-
-- files that contain functional doctests must provide a string::
-
- :Test-Layer: functional
-
- to be registered. Furthermore they must by default have a filename
- extension `.txt` or `.rst`. A file `sampletest.txt` with functional
- tests might look like this:
-
- **Functional Doctest Example:**::
-
- ==========
- My package
- ==========
-
- :Test-Layer: functional
-
- This is documentation for the MyPackage package.
-
- >>> 1+1
- 2
-
-
Copied: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt (from rev 83968, z3c.testsetup/trunk/src/z3c/testsetup/README.txt)
===================================================================
--- z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt (rev 0)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/README.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -0,0 +1,525 @@
+z3c.testsetup
+*************
+
+Easy testsetups for Zope 3 and Python projects.
+
+Setting up tests for Zope 3 projects sometimes tends to be
+cumbersome. ``z3c.testsetup`` jumps in here, to support much flatter
+test setups. The package supports three kinds of tests:
+
+- normal python tests: i.e. tests, that consist of python modules
+ which in turn contain ``unittest.TestCase`` classes.
+
+- unit doctests: i.e. tests, that are written as doctests, but require
+ no complicated layer setup etc.
+
+- functional doctests: i.e. tests, that are written as doctests, but
+ also require a more or less complex framework to test for example
+ browser requests.
+
+``z3c.testsetup`` is package-oriented. That means, it registers more or
+less automatically all the three kinds of tests mentioned above
+insofar they are part of a certain package.
+
+This is a general introduction to ``z3c.testsetup``. For setup
+examples you might see the ``cave`` package contained in the `tests/`
+directory. More details on special topics can be found in the
+appropriate .txt files in this directory.
+
+
+Basic Example
+=============
+
+The shortest test setup possible with ``z3c.testsetup`` looks like
+this::
+
+ >>> import z3c.testsetup
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave')
+
+It is sufficient to put this lines into a python module which is found
+by your testrunner (see `samplesetup_short` examples in the ``cave``
+package and ``testrunner.txt``).
+
+To sum it up, testsetup with ``z3c.testsetup`` is done in two steps:
+
+1) Make sure your testfiles are named properly (.txt/.rst for
+ doctests, valid python modules for usual unit tests) and provide a
+ suitable marker string as explained below (`How to mark
+ testfiles/modules`_).
+
+2) Write a test setup module which is named so that your testrunner
+ finds it and in this module call::
+
+ test_suite = z3c.testsetup.register_all_tests(<package>)
+
+ where ``<package>`` must be a package object. Instead of a package
+ object you can also pass the package's dotted name as string like
+ `'z3c.testsetup.tests.cave'`.
+
+Given that, this setup should find all doctests (unit and functional)
+as well as python tests in the package and register them.
+
+
+Customized Setups
+=================
+
+The `register_all_tests` function mentioned above accepts a bunch of
+keyword parameters::
+
+ register_all_tests(pkg_or_dotted_name, filter_func, extensions,
+ encoding, checker,
+ globs, setup, teardown, optionflags
+ zcml_config, layer_name, layer)
+
+where all but the first parameter are keyword paramters and all but
+the package parameter are optional.
+
+While `filter_func` and `extensions` determine the set of testfiles to
+be found, the other paramters tell how to setup single tests.
+
+
+- **filter_func** (**ufilter_func**, **ffilter_func**)
+
+ a function that takes an absolute filepath and returns `True` or
+ `False`, depending on whether the file should be included in the
+ test suite as doctest or not. `filter_func` applies only to
+ doctests.
+
+ We setup a few things to check that::
+
+ >>> import os
+ >>> import unittest
+ >>> suite = test_suite()
+ >>> suite.countTestCases()
+ 4
+
+ Okay, the callable in `test_suite` we created above with
+ `register_all_tests` apparently delivered four testcases. This is
+ normally also the number of files involved, but let's check that
+ correctly.
+
+ We did setup a function `get_basenames_from_suite` in this testing
+ environment (as a `globs` entry) which determines the basenames of
+ the paths of all testcases contained in a `TestSuite`::
+
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.rst', 'file1.txt', 'subdirfile.txt']
+
+ Ah, okay. There are in fact four files, in which testcases were
+ found. Now, we define a plain filter function::
+
+ >>> def custom_file_filter(path):
+ ... """Accept all txt files."""
+ ... return path.endswith('.txt')
+
+ This one accepts all '.txt' files. We run `register_all_tests`
+ again, but this time with a `filter_func` parameter::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... filter_func=custom_file_filter)
+
+ To get the resulting test suite, we again call the returned
+ callable::
+
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.txt', 'file1.txt', 'subdirfile.txt',
+ 'subdirfile.txt']
+
+ Compared with the first call to `register_all_tests` we got some
+ strange results here: there is a '.py' file, which should have been
+ refused by our filter function and the other two files appear
+ twice. What happened?
+
+ The python module is included, because python tests are not
+ filtered by `filter_func`. Instead this value applies only to
+ doctests.
+
+ The second strange result, that every .txt file appears twice in
+ the list, comes from the fact, that the filter is valid for unit
+ and functional doctests at the same time. In other words: the tests
+ in those .txt files are registered twice, as unittests and a second
+ time as functional tests as well.
+
+ If you want a filter function for functional doctests or unit
+ doctests only, then you can use `ffilter_func` and `ufilter_func`
+ respectively::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... ffilter_func=custom_file_filter,
+ ... ufilter_func=lambda x: False)
+
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.txt', 'subdirfile.txt']
+
+ As expected, every .txt file was only registered once. The same
+ happens, when we switch and accept only unit doctests::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... ffilter_func=lambda x: False,
+ ... ufilter_func=custom_file_filter)
+
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.txt', 'subdirfile.txt']
+
+ If you specify both, a `filter_func` and a more specialized
+ `ufilter_func` or `ffilter_func`, then this has the same effect as
+ passing both, `ufilter_func` and `ffilter_func`::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... ffilter_func=lambda x: False,
+ ... filter_func=custom_file_filter)
+
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.txt', 'subdirfile.txt']
+
+
+- **pfilter_func**:
+
+ Does basically the same as the ``filter_funcs`` above, but handles
+ Python modules instead of file paths. It therefore determines the
+ set of 'normal' Python tests accepted and does not touch the set
+ of doctests accepted.
+
+ We define a simple custom filter::
+
+ >>> def custom_module_filter(module):
+ ... return 'Tests with real' in str(module.__doc__)
+
+ that checks for a certain string in modules' doc strings.
+
+ Now we start again with `pfilter_func` set::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... pfilter_func=custom_module_filter)
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.rst', 'file1.txt', 'notatest2.py', 'subdirfile.txt']
+
+ Because file1.py and notatest2.py in the cave package contain the
+ required string, this is correct. Because the default function
+ checks for the string `:Test-Layer: python`, the second module was
+ omitted by default.
+
+ Now let's use a filter, that refuses all modules::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... pfilter_func=lambda x: False)
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.rst', 'file1.txt', 'subdirfile.txt']
+
+ All Python modules vanished from the list.
+
+ In case you wonder, why not all the other Python files of the
+ `cave` package (`__init__.py`, for example) appear in one of the
+ lists: we get only the result list, which contains only such
+ modules, which provide `unittest.TestCase` definitions. Because
+ most modules of the `cave` package don't define test cases, they
+ do not appear in the list. This automatism is driven by a
+ `unittest.TestLoader`. See
+ http://docs.python.org/lib/testloader-objects.html to learn more
+ about test loaders.
+
+
+- **extensions** (**uextensions**, **fextensions**):
+
+ a list of filename extensions to be considered during test
+ search. Default value is `['.txt', '.rst']`. Python tests are not
+ touched by this (they have to be regular Python modules with '.py'
+ extension).
+
+ Note, that the `extensions` attribute is used by the default
+ filter function. If you pass your own filter function using
+ `[u|f]filter_func`, then the extensions filtering won't work any
+ more.
+
+ If we want to register .foo files, we can do so::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... extensions=['.foo'])
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'notatest1.foo', 'notatest1.foo']
+
+ Note, that only files that contain an appropriate marker are
+ found, regardless of the filename extension. The new .foo file
+ contains a marker for unit doctests and functional doctests, such
+ it is included twice in the list.
+
+ As we can see, the new file appears twice. This is, because it is
+ registered as functional doctest and unitdoctest as well.
+
+ To collect only functional doctests with a certain set of filename
+ extensions you can use: `fextensions`::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... fextensions=['.foo'])
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.rst', 'notatest1.foo']
+
+ Here the .rst file were registered as unit doctest, while the .foo
+ file was registered as functional doctest.
+
+ To collect only unit doctests with a different set of filename
+ extensions you can use `uextensions`::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... uextensions=['.foo'])
+ >>> suite = test_suite()
+ >>> get_basenames_from_suite(suite)
+ ['file1.py', 'file1.txt', 'notatest1.foo', 'subdirfile.txt']
+
+ Here the .foo file was registered as unit doctest and the .txt
+ files as functional ones.
+
+
+- **encoding**:
+
+ the encoding of testfiles. 'utf-8' by default. Setting this to `None`
+ means using the default value. We've hidden one doctest file, that
+ contains umlauts. If we set the encoding to `ascii`, we get an
+ error::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... encoding='ascii')
+ >>> suite = test_suite()
+ Traceback (most recent call last):
+ ...
+ UnicodeDecodeError: 'ascii' codec can't decode ...: ordinal
+ not in range(128)
+
+ While using 'latin-1' will work::
+
+ >>> test_suite = z3c.testsetup.register_all_tests(
+ ... 'z3c.testsetup.tests.cave',
+ ... encoding='latin-1')
+ >>> suite = test_suite()
+
+ No traceback here.
+
+ You can always overwrite an encoding setting for a certain file by
+ following PEP 0263 ( http://www.python.org/dev/peps/pep-0263/ ).
+
+
+- **checker**:
+
+ An output checker for functional doctests. `None` by default. A
+ typical output checker can be created like this::
+
+ >>> import re
+ >>> from zope.testing import renormalizing
+ >>> mychecker = renormalizing.RENormalizing([
+ ... (re.compile('[0-9]*[.][0-9]* seconds'),
+ ... '<SOME NUMBER OF> seconds'),
+ ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
+ ... ])
+
+ This would match for example output like `0.123 seconds` if you
+ write in your doctest::
+
+ <SOME NUBMER OF> seconds
+
+ Please see ``testrunner.txt`` for examples of usage.
+
+ Checkers are applied to functional doctests only!
+
+- **globs**:
+
+ A dictionary of things that should be available immediately
+ (without imports) during tests. Defaults are::
+
+ dict(http=HTTPCaller(),
+ getRootFolder=getRootFolder,
+ sync=sync)
+
+ for functional doctests and an empty dict for unit
+ doctests. Python test globals can't be set this way.
+
+ If you want to register special globals for functional doctest or
+ unit doctests only, then you can use the `fglobs` and/or `uglobs`
+ keyword respectively. These keywords replace any `globs` value for
+ the respective kind of tests.
+
+ For more extensive examples see ``testrunner.txt``.
+
+- **setup**:
+
+ A function that takes a `test` argument and is executed before
+ every single doctest. By default it runs::
+
+ zope.app.testing.functional.FunctionalTestSetup().setUp()
+
+ for functional doctests and an empty function for unit
+ doctests. Python tests provide their own setups.
+
+ If you want to register special setup-functions for either
+ functional or unit doctests, then you can pass keyword parameters
+ `fsetup` or `usetup` respectively.
+
+- **teardown**:
+
+ The equivalent to `setup`. Runs by default::
+
+ FunctionalTestSetup().tearDown()
+
+ for functional doctests and::
+
+ zope.testing.cleanup.cleanUp()
+
+ for unit doctests. Python tests have to provide their own teardown
+ functions in TestCases.
+
+- **optionflags**:
+
+ Optionflags influence the behaviour of the testrunner. They are
+ logically or'd so that you can add them arithmetically. See
+
+ http://svn.zope.org/zope.testing/trunk/src/zope/testing/doctest.py
+
+ for details.
+
+- **zcml_config**:
+
+ A filepath of a ZCML file which is registered with functional
+ doctests. In the ZCML file you can for example register principals
+ (users) usable by functional doctests.
+
+ By default any `ftesting.zcml` file from the root of the given
+ package is taken. If this does not exist, an empty ZCML file of
+ the z3c.testsetup package is used (``ftesting.zcml``).
+
+ This parameter has no effect, if also a ``layer`` parameter is
+ given.
+
+- **layer_name**:
+
+ You can name your layer, to distinguish different setups of
+ functional doctests. The layer name can be an arbitrary string.
+
+ This parameter has no effect, if also a ``layer`` parameter is
+ given.
+
+- **layer**:
+
+ You can register a ZCML layer yourself and pass it as the
+ ``layer`` parameter. If you only have a filepath to the according
+ ZCML file, use the ``zcml_config`` paramter instead.
+
+ This parameter overrides any ``zcml_config`` and ``layer_name``
+ parameter.
+
+
+How to mark testfiles/modules
+=============================
+
+To avoid non-wanted files and modules to be registered, you have to
+mark your wanted test files/modules with a special string explicitly:
+
+- python modules you want to register must provide a module docstring
+ that contains a line::
+
+ :Test-Layer: python
+
+ A module doctring is written at the top of file like this:
+
+ **Python Unit Test Example:**::
+
+ """
+ A module that tests things.
+
+ :Test-Layer: python
+
+ """
+ import unittest
+ class MyTest(unittest.TestCase):
+ def testFoo(self):
+ pass
+
+
+- doctest files that contain unit tests must provide a string::
+
+ :Test-Layer: unit
+
+ to be registered. Futhermore, their filename extension must be by
+ default '.txt' or '.rst'. A file `sampletest.txt` with a unit
+ doctest therefore might look like this:
+
+ **Unit Doctest Example 1:**::
+
+ ==========
+ My package
+ ==========
+
+ :Test-Layer: unit
+
+ This is documentation for the MyPackage package.
+
+ >>> 1+1
+ 2
+
+ Also python modules which contain tests in doctests notation are
+ doctests. As rule of thumb you can say: if a module contains tests
+ that are written preceeded by '>>>', then this is a doctest. If
+ ``unittest.TestCase`` classes are defined, then it is a 'normal'
+ python testfile. Another valid unit doctest module therefore can
+ look like this:
+
+ **Unit Doctest Example 2:**::
+
+ """
+ ==========
+ My package
+ ==========
+
+ A package for doing things.
+
+ :Test-Layer: unit
+
+ We check for basic things::
+
+ >>> 1+1
+ 2
+
+ """
+ class MyClass:
+ pass
+
+
+- files that contain functional doctests must provide a string::
+
+ :Test-Layer: functional
+
+ to be registered. Furthermore they must by default have a filename
+ extension `.txt` or `.rst`. A file `sampletest.txt` with functional
+ tests might look like this:
+
+ **Functional Doctest Example:**::
+
+ ==========
+ My package
+ ==========
+
+ :Test-Layer: functional
+
+ This is documentation for the MyPackage package.
+
+ >>> 1+1
+ 2
+
+
Deleted: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py
===================================================================
--- z3c.testsetup/trunk/src/z3c/testsetup/doctesting.py 2008-02-15 14:03:12 UTC (rev 83862)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py 2008-02-17 01:36:53 UTC (rev 83969)
@@ -1,183 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007-2008 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.
-#
-##############################################################################
-"""Test setup helpers for doctests.
-"""
-import unittest
-import os.path
-from zope.testing import doctest, cleanup
-from zope.app.testing.functional import (
- HTTPCaller, getRootFolder, sync, ZCMLLayer, FunctionalDocFileSuite,
- FunctionalTestSetup)
-from z3c.testsetup.base import BasicTestSetup
-from z3c.testsetup.util import get_package
-
-class DocTestSetup(BasicTestSetup):
- """A test setup for doctests."""
-
- globs = {}
-
- optionflags = (doctest.ELLIPSIS+
- doctest.NORMALIZE_WHITESPACE+
- doctest.REPORT_NDIFF)
-
- encoding = 'utf-8'
-
- def __init__(self, package, setup=None, teardown=None, globs=None,
- optionflags=None, encoding=None, **kw):
- BasicTestSetup.__init__(self, package, **kw)
- self.setUp = setup or self.setUp
- self.tearDown = teardown or self.tearDown
- self.encoding = encoding or self.encoding
- if globs is not None:
- self.globs = globs
- if optionflags is not None:
- self.optionflags = optionflags
-
-
-class UnitDocTestSetup(DocTestSetup):
- """A unit test setup for packages.
-
- A collection of methods to search for appropriate doctest files in
- a given package. ``UnitTestSetup`` is also able to 'register' the
- tests found and to deliver them as a ready-to-use
- ``unittest.TestSuite`` instance.
-
- While the functionality to search for testfiles is mostly
- inherited from the base class, the focus here is to setup the
- tests correctly.
-
- See file `unittestsetup.py` in the tests/testsetup directory to
- learn more about ``UnitTestSetup``.
- """
-
- optionflags = (doctest.ELLIPSIS+
- doctest.NORMALIZE_WHITESPACE+
- doctest.REPORT_NDIFF)
-
- regexp_list = [
- '^\s*:(T|t)est-(L|l)ayer:\s*(unit)\s*',
- ]
-
- globs = dict()
-
- def setUp(self, test):
- pass
-
- def tearDown(self, test):
- cleanup.cleanUp()
-
- def getTestSuite(self):
- docfiles = self.getDocTestFiles(package=self.package)
- suite = unittest.TestSuite()
- for name in docfiles:
- if os.path.isabs(name):
- # We get absolute pathnames, but we need relative ones...
- common_prefix = os.path.commonprefix([self.package.__file__,
- name])
- name = name[len(common_prefix):]
- suite.addTest(
- doctest.DocFileSuite(
- name,
- package=self.package,
- setUp=self.setUp,
- tearDown=self.tearDown,
- globs=self.globs,
- optionflags=self.optionflags,
- **self.additional_options
- ))
- return suite
-
-
-class FunctionalDocTestSetup(DocTestSetup):
- """A functional test setup for packages.
-
- A collection of methods to search for appropriate doctest files in
- a given package. ``FunctionalTestSetup`` is also able to
- 'register' the tests found and to deliver them as a ready-to-use
- ``unittest.TestSuite`` instance.
-
- While the functionality to search for testfiles is mostly
- inherited from the base class, the focus here is to setup the
- tests correctly.
- """
- ftesting_zcml = os.path.join(os.path.dirname(__file__),
- 'ftesting.zcml')
- layer = ZCMLLayer(ftesting_zcml, __name__,
- 'FunctionalLayer')
-
- globs=dict(http=HTTPCaller(),
- getRootFolder=getRootFolder,
- sync=sync
- )
-
- optionflags = (doctest.ELLIPSIS+
- doctest.NORMALIZE_WHITESPACE+
- doctest.REPORT_NDIFF)
-
- regexp_list = [
- '^\s*:(T|t)est-(L|l)ayer:\s*(functional)\s*',
- ]
-
- checker = None
-
- def __init__(self, package, checker=None, zcml_config = None,
- layer_name='FunctionalLayer', layer=None, **kw):
- DocTestSetup.__init__(self, package, **kw)
- self.checker = checker
- # Setup a new layer if specified in params...
- if zcml_config is not None and layer is None:
- if not os.path.isfile(zcml_config):
- zcml_config = os.path.join(
- os.path.dirname(self.package.__file__),
- zcml_config)
- self.layer = ZCMLLayer(zcml_config, self.package.__name__,
- layer_name)
- # Passing a ready-for-use layer overrides layer specified by
- # zcml_config...
- if layer is not None:
- self.layer = layer
- return
-
- def setUp(self, test):
- FunctionalTestSetup().setUp()
-
- def tearDown(self, test):
- FunctionalTestSetup().tearDown()
-
- def suiteFromFile(self, name):
- suite = unittest.TestSuite()
- if os.path.isabs(name):
- # We get absolute pathnames, but we need relative ones...
- common_prefix = os.path.commonprefix([self.package.__file__, name])
- name = name[len(common_prefix):]
- test = FunctionalDocFileSuite(
- name, package=self.package,
- setUp=self.setUp, tearDown=self.tearDown,
- globs=self.globs,
- optionflags=self.optionflags,
- encoding=self.encoding,
- checker=self.checker,
- **self.additional_options
- )
- test.layer = self.layer
- suite.addTest(test)
- return suite
-
- def getTestSuite(self):
- docfiles = self.getDocTestFiles(package=self.package)
- suite = unittest.TestSuite()
- for name in docfiles:
- suite.addTest(self.suiteFromFile(name))
- return suite
-
Copied: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py (from rev 83965, z3c.testsetup/trunk/src/z3c/testsetup/doctesting.py)
===================================================================
--- z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py (rev 0)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/doctesting.py 2008-02-17 01:36:53 UTC (rev 83969)
@@ -0,0 +1,190 @@
+##############################################################################
+#
+# Copyright (c) 2007-2008 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.
+#
+##############################################################################
+"""Test setup helpers for doctests.
+"""
+import unittest
+import os.path
+from zope.testing import doctest, cleanup
+from zope.app.testing.functional import (
+ HTTPCaller, getRootFolder, sync, ZCMLLayer, FunctionalDocFileSuite,
+ FunctionalTestSetup)
+from z3c.testsetup.base import BasicTestSetup
+from z3c.testsetup.util import get_package
+
+class DocTestSetup(BasicTestSetup):
+ """A test setup for doctests."""
+
+ globs = {}
+
+ optionflags = (doctest.ELLIPSIS+
+ doctest.NORMALIZE_WHITESPACE+
+ doctest.REPORT_NDIFF)
+
+ encoding = 'utf-8'
+
+ def __init__(self, package, setup=None, teardown=None, globs=None,
+ optionflags=None, encoding=None, **kw):
+ BasicTestSetup.__init__(self, package, **kw)
+ self.setUp = setup or self.setUp
+ self.tearDown = teardown or self.tearDown
+ self.encoding = encoding or self.encoding
+ if globs is not None:
+ self.globs = globs
+ if optionflags is not None:
+ self.optionflags = optionflags
+
+
+class UnitDocTestSetup(DocTestSetup):
+ """A unit test setup for packages.
+
+ A collection of methods to search for appropriate doctest files in
+ a given package. ``UnitTestSetup`` is also able to 'register' the
+ tests found and to deliver them as a ready-to-use
+ ``unittest.TestSuite`` instance.
+
+ While the functionality to search for testfiles is mostly
+ inherited from the base class, the focus here is to setup the
+ tests correctly.
+
+ See file `unittestsetup.py` in the tests/testsetup directory to
+ learn more about ``UnitTestSetup``.
+ """
+
+ optionflags = (doctest.ELLIPSIS+
+ doctest.NORMALIZE_WHITESPACE+
+ doctest.REPORT_NDIFF)
+
+ regexp_list = [
+ '^\s*:(T|t)est-(L|l)ayer:\s*(unit)\s*',
+ ]
+
+ globs = dict()
+
+ def setUp(self, test):
+ pass
+
+ def tearDown(self, test):
+ cleanup.cleanUp()
+
+ def getTestSuite(self):
+ docfiles = self.getDocTestFiles(package=self.package)
+ suite = unittest.TestSuite()
+ for name in docfiles:
+ if os.path.isabs(name):
+ # We get absolute pathnames, but we need relative ones...
+ common_prefix = os.path.commonprefix([self.package.__file__,
+ name])
+ name = name[len(common_prefix):]
+ suite.addTest(
+ doctest.DocFileSuite(
+ name,
+ package=self.package,
+ setUp=self.setUp,
+ tearDown=self.tearDown,
+ globs=self.globs,
+ optionflags=self.optionflags,
+ **self.additional_options
+ ))
+ return suite
+
+
+class FunctionalDocTestSetup(DocTestSetup):
+ """A functional test setup for packages.
+
+ A collection of methods to search for appropriate doctest files in
+ a given package. ``FunctionalTestSetup`` is also able to
+ 'register' the tests found and to deliver them as a ready-to-use
+ ``unittest.TestSuite`` instance.
+
+ While the functionality to search for testfiles is mostly
+ inherited from the base class, the focus here is to setup the
+ tests correctly.
+ """
+ ftesting_zcml = os.path.join(os.path.dirname(__file__),
+ 'ftesting.zcml')
+ layer = ZCMLLayer(ftesting_zcml, __name__,
+ 'FunctionalLayer')
+
+ globs=dict(http=HTTPCaller(),
+ getRootFolder=getRootFolder,
+ sync=sync
+ )
+
+ optionflags = (doctest.ELLIPSIS+
+ doctest.NORMALIZE_WHITESPACE+
+ doctest.REPORT_NDIFF)
+
+ regexp_list = [
+ '^\s*:(T|t)est-(L|l)ayer:\s*(functional)\s*',
+ ]
+
+ checker = None
+
+ def __init__(self, package, checker=None, zcml_config = None,
+ layer_name='FunctionalLayer', layer=None, **kw):
+ DocTestSetup.__init__(self, package, **kw)
+ self.checker = checker
+ # Setup a new layer if specified in params...
+ if zcml_config is not None and layer is None:
+ if not os.path.isfile(zcml_config):
+ zcml_config = os.path.join(
+ os.path.dirname(self.package.__file__),
+ zcml_config)
+ self.layer = ZCMLLayer(zcml_config, self.package.__name__,
+ layer_name)
+ elif layer is None:
+ # Look for ftesting.zcml in pkg-root...
+ pkg_ftesting_zcml = os.path.join(
+ os.path.dirname(self.package.__file__), 'ftesting.zcml')
+ if os.path.isfile(pkg_ftesting_zcml):
+ self.layer = ZCMLLayer(pkg_ftesting_zcml,
+ self.package.__name__, layer_name)
+ # Passing a ready-for-use layer overrides layer specified by
+ # zcml_config...
+ if layer is not None:
+ self.layer = layer
+ return
+
+ def setUp(self, test):
+ FunctionalTestSetup().setUp()
+
+ def tearDown(self, test):
+ FunctionalTestSetup().tearDown()
+
+ def suiteFromFile(self, name):
+ suite = unittest.TestSuite()
+ if os.path.isabs(name):
+ # We get absolute pathnames, but we need relative ones...
+ common_prefix = os.path.commonprefix([self.package.__file__, name])
+ name = name[len(common_prefix):]
+ test = FunctionalDocFileSuite(
+ name, package=self.package,
+ setUp=self.setUp, tearDown=self.tearDown,
+ globs=self.globs,
+ optionflags=self.optionflags,
+ encoding=self.encoding,
+ checker=self.checker,
+ **self.additional_options
+ )
+ test.layer = self.layer
+ suite.addTest(test)
+ return suite
+
+ def getTestSuite(self):
+ docfiles = self.getDocTestFiles(package=self.package)
+ suite = unittest.TestSuite()
+ for name in docfiles:
+ suite.addTest(self.suiteFromFile(name))
+ return suite
+
Deleted: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt
===================================================================
--- z3c.testsetup/trunk/src/z3c/testsetup/functionaldoctestsetup.txt 2008-02-15 14:03:12 UTC (rev 83862)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -1,448 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 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.
-#
-##############################################################################
-"""
-=========================
-Functional Doc Test Setup
-=========================
-
-``FunctionalDocTestSetup`` helps to find and setup functional doctests
-contained in a package. The most important method therefore might be
-``getTestSuite()``, which searches a given package for doctest files
-and returns all tests found as a suite of functional doctests.
-
-Functional doctest setups find and register only doctests. Those tests
-can also be Python modules but if you defined real `unttest.TestCase`
-classes in your tests, then you most likely have 'normal' Python unit
-tests. Please see 'pythontestsetup.txt' in this case. For simple unit
-doctests, that do not require a more or less complex framework setup
-to be done for each test, the setups described in
-'unitdoctestsetup.txt' might suit your needs better.
-
-There are also real 'oneliners' possible, that wrap around the classes
-described here. See 'README.txt' to learn more about that.
-
-The work is done mainly in two stages:
-
-1) The package is searched for appropriate docfiles, based on the
- settings of instance attributes.
-
-2) The tests contained in the found docfiles are setup as functional
- tests and added to a ``unittest.TestSuite`` instance.
-
-There are plenty of default values active, if you use instances of
-this class without further modifications. Therefore we will first
-discuss the default behaviour and afterwards show, how you can modify
-this behaviour to suit your special expectations on the tests.
-
-
-Setting up a simple test suite
-------------------------------
-
-We want to register the doctests contained in the local ``cave``
-package. This can be simply archieved by doing::
-
- >>> from z3c.testsetup import FunctionalDocTestSetup
- >>> setup = FunctionalDocTestSetup('z3c.testsetup.tests.cave')
- >>> setup
- <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>
-
-Apparently the package to handle was passed as a string in 'dotted
-name' notation. We could also pass the package itself, if it was
-loaded before::
-
- >>> from z3c.testsetup.tests import cave
- >>> setup = FunctionalDocTestSetup(cave)
- >>> setup
- <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>
-
-This setup is ready for use::
-
- >>> suite = setup.getTestSuite()
- >>> suite
- <unittest.TestSuite tests=[...]>
-
-To sum it up, writing a test setup for a project now can be that
-short::
-
- import z3c.testsetup
- def test_suite():
- setup = z3c.testsetup.FunctionalDocTestSetup('z3c.testsetup.tests.cave')
- return setup.getTestSuite()
-
-This will find all .rst and .txt files in the package that provide a
-certain signature (see below), register the contained tests as
-functional tests and run them as part of a `unittest.TestSuite`.
-
-Note: in many test setups you will find a code fragment like the
- following at the end of file::
-
- if __name__ == '__main__':
- unittest.main(default='test_suite')
-
- This is not neccessary for usual testrunner setups. A testrunner
- will look for appropriate filenames (modules) and if those
- modules provide a callable ``test_suite`` (usually a function)
- this callable will be called to deliver a test suite.
-
-FunctionalDocTestSetup default values
--------------------------------------
-
-Understanding the defaults is important, because the default values
-are driving the whole process of finding and registering the test.
-
-
-Which files are found by default?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Basically, all files are accepted that
-
-1) reside inside the package passed to the constructor. This includes
- subdirectories.
-
-2) have a filename extension `.txt` or `.rst` (uppercase, lowercase
- etc. does not matter).
-
-3) are *not* located inside a 'hidden' directory (i.e. a directory
- starting with a dot ('.'). Also subdirectories of 'hidden'
- directories are skipped.
-
-4) contain a ReStructured Text meta-marker somewhere, that defines the
- file as a functional doctest explicitly::
-
- :Test-Layer: functional
-
- This means: there *must* be a line like the above one in the
- doctest file. The term might be preceeded or followed by whitspace
- characters (spaces, tabs).
-
-Only files, that meet all four conditions are searched for functional
-doctests. You can modify this behaviour of course, which will be
-explained below in detail.
-
-
-What options are set by default?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Many options can be set, when registering functional doctests. When
-using the default set of options, the following values are set::
-
-* The setup-instance's ``setUp``-method is set as the ``setUp``
- function.
-
-* The setup-instance's ``tearDown``-method is set as the ``tearDown``
- function.
-
- >>> setup.setUp
- <bound method FunctionalDocTestSetup.setUp of
- <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>>
-
-* The setup-instance's `globs` attribute is passed as the `globs`
- parameter. By default `globs` is a dictionary of functions, that
- should be'globally' available during testruns and it contains::
-
- >>> setup.globs
- {'http': <zope.app.testing.functional.HTTPCaller object at 0x...>,
- 'sync': <function sync at 0x...>,
- 'getRootFolder': <function getRootFolder at 0x...>}
-
- The functions `sync` and `getRootFolder` are provided by
- `zope.app.testing.functional`.
-
-* The setup-instance's `optionsflags` attribute is passed. It
- includes by default the following doctest constants:
-
- >>> from zope.testing import doctest
- >>> setup.optionflags == (doctest.ELLIPSIS+
- ... doctest.NORMALIZE_WHITESPACE |
- ... doctest.REPORT_NDIFF)
- True
-
-* The setup-instances `encoding` attribute is passed. Setting it in
- the constructor will expect doctest files to provide the appropriate
- encoding. By default it is set to 'utf-8':
-
- >>> setup.encoding
- 'utf-8'
-
- You can set it to a another value for differently encoded doctests.
- If no encoding is set (`encoding` is None), 7-bit ASCII will be
- assumed.
-
-* The `checker` attribute helps to renormalize expected
- output. A typical output checker can be created like this::
-
- >>> import re
- >>> from zope.testing import renormalizing
- >>> mychecker = renormalizing.RENormalizing([
- ... (re.compile('[0-9]*[.][0-9]* seconds'),
- ... '<SOME NUMBER OF> seconds'),
- ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
- ... ])
-
- By default a `FunctionalDocTest` instance has no checker::
-
- >>> setup.checker is None
- True
-
-Because functional tests require a ZCML layer, that defines a ZCML
-setup for the tests, we provide a layer, that is driven by the file
-`ftesting.zcml`, which comes with `z3c.testsetup`. The layer is
-accessible as the setup instance attribute `layer`::
-
- >>> setup.layer
- <zope.app.testing.functional.ZCMLLayer instance at 0x...>
-
- >>> setup.layer.config_file
- '...ftesting.zcml'
-
-You can define a custom layer. This is described below.
-
-
-No other options/parameters are set by default.
-
-
-Customizing functional test setup:
-----------------------------------
-
-You can modify the behaviour of z3c.testsetup.FunctionalTestSetup such,
-that a different set of files is registered and/or the found tests are
-registered with a different set of parameters/options. We will first
-discuss modifying the set of files to be searched.
-
-
-Customizing the doctest file search:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The searching of appropriate doctest files is basically done by the
-base class `BasicTestSetup`. Its purpose is to determine the set of
-files in a package, that contain functional tests. See the testfile
-`basicsetup.txt` to learn more about the procedure.
-
-The functional test setup, however, provides a special
-`isDocTestFile()` method, which does additional checking. Namely it
-checks for the existance of the above mentioned ReStructured Text
-meta-marker::
-
- `:Test-Layer: functional`
-
-This is determined by a list of regular expressions, which is also
-available as an object attribute::
-
- >>> setup.regexp_list
- ['^\\s*:(T|t)est-(L|l)ayer:\\s*(functional)\\s*']
-
-This is the default value of functional doctest setups.
-
-There are two files in the `cave` subpackage, which include that
-marker. We can get the list of test files using
-`getDocTestFiles()``::
-
- >>> testfile_list = setup.getDocTestFiles()
- >>> testfile_list.sort()
- >>> testfile_list
- ['...file1.txt', '...subdirfile.txt']
-
- >>> len(testfile_list)
- 2
-
-The ``isTestFile()`` method of our setup object did the filtering
-here::
-
- >>> setup.isTestFile(testfile_list[0])
- True
-
-The file file1.rst does not contain a functional test marker::
-
- >>> import os.path
- >>> path = os.path.join(os.path.dirname(cave.__file__),
- ... 'test1.rst')
- >>> setup.isTestFile(path)
- False
-
-The `regexp_list` attribute of a ``FunctionalTestSetup`` contains a
-list of regular expressions, of which each one must at least match one
-line of a searched file to be accepted. If you want to include files
-with different marker-strings, just change this attribute. The value
-will influence behaviour of the `isTestFile()``, ``getDocTestFiles()``
-and ``getTestSuite()`` methods.
-
-If you need more complex checks here, you can derive your customized
-test setup class and overwrite ``isTestFile()``.
-
-See `basicsetup.py` for further methods how to modify test file
-search, for example by choosing another set of accepted filename
-extensions.
-
-
-Customizing the functional doctest setup
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To customize the setup of your tests, you have three options:
-
-- Pass appropriate parameters to the constructor.
-
-- Set attributes of an existing `FunctionalDocTestSetup` instance.
-
-- Create your own class derived from `FunctionalDocTestSetup`.
-
-The first two ways should suit most testing environments. All the
-attributes mentioned above are settable at creation time, namely:
-
-- `setup`::
-
- >>> def myfunc(test):
- ... """A useless function."""
- ... print "Hello!"
- >>> mysetup = FunctionalDocTestSetup(cave, setup=myfunc)
- >>> mysetup.setUp(None)
- Hello!
-
-- `teardown`::
-
- >>> mysetup = FunctionalDocTestSetup(cave, teardown=myfunc)
- >>> mysetup.tearDown(None)
- Hello!
-
-- `globs`:
-
- `globs` is a dictionary of things (objects, functions, vars) that
- are available for every test immediately (without import or
- similar)::
-
- >>> mysetup = FunctionalDocTestSetup(
- ... cave, globs={'myfunc': myfunc})
- >>> mysetup.globs
- {'myfunc': <function myfunc at 0x...>}
-
-- `optionflags`
-
- See the `zope.testing.doctest` module for all optionflags::
-
- >>> from zope.testing import doctest
- >>> mysetup = FunctionalDocTestSetup(
- ... cave, optionflags=(doctest.ELLIPSIS +
- ... doctest.REPORT_UDIFF))
- >>> mysetup.optionflags & doctest.REPORT_NDIFF == 0
- True
-
- >>> mysetup.optionflags & doctest.REPORT_UDIFF == doctest.REPORT_UDIFF
- True
-
-- `checker`
-
- An output checker for functional doctests. `None` by default. A
- typical output checker can be created like this::
-
- >>> import re
- >>> from zope.testing import renormalizing
- >>> mychecker = renormalizing.RENormalizing([
- ... (re.compile('[0-9]*[.][0-9]* seconds'),
- ... '<SOME NUMBER OF> seconds'),
- ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>') ])
-
- Then, a setup with this checker can be created::
-
- >>> mysetup = FunctionalDocTestSetup(cave, checker = mychecker)
- >>> mysetup.checker
- <zope.testing.renormalizing.RENormalizing instance at 0x...>
-
- Let's see, whether we got the wanted checker, by passing an
- example string, which should match the first of the terms defined
- in the checker::
-
- >>> mysetup.checker.check_output(
- ... '''\
- ... Test took 0.012 seconds
- ... ''', '''\
- ... Test took <SOME NUMBER OF> seconds
- ... ''', 0)
- True
-
- See the `zope.testing.renormalizing` module for more things, you
- can do with checkers.
-
-- `encoding`
-
- If your doctests contain non-ASCII characters, this might lead to
- problems. You can circumvent this by setting an appropriate
- encoding string in the header of your doctest files. Another
- possibility is to pass the encoding keyword. By default
- z3c.testsetup uses 'utf-8' as default encoding::
-
- >>> setup.encoding
- 'utf-8'
-
- But you can set it as you like::
-
- >>> mysetup = FunctionalDocTestSetup(cave, encoding = 'ascii')
- >>> mysetup.encoding
- 'ascii'
-
-To setup layers, there are the following constructor options
-available:
-
-- `zcml_config`
-
-- `layer_name`
-
-- `layer`
-
-Their usage is explained in the next section.
-
-
-Cutomizing the ZCML layer
-+++++++++++++++++++++++++
-
-The ZCML layer registered by default by ``z3c.testsetup`` is very
-poor. In fact it only exists, to satisfy dependencies. In most cases,
-you would like to write your own ZCML configuration to register
-principals etc. during functional doctests.
-
-For this purpose, ``FunctionalDocTestSetup`` supports the constructor
-parameters `zcml_config` and `layer_name`. If the first is set, then
-the ZCML file denoted by the path in this variable will be used
-instead of the dummy ZCML contained in ``z3c.testsetup``.
-
- >>> setup_w_custom_layer = FunctionalDocTestSetup(
- ... cave,
- ... zcml_config = 'sampleftesting.zcml')
- >>> pnorm(setup_w_custom_layer.layer.config_file)
- '.../tests/cave/sampleftesting.zcml'
-
-You can also pass a keyword parameter `layer`, which should provide a
-value with a ready-to-use ZCML layer. If this happens, the
-`zcml_config` and `layer_name` parameter will have no effect.
-
-To show this, we first create a custom layer::
-
- >>> from zope.app.testing.functional import ZCMLLayer
- >>> mylayer = ZCMLLayer(
- ... os.path.join(os.path.dirname(__file__), 'ftesting.zcml'),
- ... __name__,
- ... 'MyFunctionalLayer')
-
-and create a functional doctest setup with it::
-
- >>> setup_w_custom_layer = FunctionalDocTestSetup(
- ... cave,
- ... zcml_config = 'sampleftesting.zcml',
- ... layer = mylayer)
- >>> pnorm(setup_w_custom_layer.layer.config_file)
- '.../testsetup/ftesting.zcml'
-
-As we can see, the `mylayer` config file is registered and the
-`zcml_config` parameter was skipped.
-
-
-"""
Copied: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt (from rev 83965, z3c.testsetup/trunk/src/z3c/testsetup/functionaldoctestsetup.txt)
===================================================================
--- z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt (rev 0)
+++ z3c.testsetup/tags/0.2.0/src/z3c/testsetup/functionaldoctestsetup.txt 2008-02-17 01:36:53 UTC (rev 83969)
@@ -0,0 +1,485 @@
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+"""
+=========================
+Functional Doc Test Setup
+=========================
+
+``FunctionalDocTestSetup`` helps to find and setup functional doctests
+contained in a package. The most important method therefore might be
+``getTestSuite()``, which searches a given package for doctest files
+and returns all tests found as a suite of functional doctests.
+
+Functional doctest setups find and register only doctests. Those tests
+can also be Python modules but if you defined real `unttest.TestCase`
+classes in your tests, then you most likely have 'normal' Python unit
+tests. Please see 'pythontestsetup.txt' in this case. For simple unit
+doctests, that do not require a more or less complex framework setup
+to be done for each test, the setups described in
+'unitdoctestsetup.txt' might suit your needs better.
+
+There are also real 'oneliners' possible, that wrap around the classes
+described here. See 'README.txt' to learn more about that.
+
+The work is done mainly in two stages:
+
+1) The package is searched for appropriate docfiles, based on the
+ settings of instance attributes.
+
+2) The tests contained in the found docfiles are setup as functional
+ tests and added to a ``unittest.TestSuite`` instance.
+
+There are plenty of default values active, if you use instances of
+this class without further modifications. Therefore we will first
+discuss the default behaviour and afterwards show, how you can modify
+this behaviour to suit your special expectations on the tests.
+
+
+Setting up a simple test suite
+------------------------------
+
+We want to register the doctests contained in the local ``cave``
+package. This can be simply archieved by doing::
+
+ >>> from z3c.testsetup import FunctionalDocTestSetup
+ >>> setup = FunctionalDocTestSetup('z3c.testsetup.tests.cave')
+ >>> setup
+ <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>
+
+Apparently the package to handle was passed as a string in 'dotted
+name' notation. We could also pass the package itself, if it was
+loaded before::
+
+ >>> from z3c.testsetup.tests import cave
+ >>> setup = FunctionalDocTestSetup(cave)
+ >>> setup
+ <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>
+
+This setup is ready for use::
+
+ >>> suite = setup.getTestSuite()
+ >>> suite
+ <unittest.TestSuite tests=[...]>
+
+To sum it up, writing a test setup for a project now can be that
+short::
+
+ import z3c.testsetup
+ def test_suite():
+ setup = z3c.testsetup.FunctionalDocTestSetup('z3c.testsetup.tests.cave')
+ return setup.getTestSuite()
+
+This will find all .rst and .txt files in the package that provide a
+certain signature (see below), register the contained tests as
+functional tests and run them as part of a `unittest.TestSuite`.
+
+Note: in many test setups you will find a code fragment like the
+ following at the end of file::
+
+ if __name__ == '__main__':
+ unittest.main(default='test_suite')
+
+ This is not neccessary for usual testrunner setups. A testrunner
+ will look for appropriate filenames (modules) and if those
+ modules provide a callable ``test_suite`` (usually a function)
+ this callable will be called to deliver a test suite.
+
+FunctionalDocTestSetup default values
+-------------------------------------
+
+Understanding the defaults is important, because the default values
+are driving the whole process of finding and registering the test.
+
+
+Which files are found by default?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Basically, all files are accepted that
+
+1) reside inside the package passed to the constructor. This includes
+ subdirectories.
+
+2) have a filename extension `.txt` or `.rst` (uppercase, lowercase
+ etc. does not matter).
+
+3) are *not* located inside a 'hidden' directory (i.e. a directory
+ starting with a dot ('.'). Also subdirectories of 'hidden'
+ directories are skipped.
+
+4) contain a ReStructured Text meta-marker somewhere, that defines the
+ file as a functional doctest explicitly::
+
+ :Test-Layer: functional
+
+ This means: there *must* be a line like the above one in the
+ doctest file. The term might be preceeded or followed by whitspace
+ characters (spaces, tabs).
+
+Only files, that meet all four conditions are searched for functional
+doctests. You can modify this behaviour of course, which will be
+explained below in detail.
+
+
+What options are set by default?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Many options can be set, when registering functional doctests. When
+using the default set of options, the following values are set::
+
+* The setup-instance's ``setUp``-method is set as the ``setUp``
+ function.
+
+* The setup-instance's ``tearDown``-method is set as the ``tearDown``
+ function.
+
+ >>> setup.setUp
+ <bound method FunctionalDocTestSetup.setUp of
+ <z3c.testsetup.doctesting.FunctionalDocTestSetup object at 0x...>>
+
+* The setup-instance's `globs` attribute is passed as the `globs`
+ parameter. By default `globs` is a dictionary of functions, that
+ should be'globally' available during testruns and it contains::
+
+ >>> setup.globs
+ {'http': <zope.app.testing.functional.HTTPCaller object at 0x...>,
+ 'sync': <function sync at 0x...>,
+ 'getRootFolder': <function getRootFolder at 0x...>}
+
+ The functions `sync` and `getRootFolder` are provided by
+ `zope.app.testing.functional`.
+
+* The setup-instance's `optionsflags` attribute is passed. It
+ includes by default the following doctest constants:
+
+ >>> from zope.testing import doctest
+ >>> setup.optionflags == (doctest.ELLIPSIS+
+ ... doctest.NORMALIZE_WHITESPACE |
+ ... doctest.REPORT_NDIFF)
+ True
+
+* The setup-instances `encoding` attribute is passed. Setting it in
+ the constructor will expect doctest files to provide the appropriate
+ encoding. By default it is set to 'utf-8':
+
+ >>> setup.encoding
+ 'utf-8'
+
+ You can set it to a another value for differently encoded doctests.
+ If no encoding is set (`encoding` is None), 7-bit ASCII will be
+ assumed.
+
+* The `checker` attribute helps to renormalize expected
+ output. A typical output checker can be created like this::
+
+ >>> import re
+ >>> from zope.testing import renormalizing
+ >>> mychecker = renormalizing.RENormalizing([
+ ... (re.compile('[0-9]*[.][0-9]* seconds'),
+ ... '<SOME NUMBER OF> seconds'),
+ ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
+ ... ])
+
+ By default a `FunctionalDocTest` instance has no checker::
+
+ >>> setup.checker is None
+ True
+
+Because functional tests require a ZCML layer, that defines a ZCML
+setup for the tests, we provide a layer, that is driven by the file
+`ftesting.zcml`, which comes with `z3c.testsetup`. The layer is
+accessible as the setup instance attribute `layer`::
+
+ >>> setup.layer
+ <zope.app.testing.functional.ZCMLLayer instance at 0x...>
+
+ >>> setup.layer.config_file
+ '...ftesting.zcml'
+
+You can define a custom layer. This is described below.
+
+
+No other options/parameters are set by default.
+
+
+Customizing functional test setup:
+----------------------------------
+
+You can modify the behaviour of z3c.testsetup.FunctionalTestSetup such,
+that a different set of files is registered and/or the found tests are
+registered with a different set of parameters/options. We will first
+discuss modifying the set of files to be searched.
+
+
+Customizing the doctest file search:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The searching of appropriate doctest files is basically done by the
+base class `BasicTestSetup`. Its purpose is to determine the set of
+files in a package, that contain functional tests. See the testfile
+`basicsetup.txt` to learn more about the procedure.
+
+The functional test setup, however, provides a special
+`isDocTestFile()` method, which does additional checking. Namely it
+checks for the existance of the above mentioned ReStructured Text
+meta-marker::
+
+ `:Test-Layer: functional`
+
+This is determined by a list of regular expressions, which is also
+available as an object attribute::
+
+ >>> setup.regexp_list
+ ['^\\s*:(T|t)est-(L|l)ayer:\\s*(functional)\\s*']
+
+This is the default value of functional doctest setups.
+
+There are two files in the `cave` subpackage, which include that
+marker. We can get the list of test files using
+`getDocTestFiles()``::
+
+ >>> testfile_list = setup.getDocTestFiles()
+ >>> testfile_list.sort()
+ >>> testfile_list
+ ['...file1.txt', '...subdirfile.txt']
+
+ >>> len(testfile_list)
+ 2
+
+The ``isTestFile()`` method of our setup object did the filtering
+here::
+
+ >>> setup.isTestFile(testfile_list[0])
+ True
+
+The file file1.rst does not contain a functional test marker::
+
+ >>> import os.path
+ >>> path = os.path.join(os.path.dirname(cave.__file__),
+ ... 'test1.rst')
+ >>> setup.isTestFile(path)
+ False
+
+The `regexp_list` attribute of a ``FunctionalTestSetup`` contains a
+list of regular expressions, of which each one must at least match one
+line of a searched file to be accepted. If you want to include files
+with different marker-strings, just change this attribute. The value
+will influence behaviour of the `isTestFile()``, ``getDocTestFiles()``
+and ``getTestSuite()`` methods.
+
+If you need more complex checks here, you can derive your customized
+test setup class and overwrite ``isTestFile()``.
+
+See `basicsetup.py` for further methods how to modify test file
+search, for example by choosing another set of accepted filename
+extensions.
+
+
+Customizing the functional doctest setup
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To customize the setup of your tests, you have three options:
+
+- Pass appropriate parameters to the constructor.
+
+- Set attributes of an existing `FunctionalDocTestSetup` instance.
+
+- Create your own class derived from `FunctionalDocTestSetup`.
+
+The first two ways should suit most testing environments. All the
+attributes mentioned above are settable at creation time, namely:
+
+- `setup`::
+
+ >>> def myfunc(test):
+ ... """A useless function."""
+ ... print "Hello!"
+ >>> mysetup = FunctionalDocTestSetup(cave, setup=myfunc)
+ >>> mysetup.setUp(None)
+ Hello!
+
+- `teardown`::
+
+ >>> mysetup = FunctionalDocTestSetup(cave, teardown=myfunc)
+ >>> mysetup.tearDown(None)
+ Hello!
+
+- `globs`:
+
+ `globs` is a dictionary of things (objects, functions, vars) that
+ are available for every test immediately (without import or
+ similar)::
+
+ >>> mysetup = FunctionalDocTestSetup(
+ ... cave, globs={'myfunc': myfunc})
+ >>> mysetup.globs
+ {'myfunc': <function myfunc at 0x...>}
+
+- `optionflags`
+
+ See the `zope.testing.doctest` module for all optionflags::
+
+ >>> from zope.testing import doctest
+ >>> mysetup = FunctionalDocTestSetup(
+ ... cave, optionflags=(doctest.ELLIPSIS +
+ ... doctest.REPORT_UDIFF))
+ >>> mysetup.optionflags & doctest.REPORT_NDIFF == 0
+ True
+
+ >>> mysetup.optionflags & doctest.REPORT_UDIFF == doctest.REPORT_UDIFF
+ True
+
+- `checker`
+
+ An output checker for functional doctests. `None` by default. A
+ typical output checker can be created like this::
+
+ >>> import re
+ >>> from zope.testing import renormalizing
+ >>> mychecker = renormalizing.RENormalizing([
+ ... (re.compile('[0-9]*[.][0-9]* seconds'),
+ ... '<SOME NUMBER OF> seconds'),
+ ... (re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>') ])
+
+ Then, a setup with this checker can be created::
+
+ >>> mysetup = FunctionalDocTestSetup(cave, checker = mychecker)
+ >>> mysetup.checker
+ <zope.testing.renormalizing.RENormalizing instance at 0x...>
+
+ Let's see, whether we got the wanted checker, by passing an
+ example string, which should match the first of the terms defined
+ in the checker::
+
+ >>> mysetup.checker.check_output(
+ ... '''\
+ ... Test took 0.012 seconds
+ ... ''', '''\
+ ... Test took <SOME NUMBER OF> seconds
+ ... ''', 0)
+ True
+
+ See the `zope.testing.renormalizing` module for more things, you
+ can do with checkers.
+
+- `encoding`
+
+ If your doctests contain non-ASCII characters, this might lead to
+ problems. You can circumvent this by setting an appropriate
+ encoding string in the header of your doctest files. Another
+ possibility is to pass the encoding keyword. By default
+ z3c.testsetup uses 'utf-8' as default encoding::
+
+ >>> setup.encoding
+ 'utf-8'
+
+ But you can set it as you like::
+
+ >>> mysetup = FunctionalDocTestSetup(cave, encoding = 'ascii')
+ >>> mysetup.encoding
+ 'ascii'
+
+To setup layers, there are the following constructor options
+available:
+
+- `zcml_config`
+
+ The path to a ZCML file, often named `ftesting.zcml`. If a
+ package, provides a file `ftesting.zcml` in its root, then this is
+ taken as default. The ``cave_to_let`` package in the tests/
+ directory provides such an `ftesting.zcml`::
+
+ >>> from z3c.testsetup.tests import cave_to_let
+ >>> setup = FunctionalDocTestSetup(cave_to_let)
+ >>> pnorm(setup.layer.config_file)
+ '.../tests/cave_to_let/ftesting.zcml'
+
+ The fallback-solution is to take the layer from the
+ `z3c.testsetup` package::
+
+ >>> setup = FunctionalDocTestSetup(cave)
+ >>> pnorm(setup.layer.config_file)
+ '...z3c/testsetup/ftesting.zcml'
+
+ Now the fallback `ftesting.zcml` was taken, because the cave got
+ no own ftesting.zcml.
+
+- `layer_name`
+
+ A string. The default is ``FunctionalLayer``.
+
+- `layer`
+
+ A ``zope.app.testing.functional.ZCMLLayer`` object. Setting a
+ layer overrides `zcml_config` and `layer_name`.
+
+Their usage is explained in the next section.
+
+
+Cutomizing the ZCML layer
++++++++++++++++++++++++++
+
+The ZCML layer of a FunctionalDocTestSetup is searched in four steps:
+
+1) If a setup is called with `layer` parameter, take this.
+
+2) If a setup is called with `zcml_config` paramter, take this.
+
+3) If an `ftesting.zcml` can be found in the root of the package to
+ search, take this (default).
+
+4) Take the (very poor) ftesting.zcml of the z3c.testsetup package
+ (fallback).
+
+The ZCML layer registered as fallback by ``z3c.testsetup`` is very
+poor. In fact it only exists, to satisfy dependencies. In most cases,
+you would like to write your own ZCML configuration to register
+principals etc. during functional doctests.
+
+For this purpose, ``FunctionalDocTestSetup`` supports the constructor
+parameters `zcml_config` and `layer_name`. If the first is set, then
+the ZCML file denoted by the path in this variable will be used
+instead of the dummy ZCML contained in ``z3c.testsetup``.
+
+ >>> setup_w_custom_layer = FunctionalDocTestSetup(
+ ... cave,
+ ... zcml_config = 'sampleftesting.zcml')
+ >>> pnorm(setup_w_custom_layer.layer.config_file)
+ '.../tests/cave/sampleftesting.zcml'
+
+You can also pass a keyword parameter `layer`, which should provide a
+value with a ready-to-use ZCML layer. If this happens, the
+`zcml_config` and `layer_name` parameter will have no effect.
+
+To show this, we first create a custom layer::
+
+ >>> from zope.app.testing.functional import ZCMLLayer
+ >>> mylayer = ZCMLLayer(
+ ... os.path.join(os.path.dirname(__file__), 'ftesting.zcml'),
+ ... __name__,
+ ... 'MyFunctionalLayer')
+
+and create a functional doctest setup with it::
+
+ >>> setup_w_custom_layer = FunctionalDocTestSetup(
+ ... cave,
+ ... zcml_config = 'sampleftesting.zcml',
+ ... layer = mylayer)
+ >>> pnorm(setup_w_custom_layer.layer.config_file)
+ '.../testsetup/ftesting.zcml'
+
+As we can see, the `mylayer` config file is registered and the
+`zcml_config` parameter was skipped.
+
+
+"""
Copied: z3c.testsetup/tags/0.2.0/src/z3c/testsetup/tests/cave_to_let (from rev 83965, z3c.testsetup/trunk/src/z3c/testsetup/tests/cave_to_let)
More information about the Checkins
mailing list