plone.testing


Nameplone.testing JSON
Version 9.0.1 PyPI version JSON
download
home_pagehttps://github.com/plone/plone.testing
SummaryTesting infrastructure for Zope and Plone projects.
upload_time2023-11-30 19:31:19
maintainer
docs_urlNone
authorPlone Foundation
requires_python>=3.8
licenseBSD
keywords plone zope testing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Introduction
============

.. contents:: Table of contents

``plone.testing`` provides tools for writing unit and integration tests in a Zope and Plone environment.
It is not tied to Plone, and it does not depend on Zope (although it has some optional Zope-only features).

``plone.testing`` builds on `zope.testing`_, in particular its layers concept.
This package also aims to promote some "good practice" for writing tests of various types.

.. note::

   If you are working with Plone, there is a complementary package `plone.app.testing`_, which builds on ``plone.testing`` to provide additional layers useful for testing Plone add-ons.

If you are new to automated testing and test driven development, you should spend some time learning about those concepts.
Some useful references include:

* `The Wikipedia article on unit testing <https://en.wikipedia.org/wiki/Unit_testing>`_
* `The Dive Into Python chapter on testing <https://diveintopython3.problemsolving.io/unit-testing.html>`_

Bear in mind that different Python frameworks have slightly different takes on how to approach testing.
Therefore, you may find examples that are different to those shown below.
The core concepts should be consistent, however.

Compatibility
-------------

``plone.testing`` 7.x has been tested with Python 2.7 and 3.6.
If you're using the optional Zope layers, you must use Zope version 4 or later.
Look at older ``plone.testing`` versions for supporting older Zope versions.

Definitions
-----------

In this documentation, we will use a number of testing-related terms.
The following definitions apply:

Unit test
    An automated test (i.e. one written in code) that tests a single unit (normally a function) in isolation.
    A unit test attempts to prove that the given function works as expected and gives the correct output given a particular input.
    It is common to have a number of unit tests for a single function, testing different inputs, including boundary cases and errors.
    Unit tests are typically quick to write and run.

Integration test
    An automated test that tests how a number of units interact.
    In a Zope context, this often pertains to how a particular object or view interacts with the Zope framework, the ZODB persistence engine, and so on.
    Integration tests usually require some setup and can be slower to run than unit tests.
    It is common to have fewer integration tests than unit test.

Functional test
    An automated test that tests a feature in an "end-to-end" fashion.
    In a Zope context, that normally means that it invokes an action in the same way that a user would, i.e. through a web request.
    Functional tests are normally slower to run than either unit or integration tests, and can be significantly slower to run.
    It is therefore common to have only a few functional tests for each major feature, relying on unit and integration tests for the bulk of testing.

Black box testing
    Testing which only considers the system's defined inputs and outputs.
    For example, a functional test is normally a black box test that provides inputs only through the defined interface (e.g. URLs published in a web application), and makes assertions only on end outputs (e.g. the response returned for requests to those URLs).

White box testing
    Testing which examines the internal state of a system to make assertions.
    Authors of unit and integration tests normally have significant knowledge of the implementation of the code under test, and can examine such things as data in a database or changes to the system's environment to determine if the test succeeded or failed.

Assertion
    A check that determines whether a test succeeds or fails.
    For example, if a unit test for the function ``foo()`` expects it to return the value 1, an assertion could be written to verify this fact.
    A test is said to *fail* if any of its assertions fail.
    A test always contains one or more assertions.

Test case
    A single unit, integration or functional test.
    Often shortened to just *test*.
    A test case sets up, executes and makes assertions against a single scenario that bears testing.

Test fixture
    The state used as a baseline for one or more tests.
    The test fixture is *set up* before each test is executed, and *torn down* afterwards.
    This is a pre-requisite for *test isolation* - the principle that tests should be independent of one another.

Layer
    The configuration of a test fixture shared by a number of tests.
    All test cases that belong to a particular layer will be executed together.
    The layer is *set up* once before the tests are executed, and *torn down* once after.
    Layers may depend on one another.
    Any *base layers* are set up before and torn down after a particular *child layer* is used.
    The test runner will order test execution to minimise layer setup and tear-down.

Test suite
    A collection of test cases (and layers) that are executed together.

Test runner
    The program which executes tests.
    This is responsible for calling layer and test fixture set-up and tear-down methods.
    It also reports on the test run, usually by printing output to the console.

Coverage
    To have confidence in your code, you should ensure it is adequately covered by tests.
    That is, each line of code, and each possible branching point (loops, ``if`` statements) should be executed by a test.
    This is known as *coverage*, and is normally measured as a percentage of lines of non-test code covered by tests.
    Coverage can be measured by the test runner, which keeps track of which lines of code were executed in a given test run.

Doctest
    A style of testing where tests are written as examples that could be typed into the interactive Python interpreter.
    The test runner executes each example and checks the actual output against the expected output.
    Doctests can either be placed in the docstring of a method, or in a separate file.
    The use of doctests is largely a personal preference.
    Some developers like to write documentation as doctests, which has the advantage that code samples can be automatically tested for correctness.
    You can read more about doctests on `Wikipedia <http://en.wikipedia.org/wiki/Doctest>`_.

Installation and usage
======================

To use ``plone.testing`` in your own package, you need to add it as a dependency.
Most people prefer to keep test-only dependencies separate, so that they do not need to be installed in scenarios (such as on a production server) where the tests will not be run.
This can be achieved using a ``test`` extra.

In ``setup.py``, add or modify the ``extras_require`` option, like so:::

    extras_require = {
        'test': [
                'plone.testing',
            ]
    },

You can add other test-only dependencies to that list as well, of course.

To run tests, you need a test runner.
If you are using ``zc.buildout``, you can install a test runner using the `zc.recipe.testrunner`_ recipe.
For example, you could add the following to your ``buildout.cfg``:::

    [test]
    recipe = zc.recipe.testrunner
    eggs =
        my.package [test]
    defaults = ['--auto-color', '--auto-progress']

You'll also need to add this part to the ``parts`` list, of course:::

    [buildout]
    parts =
        ...
        test

In this example, have listed a single package to test, called ``my.package``, and asked for it to be installed with the ``[test]`` extra.
This will install any regular dependencies (listed in the ``install_requires`` option in ``setup.py``), as well as those in the list associated with the ``test`` key in the ``extras_require`` option.

Note that it becomes important to properly list your dependencies here, because the test runner will only be aware of the packages explicitly listed, and their dependencies.
For example, if your package depends on Zope, you need to list ``Zope`` in the ``install_requires`` list in ``setup.py``;
ditto for ``Plone``, or indeed any other package you import from.

Once you have re-run buildout, the test runner will be installed as ``bin/test`` (the executable name is taken from the name of the buildout part).
You can execute it without arguments to run all tests of each egg listed in the ``eggs`` list::

    $ bin/test

If you have listed several eggs, and you want to run the tests for a particular one, you can do::

    $ bin/test -s my.package

If you want to run only a particular test within this package, use the ``-t`` option.
This can be passed a regular expression matching either a doctest file name or a test method name.::

    $ bin/test -s my.package -t test_spaceship

There are other command line options, which you can find by running::

    $ bin/test --help

Also note the ``defaults`` option in the buildout configuration.
This can be used to set default command line options.
Some commonly useful options are shown above.

Coverage reporting
------------------

When writing tests, it is useful to know how well your tests cover your code.
You can create coverage reports via the excellent `coverage`_ library.
In order to use it, we need to install it and a reporting script::

    [buildout]
    parts =
        ...
        test
        coverage
        report

    [coverage]
    recipe = zc.recipe.egg
    eggs = coverage
    initialization =
        include = '--source=${buildout:directory}/src'
        sys.argv = sys.argv[:] + ['run', include, 'bin/test', '--all']

    [report]
    recipe = zc.recipe.egg
    eggs = coverage
    scripts = coverage=report
    initialization =
        sys.argv = sys.argv[:] + ['html', '-i']

This will run the ``bin/test`` script with arguments like `--all` to run all layers.
You can also specify no or some other arguments.
It will place coverage reporting information in a ``.coverage`` file inside your buildout root.
Via the ``--source`` argument you specify the directories containing code you want to cover.
The coverage script would otherwise generate coverage information for all executed code, including other packages and even the standard library.

Running the ``bin/report`` script will generate a human readable HTML representation of the run in the `htmlcov` directory.
Open the contained `index.html` in a browser to see the result.

If you want to generate an XML representation suitable for the `Cobertura`_ plugin of `Jenkins`_, you can add another part::

    [buildout]
    parts =
        ...
        report-xml

    [report-xml]
    recipe = zc.recipe.egg
    eggs = coverage
    scripts = coverage=report-xml
    initialization =
        sys.argv = sys.argv[:] + ['xml', '-i']

This will generate a ``coverage.xml`` file in the buildout root.

Optional dependencies
---------------------

``plone.testing`` comes with a core set of tools for managing layers, which depends only on `zope.testing`_.
In addition, there are several layers and helper functions which can be used in your own tests (or as bases for your own layers).
Some of these have deeper dependencies.
However, these dependencies are optional and not installed by default.
If you don't use the relevant layers, you can safely ignore them.

``plone.testing`` does specify these dependencies, however, using the ``setuptools`` "extras" feature.
You can depend on one or more extras in your own ``setup.py`` ``install_requires`` or ``extras_require`` option using the same square bracket notation shown for the ``[test]`` buildout part above.
For example, if you need both the ``zca`` and ``publisher`` extras, you can have the following in your ``setup.py``::

    extras_require = {
        'test': [
                'plone.testing [zca, publisher]',
            ]
    },

The available extras are:

``zodb``
    ZODB testing.
    Depends on ``ZODB``.
    The relevant layers and helpers are in the module ``plone.testing.zodb``.

``zca``
    Zope Component Architecture testing.
    Depends on core Zope Component Architecture packages such as ``zope.component`` and ``zope.event``.
    The relevant layers and helpers are in the module ``plone.testing.zca``.

``security``
    Security testing.
    Depends on ``zope.security``.
    The relevant layers and helpers are in the module ``plone.testing.security``.

``publisher``
    Zope Publisher testing.
    Depends on ``zope.publisher``, ``zope.browsermenu``, ``zope.browserpage``, ``zope.browserresource`` and ``zope.security`` and sets up ZCML directives.
    The relevant layers and helpers are in the module ``plone.testing.publisher``.

``zope`` (For backwards compatibility there is also ``z2``.)

    Zope testing.
    Depends on the ``Zope`` egg, which includes all the dependencies of the Zope application server.
    The relevant layers and helpers are in the module ``plone.testing.zope``.

``zserver``

    Tests against the ``ZServer``. (Python 2 only!) Requires additionally to use the ``zope`` extra.
    The relevant layers and helpers are in the module ``plone.testing.zserver``


Adding a test buildout to your package
--------------------------------------

When creating reusable, mostly stand-alone packages, it is often useful to be able to include a buildout with the package sources itself that can be used to create a test runner.
This is a popular approach for many Zope packages, for example.
In fact, ``plone.testing`` itself uses this kind of layout.

To have a self-contained buildout in your package, the following is required:

* You need a ``buildout.cfg`` at the root of the package.

* In most cases, you always want a ``bootstrap.py`` file to make it easier for people to set up a fresh buildout.

* Your package sources need to be inside a ``src`` directory.
  If you're using namespace packages, that means the top level package should be in the ``src`` directory.

* The ``src`` directory must be referenced in ``setup.py``.

For example, ``plone.testing`` has the following layout::

    plone.testing/
    plone.testing/setup.py
    plone.testing/bootstrap.py
    plone.testing/buildout.cfg
    plone.testing/README.rst
    plone.testing/src/
    plone.testing/src/plone
    plone.testing/src/plone/__init__.py
    plone.testing/src/plone/testing/
    plone.testing/src/plone/testing/*

In ``setup.py``, the following arguments are required::

        packages=find_packages('src'),
        package_dir={'': 'src'},

This tells ``setuptools`` where to find the source code.

The ``buildout.cfg`` for ``plone.testing`` looks like this::

    [buildout]
    extends =
        http://download.zope.org/Zope2/index/2.12.12/versions.cfg
    parts = coverage test report report-xml
    develop = .

    [test]
    recipe = collective.xmltestreport
    eggs =
        plone.testing [test]
    defaults = ['--auto-color', '--auto-progress']

    [coverage]
    recipe = zc.recipe.egg
    eggs = coverage
    initialization =
        include = '--source=${buildout:directory}/src'
        sys.argv = sys.argv[:] + ['run', include, 'bin/test', '--all', '--xml']

    [report]
    recipe = zc.recipe.egg
    eggs = coverage
    scripts = coverage=report
    initialization =
        sys.argv = sys.argv[:] + ['html', '-i']

    [report-xml]
    recipe = zc.recipe.egg
    eggs = coverage
    scripts = coverage=report-xml
    initialization =
        sys.argv = sys.argv[:] + ['xml', '-i']

Obviously, you should adjust the package name in the ``eggs`` list and the version set in the ``extends`` line as appropriate.

You can of course also add additional buildout parts, for example to include some development/debugging tools, or even a running application server for testing purposes.

    *Hint:* If you use this package layout, you should avoid checking any files or directories generated by buildout into your version control repository.
    You want to ignore:

    * ``.coverage``
    * ``.installed.cfg``
    * ``bin``
    * ``coverage.xml``
    * ``develop-eggs``
    * ``htmlcov``
    * ``parts``
    * ``src/*.egg-info``

Layers
======

In large part, ``plone.testing`` is about layers.
It provides:

* A set of layers (outlined below), which you can use or extend.

* A set of tools for working with layers

* A mini-framework to make it easy to write layers and manage shared resources associated with layers.

We'll discuss the last two items here, before showing how to write tests that use layers.

Layer basics
------------

Layers are used to create test fixtures that are shared by multiple test cases.
For example, if you are writing a set of integration tests, you may need to set up a database and configure various components to access that database.
This type of test fixture setup can be resource-intensive and time-consuming.
If it is possible to only perform the setup and tear-down once for a set of tests without losing isolation between those tests, test runs can often be sped up significantly.

Layers also allow reuse of test fixtures and set-up/tear-down code.
``plone.testing`` provides a number of useful (but optional) layers that manage test fixtures for common Zope testing scenarios, letting you focus on the actual test authoring.

At the most basic, a layer is an object with the following methods and attributes:

``setUp()``
    Called by the test runner when the layer is to be set up.
    This is called exactly once for each layer used during a test run.

``tearDown()``
    Called by the test runner when the layer is to be torn down.
    As with ``setUp()``, this is called exactly once for each layer.

``testSetUp()``
    Called immediately before each test case that uses the layer is executed.
    This is useful for setting up aspects of the fixture that are managed on a per-test basis, as opposed to fixture shared among all tests.

``testTearDown()``
    Called immediately after each test case that uses the layer is executed.
    This is a chance to perform any post-test cleanup to ensure the fixture is ready for the next test.

``__bases__``
    A tuple of base layers.

Each test case is associated with zero or one layer.
(The syntax for specifying the layer is shown in the section "Writing tests" below.) All the tests associated with a given layer will be executed together.

Layers can depend on one another (as indicated in the ``__bases__`` tuple), allowing one layer to build on the fixture created by another.
Base layers are set up before and torn down after their dependants.

For example, if the test runner is executing some tests that belong to layer A, and some other tests that belong to layer B, both of which depend on layer C, the order of execution might be::

    1. C.setUp()
    1.1. A.setUp()

    1.1.1. C.testSetUp()
    1.1.2. A.testSetUp()
    1.1.3. [One test using layer A]
    1.1.4. A.testTearDown()
    1.1.5. C.testTearDown()

    1.1.6. C.testSetUp()
    1.1.7. A.testSetUp()
    1.1.8. [Another test using layer A]
    1.1.9. A.testTearDown()
    1.1.10. C.testTearDown()

    1.2. A.tearDown()
    1.3. B.setUp()

    1.3.1. C.testSetUp()
    1.3.2. B.testSetUp()
    1.3.3. [One test using layer B]
    1.3.4. B.testTearDown()
    1.3.5. C.testTearDown()

    1.3.6. C.testSetUp()
    1.3.7. B.testSetUp()
    1.3.8. [Another test using layer B]
    1.3.9. B.testTearDown()
    1.3.10. C.testTearDown()

    1.4. B.tearDown()
    2. C.tearDown()

A base layer may of course depend on other base layers.
In the case of nested dependencies like this, the order of set up and tear-down as calculated by the test runner is similar to the way in which Python searches for the method to invoke in the case of multiple inheritance.

Writing layers
--------------

The easiest way to create a new layer is to use the ``Layer`` base class and implement the ``setUp()``, ``tearDown()``, ``testSetUp()`` and ``testTearDown()`` methods as needed.
All four are optional.
The default implementation of each does nothing.

By convention, layers are created in a module called ``testing.py`` at the top level of your package.
The idea is that other packages that extend your package can reuse your layers for their own testing.

A simple layer may look like this::

    >>> from plone.testing import Layer
    >>> class SpaceShip(Layer):
    ...
    ...     def setUp(self):
    ...         print("Assembling space ship")
    ...
    ...     def tearDown(self):
    ...         print("Disasembling space ship")
    ...
    ...     def testSetUp(self):
    ...         print("Fuelling space ship in preparation for test")
    ...
    ...     def testTearDown(self):
    ...         print("Emptying the fuel tank")

Before this layer can be used, it must be instantiated.
Layers are normally instantiated exactly once, since by nature they are shared between tests.
This becomes important when you start to manage resources (such as persistent data, database connections, or other shared resources) in layers.

The layer instance is conventionally also found in ``testing.py``, just after the layer class definition.::

    >>> SPACE_SHIP = SpaceShip()

.. note::

    Since the layer is instantiated in module scope, it will be created as soon as the ``testing`` module is imported.
    It is therefore very important that the layer class is inexpensive and safe to create.
    In general, you should avoid doing anything non-trivial in the ``__init__()`` method of your layer class.
    All setup should happen in the ``setUp()`` method.
    If you *do* implement ``__init__()``, be sure to call the ``super`` version as well.

The layer shown above did not have any base layers (dependencies).
Here is an example of another layer that depends on it:::

    >>> class ZIGSpaceShip(Layer):
    ...     defaultBases = (SPACE_SHIP,)
    ...
    ...     def setUp(self):
    ...         print("Installing main canon")

    >>> ZIG = ZIGSpaceShip()

Here, we have explicitly listed the base layers on which ``ZIGSpaceShip`` depends, in the ``defaultBases`` attribute.
This is used by the ``Layer`` base class to set the layer bases in a way that can also be overridden: see below.

Note that we use the layer *instance* in the ``defaultBases`` tuple, not the class.
Layer dependencies always pertain to specific layer instances.
Above, we are really saying that *instances* of ``ZIGSpaceShip`` will, by default, require the ``SPACE_SHIP`` layer to be set up first.

.. note::

    You may find it useful to create other layer base/mix-in classes that extend ``plone.testing.Layer`` and provide helper methods for use in your own layers.
    This is perfectly acceptable, but please do not confuse a layer base class used in this manner with the concept of a *base layer* as described above:

    * A class deriving from ``plone.testing.Layer`` is known as a *layer class*.
      It defines the behaviour of the layer by implementing the lifecycle methods ``setUp()``, ``tearDown()``, ``testSetUp()`` and/or ``testTearDown()``.

    * A layer class can be instantiated into an actual layer.
      When a layer is associated with a test, it is the layer *instance* that is used.

    * The instance is usually a shared, module-global object, although in some cases it is useful to create copies of layers by instantiating the class more than once.

    * Subclassing an existing layer class is just straightforward OOP reuse: the test runner is not aware of the subclassing relationship.

    * A layer *instance* can be associated with any number of layer *bases*, via its ``__bases__`` property (which is usually via the ``defaultBases`` variable in the class body and/or overridden using the ``bases`` argument to the ``Layer`` constructor).
      These bases are layer *instances*, not classes.
      The test runner will inspect the ``__bases__`` attribute of each layer instance it sets up to calculate layer pre-requisites and dependencies.

    Also note that the `zope.testing`_ documentation contains examples of layers that are "old-style" classes where the ``setUp()`` and ``tearDown()`` methods are ``classmethod`` methods and class inheritance syntax is used to specify base layers.
    Whilst this pattern works, we discourage its use, because the classes created using this pattern are not really used as classes.
    The concept of layer bases is slightly different from class inheritance, and using the ``class`` keyword to create layers with base layers leads to a number of "gotchas" that are best avoided.

Advanced - overriding bases
---------------------------

In some cases, it may be useful to create a copy of a layer, but change its bases.
One reason to do this may if you are reusing a layer from another module, and you need to change the order in which layers are set up and torn down.

Normally, of course, you would just reuse the layer instance, either directly in a test, or in the ``defaultBases`` tuple of another layer, but if you need to change the bases, you can pass a new list of bases to the layer instance constructor:::

    >>> class CATSMessage(Layer):
    ...
    ...     def setUp(self):
    ...         print("All your base are belong to us")
    ...
    ...     def tearDown(self):
    ...         print("For great justice")

    >>> CATS_MESSAGE = CATSMessage()

    >>> ZERO_WING = ZIGSpaceShip(bases=(SPACE_SHIP, CATS_MESSAGE,), name="ZIGSpaceShip:CATSMessage")

Please note that when overriding bases like this, the ``name`` argument is required.
This is because each layer (using in a given test run) must have a unique name.
The default is to use the layer class name, but this obviously only works for one instantiation.
Therefore, ``plone.testing`` requires a name when setting ``bases`` explicitly.

Please take great care when changing layer bases like this.
The layer implementation may make assumptions about the test fixture that was set up by its bases.
If you change the order in which the bases are listed, or remove a base altogether, the layer may fail to set up correctly.

Also, bear in mind that the new layer instance is independent of the original layer instance, so any resources defined in the layer are likely to be duplicated.

Layer combinations
------------------

Sometimes, it is useful to be able to combine several layers into one, without adding any new fixture.
One way to do this is to use the ``Layer`` class directly and instantiate it with new bases:::

    >>> COMBI_LAYER = Layer(bases=(CATS_MESSAGE, SPACE_SHIP,), name="Combi")

Here, we have created a "no-op" layer with two bases: ``CATS_MESSAGE`` and ``SPACE_SHIP``, named ``Combi``.

Please note that when using ``Layer`` directly like this, the ``name`` argument is required.
This is to allow the test runner to identify the layer correctly.
Normally, the class name of the layer is used as a basis for the name, but when using the ``Layer`` base class directly, this is unlikely to be unique or descriptive.

Layer resources
---------------

Many layers will manage one or more resources that are used either by other layers, or by tests themselves.
Examples may include database connections, thread-local objects, or configuration data.

``plone.testing`` contains a simple resource storage abstraction that makes it easy to access resources from dependent layers or tests.
The resource storage uses dictionary notation:::

    >>> class WarpDrive(object):
    ...     """A shared resource"""
    ...
    ...     def __init__(self, maxSpeed):
    ...         self.maxSpeed = maxSpeed
    ...         self.running = False
    ...
    ...     def start(self, speed):
    ...         if speed > self.maxSpeed:
    ...             print("We need more power!")
    ...         else:
    ...             print("Going to warp at speed", speed)
    ...             self.running = True
    ...
    ...     def stop(self):
    ...         self.running = False

    >>> class ConstitutionClassSpaceShip(Layer):
    ...     defaultBases = (SPACE_SHIP,)
    ...
    ...     def setUp(self):
    ...         self['warpDrive'] = WarpDrive(8.0)
    ...
    ...     def tearDown(self):
    ...         del self['warpDrive']

    >>> CONSTITUTION_CLASS_SPACE_SHIP = ConstitutionClassSpaceShip()

    >>> class GalaxyClassSpaceShip(Layer):
    ...     defaultBases = (CONSTITUTION_CLASS_SPACE_SHIP,)
    ...
    ...     def setUp(self):
    ...         # Upgrade the warp drive
    ...         self.previousMaxSpeed = self['warpDrive'].maxSpeed
    ...         self['warpDrive'].maxSpeed = 9.5
    ...
    ...     def tearDown(self):
    ...         # Restore warp drive to its previous speed
    ...         self['warpDrive'].maxSpeed = self.previousMaxSpeed

    >>> GALAXY_CLASS_SPACE_SHIP = GalaxyClassSpaceShip()

As shown, layers (that derive from ``plone.testing.Layer``) support item (dict-like) assignment, access and deletion of arbitrary resources under string keys.

    **Important:** If a layer creates a resource (by assigning an object to a key on ``self`` as shown above) during fixture setup-up, it must also delete the resource on tear-down.
    Set-up and deletion should be symmetric: if the resource is assigned during ``setUp()`` it should be deleted in ``tearDown()``;
    if it's created in ``testSetUp()`` it should be deleted in ``testTearDown()``.

A resource defined in a base layer is accessible from and through a child layer.
If a resource is set on a child using a key that also exists in a base layer, the child version will shadow the base version until the child layer is torn down (presuming it deletes the resource, which it should), but the base layer version remains intact.

.. note::

    Accessing a resource is analogous to accessing an instance variable.
    For example, if a base layer assigns a resource to a given key in its ``setUp()`` method, a child layer shadows that resource with another object under the same key, the shadowed resource will by used during the ``testSetUp()`` and ``testTearDown()`` lifecycle methods if implemented by the *base* layer as well.
    This will be the case until the child layer "pops" the resource by deleting it, normally in its ``tearDown()``.

Conversely, if (as shown above) the child layer accesses and modifies the object, it will modify the original.

.. note::

   It is sometimes necessary (or desirable) to modify a shared resource in a child layer, as shown in the example above.  In this case, however, it is very important to restore the original state when the layer is torn down.  Otherwise, other layers or tests using the base layer directly may be affected in difficult-to-debug ways.

If the same key is used in multiple base layers, the rules for choosing which version to use are similar to those that apply when choosing an attribute or method to use in the case of multiple inheritance.

In the example above, we used the resource manager for the ``warpDrive`` object, but we assigned the ``previousMaxSpeed`` variable to ``self``.
This is because ``previousMaxSpeed`` is internal to the layer and should not be shared with any other layers that happen to use this layer as a base.
Nor should it be used by any test cases.
Conversely, ``warpDrive`` is a shared resource that is exposed to other layers and test cases.

The distinction becomes even more important when you consider how a test case may access the shared resource.
We'll discuss how to write test cases that use layers shortly, but consider the following test:::

    >>> import unittest
    >>> class TestFasterThanLightTravel(unittest.TestCase):
    ...     layer = GALAXY_CLASS_SPACE_SHIP
    ...
    ...     def test_hyperdrive(self):
    ...         warpDrive = self.layer['warpDrive']
    ...         warpDrive.start(8)

This test needs access to the shared resource.
It knows that its layer defines one called ``warpDrive``.
It does not know or care that the warp drive was actually initiated by the ``ConstitutionClassSpaceShip`` base layer.

If, however, the base layer had assigned the resource as an instance variable, it would not inherit to child layers (remember: layer bases are not base classes!).
The syntax to access it would be:::

    self.layer.__bases__[0].warpDrive

which is not only ugly, but brittle: if the list of bases is changed, the expression above may lead to an attribute error.

Writing tests
=============

Tests are usually written in one of two ways: As methods on a class that derives from ``unittest.TestCase`` (this is sometimes known as "Python tests" or "JUnit-style tests"), or using doctest syntax.

You should realise that although the relevant frameworks (``unittest`` and ``doctest``) often talk about unit testing, these tools are also used to write integration and functional tests.
The distinction between unit, integration and functional tests is largely practical: you use the same techniques to set up a fixture or write assertions for an integration test as you would for a unit test.
The difference lies in what that fixture contains, and how you invoke the code under test.
In general, a true unit test will have a minimal or no test fixture, whereas an integration test will have a fixture that contains the components your code is integrating with.
A functional test will have a fixture that contains enough of the full system to execute and test an "end-to-end" scenario.

Python tests
------------

Python tests use the Python `unittest`_ module.
They should be placed in a module or package called ``tests`` for the test runner to pick them up.

For small packages, a single module called ``tests.py`` will normally contain all tests.
For larger packages, it is common to have a ``tests`` package that contains a number of modules with tests.
These need to start with the word ``test``, e.g.
``tests/test_foo.py`` or ``tests/test_bar.py``.
Don't forget the ``__init__.py`` in the ``tests`` package, too!

unittest
~~~~~~~~

Please note that the `zope.testing`_ test runner at the time of writing (version 4.6.2) does not (yet) support the new ``setUpClass()``, ``tearDownClass()``, ``setUpModule()`` and ``tearDownModule()`` hooks from ``unittest``.
This is not normally a problem, since we tend to use layers to manage complex fixtures, but it is important to be aware of nonetheless.

Test modules, classes and functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Python tests are written with classes that derive from the base class ``TestCase``.
Each test is written as a method that takes no arguments and has a name starting with ``test``.
Other methods can be added and called from test methods as appropriate, e.g.
to share some test logic.

Two special methods, ``setUp()`` and ``tearDown()``, can also be added.
These will be called before or after each test, respectively, and provide a useful place to construct and clean up test fixtures without writing a custom layer.
They are obviously not as reusable as layers, though.

   *Hint:* Somewhat confusingly, the ``setUp()`` and ``tearDown()`` methods in a test case class are the equivalent of the ``testSetUp()`` and ``testTearDown()`` methods of a layer class.

A layer can be specified by setting the ``layer`` class attribute to a layer instance.
If layers are used in conjunction with ``setUp()`` and ``tearDown()`` methods in the test class itself, the class' ``setUp()`` method will be called after the layer's ``testSetUp()`` method, and the class' ``tearDown()`` method will be called before the layer's ``testTearDown()`` method.

The ``TestCase`` base class contains a number of methods which can be used to write assertions.
They all take the form ``self.assertSomething()``, e.g.
``self.assertEqual(result, expectedValue)``.
See the `unittest`_ documentation for details.

Putting this together, let's expand on our previous example unit test:::

    >>> import unittest

    >>> class TestFasterThanLightTravel(unittest.TestCase):
    ...     layer = GALAXY_CLASS_SPACE_SHIP
    ...
    ...     def setUp(self):
    ...         self.warpDrive = self.layer['warpDrive']
    ...         self.warpDrive.stop()
    ...
    ...     def tearDown(self):
    ...         self.warpDrive.stop()
    ...
    ...     def test_warp8(self):
    ...         self.warpDrive.start(8)
    ...         self.assertEqual(self.warpDrive.running, True)
    ...
    ...     def test_max_speed(self):
    ...         tooFast = self.warpDrive.maxSpeed + 0.1
    ...         self.warpDrive.start(tooFast)
    ...         self.assertEqual(self.warpDrive.running, False)

A few things to note:

* The class derives from ``unittest.TestCase``.

* The ``layer`` class attribute is set to a layer instance (not a layer class!) defined previously.
  This would typically be imported from a ``testing`` module.

* There are two tests here: ``test_warp8()`` and ``test_max_speed()``.

* We have used the ``self.assertEqual()`` assertion in both tests to check the result of executing the ``start()`` method on the warp drive.

* We have used the ``setUp()`` method to fetch the ``warpDrive`` resource and ensure that it is stopped before each test is executed.
  Assigning a variable to ``self`` is a useful way to provide some state to each test method, though be careful about data leaking between tests: in general, you cannot predict the order in which tests will run, and tests should always be independent.

* We have used the ``tearDown()`` method to make sure the warp drive is really stopped after each test.

Test suites
~~~~~~~~~~~

A class like the one above is all you need: any class deriving from ``TestCase`` in a module with a name starting with ``test`` will be examined for test methods.
Those tests are then collected into a test suite and executed.

See the `unittest`_ documentation for other options.

Doctests
--------

Doctests can be written in two ways: as the contents of a docstring (usually, but not always, as a means of illustrating and testing the functionality of the method or class where the docstring appears), or as a separate text file.
In both cases, the standard `doctest`_ module is used.
See its documentation for details about doctest syntax and conventions.

Doctests are used in two different ways:

* To test documentation.
  That is, to ensure that code examples contained in documentation are valid and continue to work as the software is updated.

* As a convenient syntax for writing tests.

These two approaches use the same testing APIs and techniques.
The difference is mostly about mindset.
However, it is important to avoid falling into the trap that tests can substitute for good documentation or vice-a-versa.
Tests usually need to systematically go through inputs and outputs and cover off a number of corner cases.
Documentation should tell a compelling narrative and usually focus on the main usage scenarios.
Trying to kill these two birds with one stone normally leaves you with an unappealing pile of stones and feathers.

Docstring doctests
~~~~~~~~~~~~~~~~~~

Doctests can be added to any module, class or function docstring:::

    def canOutrunKlingons(warpDrive):
        """Find out of the given warp drive can outrun Klingons.

        Klingons travel at warp 8

        >>> drive = WarpDrive(5)
        >>> canOutrunKlingons(drive)
        False

        We have to be faster than that to outrun them.

        >>> drive = WarpDrive(8.1)
        >>> canOutrunKlingons(drive)
        True

        We can't outrun them if we're travelling exactly the same speed

        >>> drive = WarpDrive(8.0)
        >>> canOutrunKlingons(drive)
        False

        """
        return warpDrive.maxSpeed > 8.0

To add the doctests from a particular module to a test suite, you need to use the ``test_suite()`` function hook:::

    >>> import doctest
    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         unittest.makeSuite(TestFasterThanLightTravel), # our previous test
    ...         doctest.DocTestSuite('spaceship.utils'),
    ...     ])
    ...     return suite

Here, we have given the name of the module to check as a string dotted name.
It is also possible to import a module and pass it as an object.
The code above passes a list to ``addTests()``, making it easy to add several sets of tests to the suite: the list can be constructed from calls to ``DocTestSuite()``, ``DocFileSuite()`` (shown below) and ``makeSuite()`` (shown above).

    Remember that if you add a ``test_suite()`` function to a module that also has ``TestCase``-derived python tests, those tests will no longer be automatically picked up by ``zope.testing``, so you need to add them to the test suite explicitly.

The example above illustrates a documentation-oriented doctest, where the doctest forms part of the docstring of a public module.
The same syntax can be used for more systematic unit tests.
For example, we could have a module ``spaceship.tests.test_spaceship`` with a set of methods like::

    # It's often better to put the import into each method, but here we've
    # imported the code under test at module level
    from spaceship.utils import WarpDrive, canOutrunKlingons

    def test_canOutrunKlingons_too_small():
        """Klingons travel at warp 8.0

        >>> drive = WarpDrive(7.9)
        >>> canOutrunKlingons(drive)
        False

        """

    def test_canOutrunKlingons_big():
        """Klingons travel at warp 8.0

        >>> drive = WarpDrive(8.1)
        >>> canOutrunKlingons(drive)
        True

        """

    def test_canOutrunKlingons_must_be_greater():
        """Klingons travel at warp 8.0

        >>> drive = WarpDrive(8.0)
        >>> canOutrunKlingons(drive)
        False

        """

Here, we have created a number of small methods that have no body.
They merely serve as a container for docstrings with doctests.
Since the module has no globals, each test must import the code under test, which helps make import errors more explicit.

File doctests
~~~~~~~~~~~~~

Doctests contained in a file are similar to those contained in docstrings.
File doctests are better suited to narrative documentation covering the usage of an entire module or package.

For example, if we had a file called ``spaceship.txt`` with doctests, we could add it to the test suite above with:::

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         unittest.makeSuite(TestFasterThanLightTravel),
    ...         doctest.DocTestSuite('spaceship.utils'),
    ...         doctest.DocFileSuite('spaceship.txt'),
    ...     ])
    ...     return suite

By default, the file is located relative to the module where the test suite is defined.
You can use ``../`` (even on Windows) to reference the parent directory, which is sometimes useful if the doctest is inside a module in a ``tests`` package.

.. note::

    If you put the doctest ``test_suite()`` method in a module inside a ``tests`` package, that module must have a name starting with ``test``.
    It is common to have ``tests/test_doctests.py`` that contains a single ``test_suite()`` method that returns a suite of multiple doctests.

It is possible to pass several tests to the suite, e.g.::

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         unittest.makeSuite(TestFasterThanLightTravel),
    ...         doctest.DocTestSuite('spaceship.utils'),
    ...         doctest.DocFileSuite('spaceship.txt', 'warpdrive.txt',),
    ...     ])
    ...     return suite

The test runner will report each file as a separate test, i.e.
the ``DocFileSuite()`` above would add two tests to the overall suite.
Conversely, a ``DocTestSuite()`` using a module with more than one docstring containing doctests will report one test for each eligible docstring.

Doctest fixtures and layers
~~~~~~~~~~~~~~~~~~~~~~~~~~~

A docstring doctest will by default have access to any global symbol available in the module where the docstring is found (e.g.
anything defined or imported in the module).
The global namespace can be overridden by passing a ``globs`` keyword argument to the ``DocTestSuite()`` constructor, or augmented by passing an ``extraglobs`` argument.
Both should be given dictionaries.

A file doctest has an empty globals namespace by default.
Globals may be provided via the ``globs`` argument to ``DocFileSuite()``.

To manage a simple test fixture for a doctest, you can define set-up and tear-down functions and pass them as the ``setUp`` and ``tearDown`` arguments respectively.
These are both passed a single argument, a ``DocTest`` object.
The most useful attribute of this object is ``globs``, which is a mutable dictionary of globals available in the test.

For example:::

    >>> def setUpKlingons(doctest):
    ...     doctest.globs['oldStyleKlingons'] = True

    >>> def tearDownKlingons(doctest):
    ...     doctest.globs['oldStyleKlingons'] = False

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         doctest.DocTestSuite('spaceship.utils', setUp=setUpKlingons, tearDown=tearDownKlingons),
    ...     ])
    ...     return suite

The same arguments are available on the ``DocFileSuite()`` constructor.
The set up method is called before each docstring in the given module for a ``DocTestSuite``, and before each file given in a ``DocFileSuite``.

Of course, we often want to use layers with doctests too.
Unfortunately, the ``unittest`` API is not aware of layers, so you can't just pass a layer to the ``DocTestSuite()`` and ``DocFileSuite()`` constructors.
Instead, you have to set a ``layer`` attribute on the suite after it has been constructed.

Furthermore, to use layer resources in a doctest, we need access to the layer instance.
The easiest way to do this is to pass it as a glob, conventionally called 'layer'.
This makes a global name 'layer' available in the doctest itself, giving access to the test's layer instance.

To make it easier to do this, ``plone.testing`` comes with a helper function called ``layered()``.
Its first argument is a test suite.
The second argument is the layer.

For example:::

    >>> from plone.testing import layered
    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         layered(doctest.DocTestSuite('spaceship.utils'), layer=CONSTITUTION_CLASS_SPACE_SHIP),
    ...     ])
    ...     return suite

This is equivalent to:::

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...
    ...     spaceshipUtilTests = doctest.DocTestSuite('spaceship.utils', globs={'layer': CONSTITUTION_CLASS_SPACE_SHIP})
    ...     spaceshipUtilTests.layer = CONSTITUTION_CLASS_SPACE_SHIP
    ...     suite.addTest(spaceshipUtilTests)
    ...
    ...     return suite

(In this example, we've opted to use ``addTest()`` to add a single suite, instead of using ``addTests()`` to add multiple suites in one go).

Zope testing tools
==================

Everything described so far in this document relies only on the standard `unittest`_ and `doctest`_ modules and `zope.testing`_, and you can use this package without any other dependencies.

However, there are also some tools (and layers) available in this package, as well as in other packages, that are specifically useful for testing applications that use various Zope-related frameworks.

Test cleanup
------------

If a test uses a global registry, it may be necessary to clean that registry on set up and tear down of each test fixture.
``zope.testing`` provides a mechanism to register cleanup handlers - methods that are called to clean up global state.
This can then be invoked in the ``setUp()`` and ``tearDown()`` fixture lifecycle methods of a test case.::

    >>> from zope.testing import cleanup

Let's say we had a global registry, implemented as a dictionary:::

    >>> SOME_GLOBAL_REGISTRY = {}

If we wanted to clean this up on each test run, we could call ``clear()`` on the dict.
Since that's a no-argument method, it is perfect as a cleanup handler.::

    >>> cleanup.addCleanUp(SOME_GLOBAL_REGISTRY.clear)

We can now use the ``cleanUp()`` method to execute all registered cleanups:::

    >>> cleanup.cleanUp()

This call could be placed in a ``setUp()`` and/or ``tearDown()`` method in a test class, for example.

Event testing
-------------

You may wish to test some code that uses ``zope.event`` to fire specific events.
`zope.component`_ provides some helpers to capture and analyse events.::

    >>> from zope.component import eventtesting

To use this, you first need to set up event testing.
Some of the layers shown below will do this for you, but you can do it yourself by calling the ``eventtesting.setUp()`` method, e.g.
from your own ``setUp()`` method:::

    >>> eventtesting.setUp()

This simply registers a few catch-all event handlers.
Once you have executed the code that is expected to fire events, you can use the ``getEvents()`` helper function to obtain a list of the event instances caught:::

    >>> events = eventtesting.getEvents()

You can now examine ``events`` to see what events have been caught since the last cleanup.

``getEvents()`` takes two optional arguments that can be used to filter the returned list of events.
The first (``event_type``) is an interface.
If given, only events providing this interface are returned.
The second (``filter``) is a callable taking one argument.
If given, it will be called with each captured event.
Only those events where the filter function returns ``True`` will be included.

The ``eventtesting`` module registers a cleanup action as outlined above.
When you call ``cleanup.cleanUp()`` (or ``eventtesting.clearEvents()``, which is the handler it registers), the events list will be cleared, ready for the next test.
Here, we'll do it manually:::

    >>> eventtesting.clearEvents()

Mock requests
-------------

Many tests require a request object, often with particular request/form variables set.
`zope.publisher`_ contains a useful class for this purpose.::

    >>> from zope.publisher.browser import TestRequest

A simple test request can be constructed with no arguments:::

    >>> request = TestRequest()

To add a body input stream, pass a ``StringIO`` or file as the first parameter.
To set the environment (request headers), use the ``environ`` keyword argument.
To simulate a submitted form, use the ``form`` keyword argument:::

    >>> request = TestRequest(form=dict(field1='foo', field2=1))

Note that the ``form`` dict contains marshalled form fields, so modifiers like ``:int`` or ``:boolean`` should not be included in the field names, and values should be converted to the appropriate type.

Registering components
----------------------

Many test fixtures will depend on having a minimum of Zope Component Architecture (ZCA) components registered.
In normal operation, these would probably be registered via ZCML, but in a unit test, you should avoid loading the full ZCML configuration of your package (and its dependencies).

Instead, you can use the Python API in `zope.component`_ to register global components instantly.
The three most commonly used functions are:::

    >>> from zope.component import provideAdapter
    >>> from zope.component import provideUtility
    >>> from zope.component import provideHandler

See the `zope.component`_ documentation for details about how to use these.

When registering global components like this, it is important to avoid test leakage.
The ``cleanup`` mechanism outlined above can be used to tear down the component registry between each test.
See also the ``plone.testing.zca.UNIT_TESTING`` layer, described below, which performs this cleanup automatically via the ``testSetUp()``/``testTearDown()`` mechanism.

Alternatively, you can "stack" a new global component registry using the ``plone.testing.zca.pushGlobalRegistry()`` and ``plone.testing.zca.popGlobalRegistry()`` helpers.
This makes it possible to set up and tear down components that are specific to a given layer, and even allow tests to safely call the global component API (or load ZCML - see below) with proper tear-down.
See the layer reference below for details.

Loading ZCML
------------

Integration tests often need to load ZCML configuration.
This can be achieved using the ``zope.configuration`` API.::

    >>> from zope.configuration import xmlconfig

The ``xmlconfig`` module contains two methods for loading ZCML.

``xmlconfig.string()`` can be used to load a literal string of ZCML:::

    >>> xmlconfig.string("""\
    ... <configure xmlns="http://namespaces.zope.org/zope" package="plone.testing">
    ...     <include package="zope.component" file="meta.zcml" />
    ... </configure>
    ... """)
    <zope.configuration.config.ConfigurationMachine object at ...>

Note that we need to set a package (used for relative imports and file locations) explicitly here, using the ``package`` attribute of the ``<configure />`` element.

Also note that unless the optional second argument (``context``) is passed, a new configuration machine will be created every time ``string()`` is called.
It therefore becomes necessary to explicitly ``<include />`` the files that contain the directives you want to use (the one in ``zope.component`` is a common example).
Layers that set up ZCML configuration may expose a resource which can be passed as the ``context`` parameter, usually called ``configurationContext`` - see below.

To load the configuration for a particular package, use ``xmlconfig.file()``:::

    >>> import zope.component
    >>> context = xmlconfig.file('meta.zcml', zope.component)
    >>> xmlconfig.file('configure.zcml', zope.component, context=context)
    <zope.configuration.config.ConfigurationMachine object at ...>

This takes two required arguments: the file name and the module relative to which it is to be found.
Here, we have loaded two files: ``meta.zcml`` and ``configure.zcml``.
The first call to ``xmlconfig.file()`` creates and returns a configuration context.
We reuse that for the subsequent invocation, so that the directives configured are available.

Installing a Zope product
-------------------------

Some packages (including all those in the ``Products.*`` namespace) have the special status of being Zope "products".
These are recorded in a special registry, and may have an ``initialize()`` hook in their top-level ``__init__.py`` that needs to be called for the package to be fully configured.

Zope 2 will find and execute any products during startup.
For testing, we need to explicitly list the products to install.
Provided you are using ``plone.testing`` with Zope, you can use the following:::

    from plone.testing import zope

    with zope.zopeApp() as app:
        zope.installProduct(app, 'Products.ZCatalog')

This would normally be used during layer ``setUp()``.
Note that the basic Zope application context must have been set up before doing this.
The usual way to ensure this, is to use a layer that is based on ``zope.STARTUP`` - see below.

To tear down such a layer, you should do:::

    from plone.testing import zope

    with zope.zopeApp() as app:
        zope.uninstallProduct(app, 'Products.ZCatalog')

Note:

* Unlike the similarly-named function from ``ZopeTestCase``, these helpers will work with any type of product.
  There is no distinction between a "product" and a "package" (and no ``installPackage()``).
  However, you must use the full name (``Products.*``) when registering a product.

* Installing a product in this manner is independent of ZCML configuration.
  However, it is almost always necessary to install the package's ZCML configuration first.

Functional testing
------------------

For functional tests that aim to simulate the browser, you can use `zope.testbrowser`_ in a Python test or doctest:::

    >>> from zope.testbrowser.browser import Browser
    >>> browser = Browser()

This provides a simple API to simulate browser input, without actually running a web server thread or scripting a live browser (as tools such as Selenium_ do).
The downside is that it is not possible to test JavaScript- dependent behaviour.

If you are testing a Zope application, you need to change the import location slightly, and pass the application root to the method:::

    from plone.testing.zope import Browser
    browser = Browser(app)

You can get the application root from the ``app`` resource in any of the Zope layers in this package.

Beyond that, the `zope.testbrowser`_ documentation should cover how to use the test browser.

    **Hint:** The test browser will usually commit at the end of a request.
    To avoid test fixture contamination, you should use a layer that fully isolates each test, such as the ``zope.INTEGRATION_TESTING`` layer described below.

Layer reference
===============

``plone.testing`` comes with several layers that are available to use directly or extend.
These are outlined below.

Zope Component Architecture
---------------------------

The Zope Component Architecture layers are found in the module ``plone.testing.zca``.
If you depend on this, you can use the ``[zca]`` extra when depending on ``plone.testing``.

Unit testing
~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zca.UNIT_TESTING``               |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zca.UnitTesting``                |
+------------+--------------------------------------------------+
| Bases:     | None                                             |
+------------+--------------------------------------------------+
| Resources: | None                                             |
+------------+--------------------------------------------------+

This layer does not set up a fixture per se, but cleans up global state before and after each test, using ``zope.testing.cleanup`` as described above.

The net result is that each test has a clean global component registry.
Thus, it is safe to use the `zope.component`_ Python API (``provideAdapter()``, ``provideUtility()``, ``provideHandler()`` and so on) to register components.

Be careful with using this layer in combination with other layers.
Because it tears down the component registry between each test, it will clobber any layer that sets up more permanent test fixture in the component registry.

Event testing
~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zca.EVENT_TESTING``              |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zca.EventTesting``               |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zca.UNIT_TESTING``               |
+------------+--------------------------------------------------+
| Resources: | None                                             |
+------------+--------------------------------------------------+

This layer extends the ``zca.UNIT_TESTING`` layer to enable the ``eventtesting`` support from ``zope.component``.
Using this layer, you can import and use ``zope.component.eventtesting.getEvent`` to inspect events fired by the code under test.

See above for details.

Layer cleanup
~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zca.LAYER_CLEANUP``              |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zca.LayerCleanup``               |
+------------+--------------------------------------------------+
| Bases:     | None                                             |
+------------+--------------------------------------------------+
| Resources: | None                                             |
+------------+--------------------------------------------------+

This layer calls the cleanup functions from ``zope.testing.cleanup`` on setup and tear-down (but not between each test).
It is useful as a base layer for other layers that need an environment as pristine as possible.

Basic ZCML directives
~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zca.ZCML_DIRECTIVES``            |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zca.ZCMLDirectives``             |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |
+------------+--------------------------------------------------+
| Resources: | ``configurationContext``                         |
+------------+--------------------------------------------------+

This registers a minimal set of ZCML directives, principally those found in the ``zope.component`` package, and makes available a configuration context.
This allows custom ZCML to be loaded as described above.

The ``configurationContext`` resource should be used when loading custom ZCML.
To ensure isolation, you should stack this using the ``stackConfigurationContext()`` helper.
For example, if you were writing a ``setUp()`` method in a layer that had ``zca.ZCML_DIRECTIVES`` as a base, you could do:::

    self['configurationContext'] = context = zca.stackConfigurationContext(self.get('configurationContext'))
    xmlconfig.string(someZCMLString, context=context)

This will create a new configuration context with the state of the base layer's context.
On tear-down, you should delete the layer-specific resource:::

    del self['configurationContext']

.. note::

   If you fail to do this, you may get problems if your layer is torn down and then needs to be set up again later.

See above for more details about loading custom ZCML in a layer or test.

ZCML files helper class
~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zca.ZCMLSandbox``                |
+------------+--------------------------------------------------+
| Resources: | ``configurationContext``                         |
+------------+--------------------------------------------------+

The ``ZCMLSandbox`` can be instantiated with a ``filename`` and ``package`` arguments::

    ZCML_SANDBOX = zca.ZCMLSandbox(filename="configure.zcml",
        package=my.package)


That layer ``setUp`` loads the ZCML file.
It avoids the need to using (and understand) ``configurationContext`` and ``globalRegistry`` until you need more flexibility or modularity for your layer and tests.

See above for more details about loading custom ZCML in a layer or test.

Helper functions
~~~~~~~~~~~~~~~~

The following helper functions are available in the ``plone.testing.zca`` module.

``stackConfigurationContext(context=None)``

    Create and return a copy of the passed-in ZCML configuration context, or a brand new context if it is ``None``.

    The purpose of this is to ensure that if a layer loads some ZCML files (using the ``zope.configuration`` API during) during its ``setUp()``, the state of the configuration registry (which includes registered directives as well as a list of already imported files, which will not be loaded again even if explicitly included) can be torn down during ``tearDown()``.

    The usual pattern is to keep the configuration context in a layer resource called ``configurationContext``.
    In ``setUp()``, you would then use::

        self['configurationContext'] = context = zca.stackConfigurationContext(self.get('configurationContext'))

        # use 'context' to load some ZCML

    In ``tearDown()``, you can then simply do::

        del self['configurationContext']

``pushGlobalRegistry(new=None)``

    Create or obtain a stack of global component registries, and push a new registry to the top of the stack.
    The net result is that ``zope.component.getGlobalSiteManager()`` and (an un-hooked) ``getSiteManager()`` will return the new registry instead of the default, module-scope one.
    From this point onwards, calls to ``provideAdapter()``, ``provideUtility()`` and other functions that modify the global registry will use the new registry.

    If ``new`` is not given, a new registry is created that has the previous global registry (site manager) as its sole base.
    This has the effect that registrations in the previous default global registry are still available, but new registrations are confined to the new registry.

    **Warning**: If you call this function, you *must* reciprocally call ``popGlobalRegistry()``.
    That is, if you "push" a registry during layer ``setUp()``, you must "pop" it during ``tearDown()``.
    If you "push" during ``testSetUp()``, you must "pop" during ``testTearDown()``.
    If the calls to push and pop are not balanced, you will leave your global registry in a mess, which is not pretty.

    Returns the new default global site manager.
    Also causes the site manager hook from ``zope.component.hooks`` to be reset, clearing any local site managers as appropriate.

``popGlobalRegistry()``

    Pop the global site registry, restoring the previous registry to be the default.

    Please heed the warning above: push and pop must be balanced.

    Returns the new default global site manager.
    Also causes the site manager hook from ``zope.component.hooks`` to be reset, clearing any local site managers as appropriate.

Zope Security
-------------

The Zope Security layers build can be found in the module ``plone.testing.security``.

If you depend on this, you can use the ``[security]`` extra when depending on ``plone.testing``.

Security checker isolation
~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.security.CHECKERS``              |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.security.Checkers``              |
+------------+--------------------------------------------------+
| Bases:     | None                                             |
+------------+--------------------------------------------------+
| Resources: | None                                             |
+------------+--------------------------------------------------+

This layer ensures that security checkers used by ``zope.security`` are isolated.
Any checkers set up in a child layer will be removed cleanly during tear-down.

Helper functions
~~~~~~~~~~~~~~~~

The security checker isolation outlined above is managed using two helper functions found in the module ``plone.testing.security``:

``pushCheckers()``

    Copy the current set of security checkers for later tear-down.

``popCheckers()``

    Restore the set of security checkers to the state of the most recent call to ``pushCheckers()``.

You *must* keep calls to ``pushCheckers()`` and ``popCheckers()`` in balance.
That usually means that if you call the former during layer setup, you should call the latter during layer tear-down.
Ditto for calls during test setup/tear-down or within tests themselves.

Zope Publisher
--------------

The Zope Publisher layers build on the Zope Component Architecture layers.
They can be found in the module ``plone.testing.publisher``.

If you depend on this, you can use the ``[publisher]`` extra when depending on ``plone.testing``.

Publisher directives
~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.publisher.PUBLISHER_DIRECTIVES`` |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.publisher.PublisherDirectives``  |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zca.ZCML_DIRECTIVES``            |
+------------+--------------------------------------------------+
| Resources: | None                                             |
+------------+--------------------------------------------------+

This layer extends the ``zca.ZCML_DIRECTIVES`` layer to install additional ZCML directives in the ``browser`` namespace (from ``zope.app.publisher.browser``) as well as those from ``zope.security``.
This allows browser views, browser pages and other UI components to be registered, as well as the definition of new permissions.

As with ``zca.ZCML_DIRECTIVES``, you should use the ``configurationContext`` resource when loading ZCML strings or files, and the ``stackConfigurationRegistry()`` helper to create a layer-specific version of this resource resource.
See above.

ZODB
----

The ZODB layers set up a test fixture with a persistent ZODB.
The ZODB instance uses ``DemoStorage``, so it will not interfere with any "live" data.

ZODB layers can be found in the module ``plone.testing.zodb``.
If you depend on this, you can use the ``[zodb]`` extra when depending on ``plone.testing``.

Empty ZODB sandbox
~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zodb.EMPTY_ZODB``                |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zodb.EmptyZODB``                 |
+------------+--------------------------------------------------+
| Bases:     |  None                                            |
+------------+--------------------------------------------------+
| Resources: | ``zodbRoot``                                     |
|            +--------------------------------------------------+
|            | ``zodbDB`` (test set-up only)                    |
|            +--------------------------------------------------+
|            | ``zodbConnection`` (test set-up only)            |
+------------+--------------------------------------------------+

This layer sets up a simple ZODB sandbox using ``DemoStorage``.
The ZODB root object is a simple persistent mapping, available as the resource ``zodbRoot``.
The ZODB database object is available as the resource ``zodbDB``.
The connection used in the test is available as ``zodbConnection``.

Note that the ``zodbConnection`` and ``zodbRoot`` resources are created and destroyed for each test.
You can use ``zodbDB`` (and the ``open()`` method) if you are writing a layer based on this one and need to set up a fixture during layer set up.
Don't forget to close the connection before concluding the test setup!

A new transaction is begun for each test, and rolled back (aborted) on test tear-down.
This means that so long as you don't use ``transaction.commit()`` explicitly in your code, it should be safe to add or modify items in the ZODB root.

If you want to create a test fixture with persistent data in your own layer based on ``EMPTY_ZODB``, you can use the following pattern::

    from plone.layer import Layer
    from plone.layer import zodb

    class MyLayer(Layer):
        defaultBases = (zodb.EMPTY_ZODB,)

        def setUp(self):

            import transaction
            self['zodbDB'] = db = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')

            conn = db.open()
            root = conn.root()

            # modify the root object here

            transaction.commit()
            conn.close()

        def tearDown(self):

            self['zodbDB'].close()
            del self['zodbDB']

This shadows the ``zodbDB`` resource with a new database that uses a new ``DemoStorage`` stacked on top of the underlying database storage.
The fixture is added to this storage and committed during layer setup.
(The base layer test set-up/tear-down will still begin and abort a new transaction for each *test*).
On layer tear-down, the database is closed and the resource popped, leaving the original ``zodbDB`` database with the original, pristine storage.

Helper functions
~~~~~~~~~~~~~~~~

One helper function is available in the ``plone.testing.zodb`` module.

``stackDemoStorage(db=None, name=None)``

Create a new ``DemoStorage`` using the storage from the passed-in database as a base.
If ``db`` is None, a brand new storage is created.

A ``name`` can be given to uniquely identify the storage.
It is optional, but it is often useful for debugging purposes to pass the name of the layer.

The usual pattern is::

    def setUp(self):
        self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')

    def tearDown(self):
        self['zodbDB'].close()
        del self['zodbDB']

This will shadow the ``zodbDB`` resource with an isolated ``DemoStorage``, creating a new one if that resource does not already exist.
All existing data continues to be available, but new changes are written to the stacked storage.
On tear-down, the stacked database is closed and the resource removed, leaving the original data.

Zope
----

The Zope layers provide test fixtures suitable for testing Zope applications.
They set up a Zope application root, install core Zope products, and manage security.

Zope layers can be found in the module ``plone.testing.zope``.
If you depend on this, you can use the ``[zope]`` extra when depending on ``plone.testing``.

Startup
~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zope.STARTUP``                   |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zope.Startup``                   |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |
+------------+--------------------------------------------------+
| Resources: | ``zodbDB``                                       |
|            +--------------------------------------------------+
|            | ``configurationContext``                         |
|            +--------------------------------------------------+
|            | ``host``                                         |
|            +--------------------------------------------------+
|            | ``port``                                         |
+------------+--------------------------------------------------+

This layer sets up a Zope environment, and is a required base for all other Zope layers.
You cannot run two instances of this layer in parallel, since Zope depends on some module-global state to run, which is managed by this layer.

On set-up, the layer will configure a Zope environment with:

.. note::

    The ``STARTUP`` layer is a useful base layer for your own fixtures, but should not be used directly, since it provides no test lifecycle or transaction management.
    See the "Integration test" and "Functional" test sections below for examples of how to create your own layers.

* Debug mode enabled.

* ZEO client cache disabled.

* Some patches installed, which speed up Zope startup by disabling some superfluous aspects of Zope.

* One thread (this only really affects the ``WSGI_SERVER``, ``ZSERVER`` and ``FTP_SERVER`` layers).

* A pristine database using ``DemoStorage``, exposed as the resource ``zodbDB``.
  Zope is configured to use this database in a way that will also work if the ``zodbDB`` resource is shadowed using the pattern shown above in the description of the ``zodb.EMPTY_ZODB`` layer.

* A fake hostname and port, exposed as the ``host`` and ``port`` resource, respectively.

* A minimal set of products installed (``Products.OFSP`` and ``Products.PluginIndexes``, both required for Zope to start up).

* A stacked ZCML configuration context, exposed as the resource ``configurationContext``.
  As illustrated above, you should use the ``zca.stackConfigurationContext()`` helper to stack your own configuration context if you use this.

* A minimal set of global Zope components configured.

Note that unlike a "real" Zope site, products in the ``Products.*`` namespace are not automatically loaded, nor is any ZCML.

Integration test
~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zope.INTEGRATION_TESTING``       |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zope.IntegrationTesting``        |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zope.STARTUP``                   |
+------------+--------------------------------------------------+
| Resources: | ``app``                                          |
|            +--------------------------------------------------+
|            | ``request``                                      |
+------------+--------------------------------------------------+

This layer is intended for integration testing against the simple ``STARTUP`` fixture.
If you want to create your own layer with a more advanced, shared fixture, see "Integration and functional testing with custom fixtures" below.

For each test, it exposes the Zope application root as the resource ``app``.
This is wrapped in the request container, so you can do ``app.REQUEST`` to acquire a fake request, but the request is also available as the resource ``request``.

A new transaction is begun for each test and rolled back on test tear-down, meaning that so long as the code under test does not explicitly commit any changes, the test may modify the ZODB.

    *Hint:* If you want to set up a persistent test fixture in a layer based on this one (or ``zope.FUNCTIONAL_TESTING``), you can stack a new ``DemoStorage`` in a shadowing ``zodbDB`` resource, using the pattern described above for the ``zodb.EMPTY_ZODB`` layer.

    Once you've shadowed the ``zodbDB`` resource, you can do (e.g. in your layer's ``setUp()`` method)::

        ...
        with zope.zopeApp() as app:
            # modify the Zope application root

    The ``zopeApp()`` context manager will open a new connection to the Zope application root, accessible here as ``app``.
    Provided the code within the ``with`` block does not raise an exception, the transaction will be committed and the database closed properly upon exiting the block.

Functional testing
~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zope.FUNCTIONAL_TESTING``        |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zope.FunctionalTesting``         |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zope.STARTUP``                   |
+------------+--------------------------------------------------+
| Resources: | ``app``                                          |
|            +--------------------------------------------------+
|            | ``request``                                      |
+------------+--------------------------------------------------+

This layer is intended for functional testing against the simple ``STARTUP`` fixture.
If you want to create your own layer with a more advanced, shared fixture, see "Integration and functional testing with custom fixtures" below.

As its name implies, this layer is intended mainly for functional end-to-end testing using tools like `zope.testbrowser`_.
See also the ``Browser`` object as described under "Helper functions" below.

This layer is very similar to ``INTEGRATION_TESTING``, but is not based on it.
It sets up the same fixture and exposes the same resources.
However, instead of using a simple transaction abort to isolate the ZODB between tests, it uses a stacked ``DemoStorage`` for each test.
This is slower, but allows test code to perform and explicit commit, as will usually happen in a functional test.

Integration and functional testing with custom fixtures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to extend the ``STARTUP`` fixture for use with integration or functional testing, you should use the following pattern:

* Create a layer class and a "fixture" base layer instance that has ``zope.STARTUP`` (or some intermediary layer, such as ``zope.WSGI_SERVER_FIXTURE``, shown below) as a base.

* Create "end user" layers by instantiating the ``zope.IntegrationTesting`` and/or ``FunctionalTesting`` classes with this new "fixture" layer as a base.

This allows the same fixture to be used regardless of the "style" of testing, minimising the amount of set-up and tear-down.
The "fixture" layers manage the fixture as part of the *layer* lifecycle.
The layer class (``IntegrationTesting`` or ``FunctionalTesting``), manages the *test* lifecycle, and the test lifecycle only.

For example::

    from plone.testing import Layer, zope, zodb

    class MyLayer(Layer):
        defaultBases = (zope.STARTUP,)

        def setUp(self):
            # Set up the fixture here
            ...

        def tearDown(self):
            # Tear down the fixture here
            ...

    MY_FIXTURE = MyLayer()

    MY_INTEGRATION_TESTING = zope.IntegrationTesting(bases=(MY_FIXTURE,), name="MyFixture:Integration")
    MY_FUNCTIONAL_TESTING = zope.FunctionalTesting(bases=(MY_FIXTURE,), name="MyFixture:Functional")

(Note that we need to give an explicit, unique name to the two layers that reuse the ``IntegrationTesting`` and ``FunctionalTesting`` classes.)

In this example, other layers could extend the "MyLayer" fixture by using ``MY_FIXTURE`` as a base.
Tests would use either ``MY_INTEGRATION_TESTING`` or ``MY_FUNCTIONAL_TESTING`` as appropriate.
However, even if both these two layers were used, the fixture in ``MY_FIXTURE`` would only be set up once.

.. note::

    If you implement the ``testSetUp()`` and ``testTearDown()`` test lifecycle methods in your "fixture" layer (e.g. in the the ``MyLayer`` class above), they will execute before the corresponding methods from ``IntegrationTesting`` and ``FunctionalTesting``.
    Hence, they cannot use those layers' resources (``app`` and ``request``).

It may be preferable, therefore, to have your own "test lifecycle" layer classes that subclass ``IntegrationTesting`` and/or ``FunctionalTesting`` and call base class methods as appropriate.
``plone.app.testing`` takes this approach, for example.

HTTP WSGI server thread (fixture only)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zope.WSGI_SERVER_FIXTURE``       |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zope.WSGIServer``                |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zope.STARTUP``                   |
+------------+--------------------------------------------------+
| Resources: | ``host``                                         |
|            +--------------------------------------------------+
|            | ``port``                                         |
+------------+--------------------------------------------------+

This layer extends the ``zope.STARTUP`` layer to start the Zope HTTP WSGI server in a separate thread.
This means the test site can be accessed through a web browser, and can thus be used with tools like `Selenium`_.

.. note::

    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.
    Use the ``WSGI_SERVER`` layer if you want to execute functional tests against this fixture.

The WSGI server's hostname (normally ``localhost``) is available through the resource ``host``, whilst the port it is running on is available through the resource ``port``.

  *Hint:* Whilst the layer is set up, you can actually access the test Zope site through a web browser.
  The default URL will be ``http://localhost:55001``.

HTTP WSGI server functional testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zope.WSGI_SERVER``               |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zope.FunctionalTesting``         |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zope.WSGI_SERVER_FIXTURE``       |
+------------+--------------------------------------------------+
| Resources: |                                                  |
+------------+--------------------------------------------------+

This layer provides the functional testing lifecycle against the fixture set up by the ``zope.WSGI_SERVER_FIXTURE`` layer.

You can use this to run "live" functional tests against a basic Zope site.
You should **not** use it as a base.
Instead, create your own "fixture" layer that extends ``zope.WSGI_SERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.

Helper functions
~~~~~~~~~~~~~~~~

Several helper functions are available in the ``plone.testing.zope`` module.

``zopeApp(db=None, conn=Non, environ=None)``

    This function can be used as a context manager for any code that requires access to the Zope application root.
    By using it in a ``with`` block, the database will be opened, and the application root will be obtained and request-wrapped.
    When exiting the ``with`` block, the transaction will be committed and the database properly closed, unless an exception was raised::

        with zope.zopeApp() as app:
            # do something with app

    If you want to use a specific database or database connection, pass either the ``db`` or ``conn`` arguments.
    If the context manager opened a new connection, it will close it, but it will not close a connection passed with ``conn``.

    To set keys in the (fake) request environment, pass a dictionary of environment values as ``environ``.

    Note that ``zopeApp()`` should *not* normally be used in tests or test set-up/tear-down, because the ``INTEGRATOIN_TEST`` and ``FUNCTIONAL_TESTING`` layers both manage the application root (as the ``app`` resource) and close it for you.
    It is very useful in layer setup, however.

``installProduct(app, product, quiet=False)``

    Install a Zope 2 style product, ensuring that its ``initialize()`` function is called.
    The product name must be the full dotted name, e.g. ``plone.app.portlets`` or ``Products.CMFCore``.
    If ``quiet`` is true, duplicate registrations will be ignored silently, otherwise a message is logged.

    To get hold of the application root, passed as the ``app`` argument, you would normally use the ``zopeApp()`` context manager outlined above.

``uninstallProduct(app, product, quiet=False)``

    This is the reciprocal of ``installProduct()``, normally used during layer tear-down.
    Again, you should use ``zopeApp()`` to obtain the application root.

``login(userFolder, userName)``

    Create a new security manager that simulates being logged in as the given user.
    ``userFolder`` is an ``acl_users`` object, e.g. ``app['acl_users']`` for the root user folder.

``logout()``

    Simulate being the anonymous user by unsetting the security manager.

``setRoles(userFolder, userName, roles)``

    Set the roles of the given user in the given user folder to the given list of roles.

``makeTestRequest()``

    Create a fake Zope request.

``addRequestContainer(app, environ=None)``

    Create a fake request and wrap the given object (normally an application root) in a ``RequestContainer`` with this request.
    This makes acquisition of ``app.REQUEST`` possible.
    To initialise the request environment with non-default values, pass a dictionary as ``environ``.

    .. note::

       This method is rarely used, because both the ``zopeApp()``
       context manager and the layer set-up/tear-down for
       ``zope.INTEGRATION_TESTING`` and ``zope.FUNCTIONAL_TESTING`` will wrap the
       ``app`` object before exposing it.

``Browser(app)``

    Obtain a test browser client, for use with `zope.testbrowser`_.
    You should use this in conjunction with the ``zope.FUNCTIONAL_TESTING`` layer or a derivative.
    You must pass the app root, usually obtained from the ``app`` resource of the layer, e.g.::

        app = self.layer['app']
        browser = zope.Browser(app)

    You can then use ``browser`` as described in the `zope.testbrowser`_ documentation.

    Bear in mind that the test browser runs separately from the test fixture.
    In particular, calls to helpers such as ``login()`` or ``logout()`` do not affect the state that the test browser sees.
    If you want to set up a persistent fixture (e.g. test content), you can do so before creating the test browser, but you will need to explicitly commit your changes, with::

        import transaction
        transaction.commit()


ZServer
-------

The ZServer layers provide test fixtures suitable for testing Zope applications while using ZServer instead of a WSGI server.
They set up a Zope application root, install core Zope products, and manage security.

ZServer layers can be found in the module ``plone.testing.zserver``.
If you depend on this, you can use the ``[zope,zserver]`` extra when depending on ``plone.testing``.

Startup
~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.STARTUP``                |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.Startup``                |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |
+------------+--------------------------------------------------+
| Resources: | ``zodbDB``                                       |
|            +--------------------------------------------------+
|            | ``configurationContext``                         |
|            +--------------------------------------------------+
|            | ``host``                                         |
|            +--------------------------------------------------+
|            | ``port``                                         |
+------------+--------------------------------------------------+

This layer sets up a Zope environment for ZServer, and is a required base for all other ZServer layers.
You cannot run two instances of this layer in parallel, since Zope depends on some module-global state to run, which is managed by this layer.

On set-up, the layer will configure a Zope environment with the same options as ``zope.Startup``, see there.

Integration test
~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.INTEGRATION_TESTING``    |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.IntegrationTesting``     |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.STARTUP``                |
+------------+--------------------------------------------------+
| Resources: | ``app``                                          |
|            +--------------------------------------------------+
|            | ``request``                                      |
+------------+--------------------------------------------------+

This layer is intended for integration testing against the simple ``STARTUP`` fixture.
If you want to create your own layer with a more advanced, shared fixture, see "Integration and functional testing with custom fixtures" below.

For each test, it exposes the Zope application root as the resource ``app``.
This is wrapped in the request container, so you can do ``app.REQUEST`` to acquire a fake request, but the request is also available as the resource ``request``.

A new transaction is begun for each test and rolled back on test tear-down, meaning that so long as the code under test does not explicitly commit any changes, the test may modify the ZODB.

    *Hint:* If you want to set up a persistent test fixture in a layer based on this one (or ``zserver.FUNCTIONAL_TESTING``), you can stack a new ``DemoStorage`` in a shadowing ``zodbDB`` resource, using the pattern described above for the ``zodb.EMPTY_ZODB`` layer.

    Once you've shadowed the ``zodbDB`` resource, you can do (e.g. in your layer's ``setUp()`` method)::

        ...
        with zserver.zopeApp() as app:
            # modify the Zope application root

    The ``zserver.zopeApp()`` context manager will open a new connection to the Zope application root, accessible here as ``app``.
    Provided the code within the ``with`` block does not raise an exception, the transaction will be committed and the database closed properly upon exiting the block.

Functional testing
~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.FUNCTIONAL_TESTING``     |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.FunctionalTesting``      |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.STARTUP``                |
+------------+--------------------------------------------------+
| Resources: | ``app``                                          |
|            +--------------------------------------------------+
|            | ``request``                                      |
+------------+--------------------------------------------------+

It behaves the same as ``zope.FunctionalTesting``, see there.


Integration and functional testing with custom fixtures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to extend the ``STARTUP`` fixture for use with integration or functional testing, you should use the following pattern:

* Create a layer class and a "fixture" base layer instance that has ``zserver.STARTUP`` (or some intermediary layer, such as ``zserver.ZSERVER_FIXTURE`` or ``zserver.FTP_SERVER_FIXTURE``, shown below) as a base.

* Create "end user" layers by instantiating the ``zserver.IntegrationTesting`` and/or ``FunctionalTesting`` classes with this new "fixture" layer as a base.

This allows the same fixture to be used regardless of the "style" of testing, minimising the amount of set-up and tear-down.
The "fixture" layers manage the fixture as part of the *layer* lifecycle.
The layer class (``IntegrationTesting`` or ``FunctionalTesting``), manages the *test* lifecycle, and the test lifecycle only.

For example::

    from plone.testing import Layer, zserver, zodb

    class MyLayer(Layer):
        defaultBases = (zserver.STARTUP,)

        def setUp(self):
            # Set up the fixture here
            ...

        def tearDown(self):
            # Tear down the fixture here
            ...

    MY_FIXTURE = MyLayer()

    MY_INTEGRATION_TESTING = zserver.IntegrationTesting(bases=(MY_FIXTURE,), name="MyFixture:Integration")
    MY_FUNCTIONAL_TESTING = zserver.FunctionalTesting(bases=(MY_FIXTURE,), name="MyFixture:Functional")

(Note that we need to give an explicit, unique name to the two layers that reuse the ``IntegrationTesting`` and ``FunctionalTesting`` classes.)

In this example, other layers could extend the "MyLayer" fixture by using ``MY_FIXTURE`` as a base.
Tests would use either ``MY_INTEGRATION_TESTING`` or ``MY_FUNCTIONAL_TESTING`` as appropriate.
However, even if both these two layers were used, the fixture in ``MY_FIXTURE`` would only be set up once.

.. note::

    If you implement the ``testSetUp()`` and ``testTearDown()`` test lifecycle methods in your "fixture" layer (e.g. in the the ``MyLayer`` class above), they will execute before the corresponding methods from ``IntegrationTesting`` and ``FunctionalTesting``.
    Hence, they cannot use those layers' resources (``app`` and ``request``).

It may be preferable, therefore, to have your own "test lifecycle" layer classes that subclass ``IntegrationTesting`` and/or ``FunctionalTesting`` and call base class methods as appropriate.
``plone.app.testing`` takes this approach, for example.


HTTP ZServer thread (fixture only)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.ZSERVER_FIXTURE``        |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.ZServer``                |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.STARTUP``                |
+------------+--------------------------------------------------+
| Resources: | ``host``                                         |
|            +--------------------------------------------------+
|            | ``port``                                         |
+------------+--------------------------------------------------+

This layer extends the ``zserver.STARTUP`` layer to start the Zope HTTP server (ZServer) in a separate thread.
This means the test site can be accessed through a web browser, and can thus be used with tools like `Selenium`_.

.. note::

    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.
    Use the ``ZSERVER`` layer if you want to execute functional tests against this fixture.

The ZServer's hostname (normally ``localhost``) is available through the resource ``host``, whilst the port it is running on is available through the resource ``port``.

  *Hint:* Whilst the layer is set up, you can actually access the test Zope site through a web browser.
  The default URL will be ``http://localhost:55001``.

HTTP ZServer functional testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.ZSERVER``                |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.FunctionalTesting``      |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.ZSERVER_FIXTURE``        |
+------------+--------------------------------------------------+
| Resources: |                                                  |
+------------+--------------------------------------------------+

This layer provides the functional testing lifecycle against the fixture set up by the ``zserver.ZSERVER_FIXTURE`` layer.

You can use this to run "live" functional tests against a basic Zope site.
You should **not** use it as a base.
Instead, create your own "fixture" layer that extends ``zserver.ZSERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.


FTP server thread (fixture only)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.FTP_SERVER_FIXTURE``     |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.FTPServer``              |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.STARTUP``                |
+------------+--------------------------------------------------+
| Resources: | ``host``                                         |
|            +--------------------------------------------------+
|            | ``port``                                         |
+------------+--------------------------------------------------+

This layer is the FTP server equivalent of the ``zserver.ZSERVER_FIXTURE`` layer.
It can be used to functionally test Zope FTP servers.

.. note::

    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.
    Use the ``FTP_SERVER`` layer if you want to execute functional tests against this fixture.

    *Hint:* Whilst the layer is set up, you can actually access the test Zope site through an FTP client.
    The default URL will be ``ftp://localhost:55002``.

.. warning::

    Do not run the ``FTP_SERVER`` and ``ZSERVER`` layers concurrently in the same process.

If you need both ZServer and FTPServer running together, you can subclass the ``ZServer`` layer class (like the ``FTPServer`` layer class does) and implement the ``setUpServer()`` and ``tearDownServer()`` methods to set up and close down two servers on different ports.
They will then share a main loop.

FTP server functional testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+------------+--------------------------------------------------+
| Layer:     | ``plone.testing.zserver.FTP_SERVER``             |
+------------+--------------------------------------------------+
| Class:     | ``plone.testing.zserver.FunctionalTesting``      |
+------------+--------------------------------------------------+
| Bases:     | ``plone.testing.zserver.FTP_SERVER_FIXTURE``     |
+------------+--------------------------------------------------+
| Resources: |                                                  |
+------------+--------------------------------------------------+

This layer provides the functional testing lifecycle against the fixture set up by the ``zserver.FTP_SERVER_FIXTURE`` layer.

You can use this to run "live" functional tests against a basic Zope site.
You should **not** use it as a base.
Instead, create your own "fixture" layer that extends ``zserver.FTP_SERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.

Helper functions
~~~~~~~~~~~~~~~~

Several helper functions are available in the ``plone.testing.zserver`` module.

``zopeApp(db=None, conn=Non, environ=None)``

    This function can be used as a context manager for any code that requires access to the Zope application root.
    By using it in a ``with`` block, the database will be opened, and the application root will be obtained and request-wrapped.
    When exiting the ``with`` block, the transaction will be committed and the database properly closed, unless an exception was raised::

        with zserver.zopeApp() as app:
            # do something with app

    If you want to use a specific database or database connection, pass either the ``db`` or ``conn`` arguments.
    If the context manager opened a new connection, it will close it, but it will not close a connection passed with ``conn``.

    To set keys in the (fake) request environment, pass a dictionary of environment values as ``environ``.

    Note that ``zopeApp()`` should *not* normally be used in tests or test set-up/tear-down, because the ``INTEGRATOIN_TEST`` and ``FUNCTIONAL_TESTING`` layers both manage the application root (as the ``app`` resource) and close it for you.
    It is very useful in layer setup, however.

The other helper functions defined in ``plone.testing.zope`` can also be used in a ZServer context but together with the ZServer layers.

.. _zope.testing: https://pypi.org/project/zope.testing/
.. _zope.testbrowser: https://pypi.org/project/zope.testbrowser
.. _zope.component: https://pypi.org/project/zope.component
.. _zope.publisher: https://pypi.org/project/zope.publisher
.. _plone.app.testing: https://pypi.org/project/plone.app.testing
.. _zc.recipe.testrunner: https://pypi.org/project/zc.recipe.testrunner
.. _coverage: https://pypi.org/project/coverage
.. _Cobertura: https://wiki.jenkins.io/display/JENKINS/Cobertura+Plugin
.. _Jenkins: https://jenkins.io
.. _unittest: http://doc.python.org/library/unittest.html
.. _doctest: http://docs.python.org/dev/library/doctest.html
.. _Selenium: http://seleniumhq.org/


Changelog
=========

.. You should *NOT* be adding new change log entries to this file.
   You should create a file in the news directory instead.
   For helpful instructions, please see:
   https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst

.. towncrier release notes start

9.0.1 (2023-11-30)
------------------

Bug fixes:


- Remove incorrect hard dependency on five.localsitemanager. @davisagli (#86)


9.0.0 (2023-10-25)
------------------

Breaking changes:


- Drop python 2.7 support.
  [gforcada] (#1)
- Drop ZServer support.
  [gforcada] (#2)


Internal:


- Update configuration files.
  [plone devs] (5cc689e5)


8.0.4 (2023-09-21)
------------------

Bug fixes:


- Fix tests when run with ZODB 5.8.1+.
  [maurits] (#581)


8.0.3 (2021-06-14)
------------------

Bug fixes:


- fix waitress deprecation warning (#77)
- Catch OSError in test teardown when removing a temporary directory.
  Fixes `issue 79 <https://github.com/plone/plone.testing/issues/79>`_.
  [maurits] (#79)


8.0.2 (2020-10-12)
------------------

Bug fixes:


- update `isort` configuration for version 5 of `isort` (#75)


8.0.1 (2020-06-16)
------------------

Bug fixes:


- fix broken Flake8 job (#74)


8.0.0 (2020-04-21)
------------------

Breaking changes:


- Drop support for Python 3.4 and 3.5.
  Remove "z2" extra.
  [jensens] (#72)


New features:


- Update links for further information about `testing`.
  [jugmac00] (#71)


Bug fixes:


- Fix tests when using zope.testrunner internals since its version 5.1.
  [jensens] (#72)


7.0.3 (2019-12-10)
------------------

Bug fixes:


- Fix issue with test-setup when using ZServer 4.0.2.
  [pbauer] (#69)


7.0.2 (2019-07-06)
------------------

Bug fixes:


- Remove the ``ZOPETESTCASEALERT`` as it imports from ZopeTestCase and has side effects.
  Fixes #64.
  [thet] (#67)


7.0.1 (2019-03-03)
------------------

Bug fixes:


- Fixed test for 'Connection refused' which could be 'Connection reset'.
  [maurits] (#59)


7.0.0 (2018-10-17)
------------------

Breaking changes:

- ``plone.testing.z2`` is now a BBB shim for ``plone.testing.zope``,
  thus it switches the tests to use WSGI.
  If you absolutely want to keep using ZServer please import from ``plone.testing.zserver``.

- ``plone.testing.z2`` now only contains a no-op FTPServer layer because FTP is not supported by WSGI.
  If you really need it, import it from ``plone.testing.zserver`` but this will not work on Python 3.
  
- Default to picking a dynamical port for ZServer layers instead of a static
  default port.
  [Rotonen]

New features:

- Make ``ZServer`` an optional dependency.

- Add support for Python 3.6.
  [rudaporto, icemac]

Bug fixes:

- Explicitly depend on ZServer on the z2 extra.
  [Rotonen]


6.1.0 (2018-10-05)
------------------

Breaking changes:

- Default to picking a dynamical port for ZServer layers instead of a static
  default port.
  [Rotonen]

Bug fixes:

- Pinned ZODB to < 5.4.0 for testing to avoid flaky doctest layer teardowns.
  [Rotonen]

- Loosened doctest assertions to keep up with Zope-side changes.
  [Rotonen]

- Fix most of the code smells Jenkins complains about.

- Fix the Zope exception hook when using the ZServer layer.

- Fix teardown of the ``plone.testing.security.Checkers`` layer.
  It was not properly restoring zope.security's ``_checkers`` dict.


6.0.0 (2018-02-05)
------------------

- Breaking changes:

  + Only support ``Zope >= 4``, no longer support ``Zope2``.
  + Drop support for Python 2.6.

- No longer use deprecated import for getSite/setSite.
  [jensens]

- Update code to follow Plone styleguide.
  [gforcada]


5.1.1 (2017-04-19)
------------------

- Do not break on import of ``plone.testing.z2`` when using `zope.testbrowser` >= 5.0 which no longer depends on `mechanize`.


5.1 (2017-04-13)
----------------

- Fix for ZODB 5: Abort transaction before DB close.
  [jensens, jimfulton]

- Remove BBB code and imports for Zope < 2.13.
  [thet]

- Fix issue, which prevented using layered-helper on Python 3.
  [datakurre]

- Fix ``.z2.Startup.setUpZCML()`` to be compatible with Zope >= 4.0a2.
  [icemac]

- Fix version pins on the package itself to be able to run the tests.
  [gforcada]

5.0.0 (2016-02-19)
------------------

Rerelease of 4.2.0 as 5.0.0.

The version 4.2.0 had changed error handling in the public api, causing exceptions where before everything continued to work.


4.2.0 (2016-02-18)
------------------

New:

- Refuse to work if user breaks test isolation.
  [do3cc]
- Check that tests don't run together with ZopeTestCase
  [do3cc]

Fixes:

- Fix tests for Zope 4, where the app root Control_Panel is not available anymore.
  [thet]


4.1.0 (2016-01-08)
------------------

Fixes:

- Rename all txt doctest files to rst. Reformat doctests.
  [thet]

- PEP 8.
  [thet]

- Depend on zope.testrunner, which was moved out from zope.testing.testrunner.
  [thet]

- Add support for Zope 4.
  [thet]


4.0.15 (2015-08-14)
-------------------

- Prevent exception masking in finally clause of zopeApp context.
  [do3cc]


4.0.14 (2015-07-29)
-------------------

- Rerelease for clarity due to double release of 4.0.13.
  [maurits]

- Added ``multiinit``-parameter to z2.installProduct to allow multiple initialize methods for a package
  [tomgross]


4.0.13 (2015-03-13)
-------------------

- Really fix not to depend on unittest2.
  [icemac]

- Add tox.ini
  [icemac]


4.0.12 (2014-09-07)
-------------------

- Fixed AttributeError when importing ``plone.testing.z2`` if ``zope.testbrowser`` 4.x is used but not ``zope.app.testing``.
  [icemac]

- Broke dependency on `unittest2` for Python 2.7+ as all features of `unittest2` are integrated in `unittest` there.
  [icemac]


4.0.11 (2014-02-22)
-------------------

- Fix z2.txt doctest for FTP_SERVER.
  [timo]


4.0.10 (2014-02-11)
-------------------

- Read 'FTPSERVER_HOST' and 'FTPSERVER_PORT' from the environment variables if possible.
  This allows us to run tests in parallel on CI servers.
  [timo]


4.0.9 (2014-01-28)
------------------

- Replace deprecated Zope2VocabularyRegistry import.
  [timo]


4.0.8 (2013-03-05)
------------------

- Factor test request creation out of addRequestContainer into makeTestRequest.
  [davisagli]


4.0.7 (2012-12-09)
------------------

- Fix quoting of urls by the testbrowser.
  [do3cc]


4.0.6 (2012-10-15)
------------------

- Update manifest.in to include content in src directory.
  [esteele]


4.0.5 (2012-10-15)
------------------

- Fixed an issue where a query string would be unquoted twice;
  once while setting up the HTTP request and once in the handler (the publisher).
  [malthe]


4.0.4 (2012-08-04)
------------------

- Fixed the cache reset code.
  In some situations the function does not have any defaults,
  so we shouldn't try to clear out the app reference.
  [malthe]


4.0.3 (2011-11-24)
------------------

- Fixed class names in documentation to match code.
  [icemac]


4.0.2 (2011-08-31)
------------------

- The defaults of the ``ZPublisher.Publish.get_module_info`` function cache
  a reference to the app, so make sure that gets reset when tearing down the
  app. This fixes a problem where the testbrowser in the second functional
  layer to be set up accessed the database from the first functional layer.
  [davisagli]


4.0.1 - 2011-05-20
------------------

- Moved readme file containing tests into the package, so tests can be run from
  released source distributions. Closes http://dev.plone.org/plone/ticket/11821.
  [hannosch]

- Relicense under BSD license.
  See http://plone.org/foundation/materials/foundation-resolutions/plone-framework-components-relicensing-policy
  [davisagli]


4.0 - 2011-05-13
----------------

- Release 4.0 Final.
  [esteele]

- Add MANIFEST.in.
  [WouterVH]


4.0a6 - 2011-04-06
------------------

- Fixed Browser cookies retrieval with Zope 2.13.
  [vincentfretin]

- Add ``ZCMLSandbox`` layer to load a ZCML file; replaces ``setUpZcmlFiles`` and
  ``tearDownZcmlFiles`` helper functions.
  [gotcha]


4.0a5 - 2011-03-02
------------------

- Handle test failures due to userFolderAddUser returning the user object in
  newer versions of Zope.
  [esteele]

- Add ``setUpZcmlFiles`` and ``tearDownZcmlFiles`` helpers to enable loading
  of ZCML files without too much boilerplate.
  [gotcha]

- Add some logging.
  [gotcha]

- Add the ``[security]`` extra, to provide tear-down of security checkers.
  [optilude]

- Let the ``IntegrationTesting`` and ``FunctionalTesting`` lifecycle layers
  set up request ``PARENTS`` and, if present, wire up
  ``zope.globalrequest``.
  [optilude]

- Make the test browser support IStreamIterators
  [optilude]


4.0a4 - 2011-01-11
------------------

- Make sure ZCML doesn't load during App startup in Zope 2.13.
  [davisagli]


4.0a3 - 2010-12-14
------------------

- Ignore the `testinghome` configuration setting if present.
  [stefan]

- Use the new API for getting the packages_to_initialize list in Zope 2.13.
  [davisagli]

- De-duplicate _register_monkies and _meta_type_regs in the correct module on
  teardown of the Startup layer in Zope 2.13.
  [davisagli]

- Allow doctest suites from `zope.testing` to work with `plone.testing.layer.layered`.
  Previously, only doctest suites from the stdlib would see the `layer` global.
  [nouri]

- Changed documentation to advertise the `coverage` library for running
  coverage tests instead of the built-in `zope.testing` support. This also
  avoids using `z3c.coverage`. The coverage tests now run at the same speed
  as a normal test run, making it more likely to get executed frequently.
  [hannosch]

- Correct license to GPL version 2 only.
  [hannosch]

- Fix some user id vs name confusion.
  [rossp]

- Add the option to specify ZServer host and port through environment
  variables - ZSERVER_HOST and ZSERVER_PORT).
  [esteele]


1.0a2 - 2010-09-05
------------------

- Fix a problem that would cause ``<meta:redefinePermission />`` to break.
  In particular fixes the use of the ``zope2.Public`` permission.
  [optilude]

- Set the security implementation to "Python" for easier debugging during
  the z2.STARTUP layer.
  [optilude]

- Initialize Five in the z2.Startup layer, pushing a Zope2VocabularyRegistry on
  layer set-up and restoring the previous one upon tear-down.
  [dukebody]


1.0a1 - 2010-08-01
------------------

- Initial release


Detailed documentation
======================

Layer base class
----------------

This package provides a layer base class which can be used by the test runner.
It is available as a convenience import from the package root.::

    >>> from plone.testing import Layer

A layer may be instantiated directly, though in this case the ``name`` argument is required (see below).::

    >>> NULL_LAYER = Layer(name="Null layer")

This is not very useful on its own.
It has an empty list of bases, and each of the layer lifecycle methods does nothing.::

    >>> NULL_LAYER.__bases__
    ()
    >>> NULL_LAYER.__name__
    'Null layer'
    >>> NULL_LAYER.__module__
    'plone.testing.layer'

    >>> NULL_LAYER.setUp()
    >>> NULL_LAYER.testSetUp()
    >>> NULL_LAYER.tearDown()
    >>> NULL_LAYER.testTearDown()

Just about the only reason to use this directly (i.e. not as a base class) is to group together other layers.::

    >>> SIMPLE_LAYER = Layer(bases=(NULL_LAYER,), name="Simple layer", module='plone.testing.tests')

Here, we've also set the module name directly.
The default for all layers is to take the module name from the stack frame where the layer was instantiated.
In doctests, that doesn't work, though, so we fall back on the module name of the layer class.
The two are often the same, of course.

This layer now has the bases, name and module we set:::

    >>> SIMPLE_LAYER.__bases__
    (<Layer 'plone.testing.layer.Null layer'>,)

    >>> SIMPLE_LAYER.__name__
    'Simple layer'

    >>> SIMPLE_LAYER.__module__
    'plone.testing.tests'

The ``name`` argument is required when using ``Layer`` directly (but not when using a subclass):::

    >>> Layer((SIMPLE_LAYER,))
    Traceback (most recent call last):
    ...
    ValueError: The `name` argument is required when instantiating `Layer` directly

    >>> class NullLayer(Layer):
    ...     pass
    >>> NullLayer()
    <Layer 'builtins.NullLayer'>

Using ``Layer`` as a base class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The usual pattern is to use ``Layer`` as a base class for a custom layer.
This can then override the lifecycle methods as appropriate, as well as set a default list of bases.::

    >>> class BaseLayer(Layer):
    ...
    ...     def setUp(self):
    ...         print("Setting up base layer")
    ...
    ...     def tearDown(self):
    ...         print("Tearing down base layer")

    >>> BASE_LAYER = BaseLayer()

The layer name and module are taken from the class.::

    >>> BASE_LAYER.__bases__
    ()
    >>> BASE_LAYER.__name__
    'BaseLayer'
    >>> BASE_LAYER.__module__
    'builtins'

We can now create a new layer that has this one as a base.
We can do this in the instance constructor, as shown above, but the most common pattern is to set the default bases in the class body, using the variable ``defaultBases``.

We'll also set the default name explicitly here by passing a name to the the super-constructor.
This is mostly cosmetic, but may be desirable if the class name would be misleading in the test runner output.::

    >>> class ChildLayer(Layer):
    ...     defaultBases = (BASE_LAYER,)
    ...
    ...     def __init__(self, bases=None, name='Child layer', module=None):
    ...         super(ChildLayer, self).__init__(bases, name, module)
    ...
    ...     def setUp(self):
    ...         print("Setting up child layer")
    ...
    ...     def tearDown(self):
    ...         print("Tearing down child layer")

    >>> CHILD_LAYER = ChildLayer()

Notice how the bases have now been set using the value in ``defaultBases``.::

    >>> CHILD_LAYER.__bases__
    (<Layer 'builtins.BaseLayer'>,)
    >>> CHILD_LAYER.__name__
    'Child layer'
    >>> CHILD_LAYER.__module__
    'builtins'

Overriding the default list of bases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We can override the list of bases on a per-instance basis.
This may be dangerous, i.e.
the layer is likely to expect that its bases are set up.
Sometimes, it may be useful to inject a new base, however, especially when re-using layers from other packages.

The new list of bases is passed to the constructor.
When creating a second instance of a layer (most layers are global singletons created only once), it's useful to give the new instance a unique name, too.::

    >>> NEW_CHILD_LAYER = ChildLayer(bases=(SIMPLE_LAYER, BASE_LAYER,), name='New child')

    >>> NEW_CHILD_LAYER.__bases__
    (<Layer 'plone.testing.tests.Simple layer'>, <Layer 'builtins.BaseLayer'>)
    >>> NEW_CHILD_LAYER.__name__
    'New child'
    >>> NEW_CHILD_LAYER.__module__
    'builtins'

Inconsistent bases
~~~~~~~~~~~~~~~~~~

Layer bases are maintained in an order that is semantically equivalent to the "method resolution order" Python maintains for base classes.
We can get this from the ``baseResolutionOrder`` attribute:::

    >>> CHILD_LAYER.baseResolutionOrder
    (<Layer 'builtins.Child layer'>, <Layer 'builtins.BaseLayer'>)

    >>> NEW_CHILD_LAYER.baseResolutionOrder
    (<Layer 'builtins.New child'>, <Layer 'plone.testing.tests.Simple layer'>,
     <Layer 'plone.testing.layer.Null layer'>,
     <Layer 'builtins.BaseLayer'>)

As with Python classes, it is possible to construct an invalid set of bases.
In this case, layer instantiation will fail.::

    >>> INCONSISTENT_BASE1 = Layer(name="Inconsistent 1")
    >>> INCONSISTENT_BASE2 = Layer((INCONSISTENT_BASE1,), name="Inconsistent 1")
    >>> INCONSISTENT_BASE3 = Layer((INCONSISTENT_BASE1, INCONSISTENT_BASE2,), name="Inconsistent 1")
    Traceback (most recent call last):
    ...
    TypeError: Inconsistent layer hierarchy!

Using the resource manager
~~~~~~~~~~~~~~~~~~~~~~~~~~

Layers are also resource managers.
Resources can be set, retrieved and deleted using dictionary syntax.
Resources in base layers are available in child layers.
When an item is set on a child layer, it shadows any items with the same key in any base layer (until it is deleted), but the original item still exists.

Let's create a somewhat complex hierarchy of layers that all set resources under a key ``'foo'`` in their ``setUp()`` methods.::

    >>> class Layer1(Layer):
    ...     def setUp(self):
    ...         self['foo'] = 1
    ...     def tearDown(self):
    ...         del self['foo']
    >>> LAYER1 = Layer1()

    >>> class Layer2(Layer):
    ...     defaultBases = (LAYER1,)
    ...     def setUp(self):
    ...         self['foo'] = 2
    ...     def tearDown(self):
    ...         del self['foo']
    >>> LAYER2 = Layer2()

    >>> class Layer3(Layer):
    ...     def setUp(self):
    ...         self['foo'] = 3
    ...     def tearDown(self):
    ...         del self['foo']
    >>> LAYER3 = Layer3()

    >>> class Layer4(Layer):
    ...     defaultBases = (LAYER2, LAYER3,)
    ...     def setUp(self):
    ...         self['foo'] = 4
    ...     def tearDown(self):
    ...         del self['foo']
    >>> LAYER4 = Layer4()

    **Important:** Resources that are created in ``setUp()`` must be deleted in ``tearDown()``.
    Similarly, resources created in ``testSetUp()`` must be deleted in ``testTearDown()``.
    This ensures resources are properly stacked and do not leak between layers.

If a test was using ``LAYER4``, the test runner would call each setup step in turn, starting with the "deepest" layer.
We'll simulate that here, so that each of the resources is created.::

    >>> LAYER1.setUp()
    >>> LAYER2.setUp()
    >>> LAYER3.setUp()
    >>> LAYER4.setUp()

The layers are ordered in a known "resource resolution order", which is used to determine in which order the layers shadow one another.
This is based on the same algorithm as Python's method resolution order.::

    >>> LAYER4.baseResolutionOrder
    (<Layer 'builtins.Layer4'>,
     <Layer 'builtins.Layer2'>,
     <Layer 'builtins.Layer1'>,
     <Layer 'builtins.Layer3'>)

When fetching and item from a layer, it will be obtained according to the resource resolution order.::

    >>> LAYER4['foo']
    4

This is not terribly interesting, since ``LAYER4`` has the resource ``'foo'`` set directly.
Let's tear down the layer (which deletes the resource) and see what happens.::

    >>> LAYER4.tearDown()
    >>> LAYER4['foo']
    2

We can continue up the chain:::

    >>> LAYER2.tearDown()
    >>> LAYER4['foo']
    1

    >>> LAYER1.tearDown()
    >>> LAYER4['foo']
    3

Once we've deleted the last key, we'll get a ``KeyError``:::

    >>> LAYER3.tearDown()
    >>> LAYER4['foo']
    Traceback (most recent call last):
    ...
    KeyError: 'foo'

To guard against this, we can use the ``get()`` method.::

    >>> LAYER4.get('foo', -1)
    -1

We can also test with 'in':::

    >>> 'foo' in LAYER4
    False

To illustrate that this indeed works, let's set the resource back on one of the bases.::

    >>> LAYER3['foo'] = 10
    >>> LAYER4.get('foo', -1)
    10

Let's now consider a special case: a base layer sets up a resource in layer setup, and uses it in test setup.
A child layer then shadows this resource in its own layer setup method.
In this case, we want the base layer's ``testSetUp()`` to use the shadowed version that the child provided.

(This is similar to how instance variables work: a base class may set an attribute on ``self`` and use it in a method.
If a subclass then sets the same attribute to a different value and the base class method is called on an instance of the subclass, the base class attribute is used).

    *Hint:* If you definitely need to access the "original" resource in your ``testSetUp()``/``testTearDown()`` methods, you can store a reference to the resource as a layer instance variable::

        self.someResource = self['someResource'] = SomeResource()

    ``self.someResource`` will now be the exact resource created here, whereas ``self['someResource']`` will retain the layer shadowing semantics.
    In most cases, you probably *don't* want to do this, allowing child layers to supply overridden versions of resources as appropriate.

First, we'll create some base layers.
We want to demonstrate having two "branches" of bases that both happen to define the same resource.::

    >>> class ResourceBaseLayer1(Layer):
    ...     def setUp(self):
    ...         self['resource'] = "Base 1"
    ...     def testSetUp(self):
    ...         print(self['resource'])
    ...     def tearDown(self):
    ...         del self['resource']

    >>> RESOURCE_BASE_LAYER1 = ResourceBaseLayer1()

    >>> class ResourceBaseLayer2(Layer):
    ...     defaultBases = (RESOURCE_BASE_LAYER1,)
    ...     def testSetUp(self):
    ...         print(self['resource'])

    >>> RESOURCE_BASE_LAYER2 = ResourceBaseLayer2()

    >>> class ResourceBaseLayer3(Layer):
    ...     def setUp(self):
    ...         self['resource'] = "Base 3"
    ...     def testSetUp(self):
    ...         print(self['resource'])
    ...     def tearDown(self):
    ...         del self['resource']

    >>> RESOURCE_BASE_LAYER3 = ResourceBaseLayer3()

We'll then create the child layer that overrides this resource.::

    >>> class ResourceChildLayer(Layer):
    ...     defaultBases = (RESOURCE_BASE_LAYER2, RESOURCE_BASE_LAYER3)
    ...     def setUp(self):
    ...         self['resource'] = "Child"
    ...     def testSetUp(self):
    ...         print(self['resource'])
    ...     def tearDown(self):
    ...         del self['resource']

    >>> RESOURCE_CHILD_LAYER = ResourceChildLayer()

We'll first set up the base layers on their own and simulate two tests.

A test with RESOURCE_BASE_LAYER1 only would look like this:::

    >>> RESOURCE_BASE_LAYER1.setUp()

    >>> RESOURCE_BASE_LAYER1.testSetUp()
    Base 1
    >>> RESOURCE_BASE_LAYER1.testTearDown()

    >>> RESOURCE_BASE_LAYER1.tearDown()

A test with RESOURCE_BASE_LAYER2 would look like this:::

    >>> RESOURCE_BASE_LAYER1.setUp()
    >>> RESOURCE_BASE_LAYER2.setUp()

    >>> RESOURCE_BASE_LAYER1.testSetUp()
    Base 1
    >>> RESOURCE_BASE_LAYER2.testSetUp()
    Base 1
    >>> RESOURCE_BASE_LAYER2.testTearDown()
    >>> RESOURCE_BASE_LAYER1.testTearDown()

    >>> RESOURCE_BASE_LAYER2.tearDown()
    >>> RESOURCE_BASE_LAYER1.tearDown()

A test with RESOURCE_BASE_LAYER3 only would look like this:::

    >>> RESOURCE_BASE_LAYER3.setUp()

    >>> RESOURCE_BASE_LAYER3.testSetUp()
    Base 3
    >>> RESOURCE_BASE_LAYER3.testTearDown()

    >>> RESOURCE_BASE_LAYER3.tearDown()

Now let's set up the child layer and simulate another test.
We should now be using the shadowed resource.::

    >>> RESOURCE_BASE_LAYER1.setUp()
    >>> RESOURCE_BASE_LAYER2.setUp()
    >>> RESOURCE_BASE_LAYER3.setUp()
    >>> RESOURCE_CHILD_LAYER.setUp()

    >>> RESOURCE_BASE_LAYER1.testSetUp()
    Child
    >>> RESOURCE_BASE_LAYER2.testSetUp()
    Child
    >>> RESOURCE_BASE_LAYER3.testSetUp()
    Child
    >>> RESOURCE_CHILD_LAYER.testSetUp()
    Child

    >>> RESOURCE_CHILD_LAYER.testTearDown()
    >>> RESOURCE_BASE_LAYER3.testTearDown()
    >>> RESOURCE_BASE_LAYER2.testTearDown()
    >>> RESOURCE_BASE_LAYER1.testTearDown()

Finally, we'll tear down the child layer again and simulate another test.
we should have the original resources back.
Note that the first and third layers no longer share a resource, since they don't have a common ancestor.::

    >>> RESOURCE_CHILD_LAYER.tearDown()

    >>> RESOURCE_BASE_LAYER1.testSetUp()
    Base 1
    >>> RESOURCE_BASE_LAYER2.testSetUp()
    Base 1
    >>> RESOURCE_BASE_LAYER2.testTearDown()
    >>> RESOURCE_BASE_LAYER1.testTearDown()

    >>> RESOURCE_BASE_LAYER3.testSetUp()
    Base 3
    >>> RESOURCE_BASE_LAYER3.testTearDown()

Finally, we'll tear down the remaining layers..::

    >>> RESOURCE_BASE_LAYER3.tearDown()
    >>> RESOURCE_BASE_LAYER2.tearDown()
    >>> RESOURCE_BASE_LAYER1.tearDown()

Asymmetric deletion
+++++++++++++++++++

It is an error to create or shadow a resource in a set-up lifecycle method and not delete it again in the tear-down.
It is also an error to delete a resource that was not explicitly created.
These two layers break those roles:::

    >>> class BadLayer1(Layer):
    ...     def setUp(self):
    ...         pass
    ...     def tearDown(self):
    ...         del self['foo']
    >>> BAD_LAYER1 = BadLayer1()

    >>> class BadLayer2(Layer):
    ...     defaultBases = (BAD_LAYER1,)
    ...     def setUp(self):
    ...         self['foo'] = 1
    ...         self['bar'] = 2
    >>> BAD_LAYER2 = BadLayer2()

Let's simulate a test that uses ``BAD_LAYER2``:::

    >>> BAD_LAYER1.setUp()
    >>> BAD_LAYER2.setUp()

    >>> BAD_LAYER1.testSetUp()
    >>> BAD_LAYER2.testSetUp()

    >>> BAD_LAYER2.testTearDown()
    >>> BAD_LAYER1.testTearDown()

    >>> BAD_LAYER2.tearDown()
    >>> BAD_LAYER1.tearDown()
    Traceback (most recent call last):
    ...
    KeyError: 'foo'

Here, we've got an error in the base layer.
This is because the resource is actually associated with the layer that first created it, in this case ``BASE_LAYER2``.
This one remains intact and orphaned:::

    >>> 'foo' in BAD_LAYER2._resources
    True
    >>> 'bar' in BAD_LAYER2._resources
    True

Doctest layer helper
~~~~~~~~~~~~~~~~~~~~

The ``doctest`` module is not aware of ``zope.testing``'s layers concept.
Therefore, the syntax for creating a doctest with a layer and adding it to a test suite is somewhat contrived: the test suite has to be created first, and then the layer attribute set on it:::

    >>> class DoctestLayer(Layer):
    ...     pass
    >>> DOCTEST_LAYER = DoctestLayer()

    >>> import unittest
    >>> import doctest

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     layerDoctest = doctest.DocFileSuite('layer.rst', package='plone.testing')
    ...     layerDoctest.layer = DOCTEST_LAYER
    ...     suite.addTest(layerDoctest)
    ...     return suite

    >>> suite = test_suite()
    >>> tests = list(suite)
    >>> len(tests)
    1
    >>> tests[0].layer is DOCTEST_LAYER
    True


To make this a little easier - especially when setting up multiple tests - a helper function called ``layered`` is provided:::

    >>> from plone.testing import layered

    >>> def test_suite():
    ...     suite = unittest.TestSuite()
    ...     suite.addTests([
    ...         layered(doctest.DocFileSuite('layer.rst', package='plone.testing'), layer=DOCTEST_LAYER),
    ...         # repeat with more suites if necessary
    ...     ])
    ...     return suite

This does the same as the sample above.::

    >>> suite = test_suite()
    >>> tests = list(suite)
    >>> len(tests)
    1
    >>> tests[0].layer is DOCTEST_LAYER
    True

In addition, a 'layer' glob is added to each test in the suite.
This allows the test to access layer resources.::

    >>> len(list(tests[0]))
    1
    >>> list(tests[0])[0]._dt_test.globs['layer'] is DOCTEST_LAYER
    True


Zope Component Architecture layers
----------------------------------

The ZCA layers are found in the module ``plone.testing.zca``:::

    >>> from plone.testing import zca

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

Unit testing
~~~~~~~~~~~~

The ``UNIT_TESTING`` layer is used to set up a clean component registry between each test.
It uses ``zope.testing.cleanup`` to clean up all global state.

It has no bases:::

    >>> "%s.%s" % (zca.UNIT_TESTING.__module__, zca.UNIT_TESTING.__name__,)
    'plone.testing.zca.UnitTesting'

    >>> zca.UNIT_TESTING.__bases__
    ()

The component registry is cleaned up between each test.::

    >>> from zope.interface import Interface
    >>> from zope.component import provideUtility

    >>> class DummyUtility(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...     def __repr__(self):
    ...         return "<%s>" % self.name

    >>> provideUtility(DummyUtility("Dummy"), provides=Interface, name="test-dummy")

    >>> from zope.component import queryUtility
    >>> queryUtility(Interface, name="test-dummy")
    <Dummy>

Layer setup does nothing.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zca.UNIT_TESTING, setupLayers)
    Set up plone.testing.zca.UnitTesting in ... seconds.

Let's now simulate a test.
Before any test setup has happened, our previously registered utility is still there.::

    >>> queryUtility(Interface, name="test-dummy")
    <Dummy>

On test setup, it disappears.::

    >>> zca.UNIT_TESTING.testSetUp()

    >>> queryUtility(Interface, name="test-dummy") is None
    True

The test would now execute. It may register some components.::

    >>> provideUtility(DummyUtility("Dummy2"), provides=Interface, name="test-dummy")
    >>> queryUtility(Interface, name="test-dummy")
    <Dummy2>

On test tear-down, this disappears.::

    >>> zca.UNIT_TESTING.testTearDown()

    >>> queryUtility(Interface, name="test-dummy") is None
    True

Layer tear-down does nothing.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zca.UnitTesting in ... seconds.

Event testing
~~~~~~~~~~~~~

The ``EVENT_TESTING`` layer extends the ``UNIT_TESTING`` layer to add the necessary registrations for ``zope.component.eventtesting`` to work.::

    >>> "%s.%s" % (zca.EVENT_TESTING.__module__, zca.EVENT_TESTING.__name__,)
    'plone.testing.zca.EventTesting'

    >>> zca.EVENT_TESTING.__bases__
    (<Layer 'plone.testing.zca.UnitTesting'>,)

Before the test, the component registry is empty and ``getEvents()`` returns nothing, even if an event is fired.::

    >>> from zope.component.eventtesting import getEvents

    >>> class DummyEvent(object):
    ...     def __repr__(self):
    ...         return "<Dummy event>"

    >>> from zope.event import notify
    >>> notify(DummyEvent())

    >>> getEvents()
    []

Layer setup does nothing.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zca.EVENT_TESTING, setupLayers)
    Set up plone.testing.zca.UnitTesting in ... seconds.
    Set up plone.testing.zca.EventTesting in ... seconds.

Let's now simulate a test. On test setup, the event testing list is emptied.::

    >>> zca.UNIT_TESTING.testSetUp()
    >>> zca.EVENT_TESTING.testSetUp()

    >>> getEvents()
    []

The test would now execute.
It may fire some events, which would show up in the event testing list.::

    >>> notify(DummyEvent())
    >>> getEvents()
    [<Dummy event>]

On test tear-down, the list is emptied again:::

    >>> zca.EVENT_TESTING.testTearDown()
    >>> zca.UNIT_TESTING.testTearDown()

    >>> getEvents()
    []

Layer tear-down does nothing.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zca.EventTesting in ... seconds.
    Tear down plone.testing.zca.UnitTesting in ... seconds.

Layer cleanup
~~~~~~~~~~~~~

The ``LAYER_CLEANUP`` layer is used to set up a clean component registry at the set-up and tear-down of a layer.
It uses ``zope.testing.cleanup`` to clean up all global state.

It has no bases:::

    >>> "%s.%s" % (zca.LAYER_CLEANUP.__module__, zca.LAYER_CLEANUP.__name__,)
    'plone.testing.zca.LayerCleanup'

    >>> zca.LAYER_CLEANUP.__bases__
    ()

The component registry is cleaned up on layer set-up and tear-down (but not between tests).::

    >>> from zope.interface import Interface
    >>> from zope.component import provideUtility

    >>> class DummyUtility(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...     def __repr__(self):
    ...         return "<%s>" % self.name

    >>> provideUtility(DummyUtility("Dummy"), provides=Interface, name="test-dummy")

    >>> from zope.component import queryUtility
    >>> queryUtility(Interface, name="test-dummy")
    <Dummy>

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zca.LAYER_CLEANUP, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.

    >>> queryUtility(Interface, name="test-dummy") is None
    True

A sub-layer may register additional components:::

    >>> provideUtility(DummyUtility("Dummy2"), provides=Interface, name="test-dummy2")

Let's now simulate a test. Test setup and tear-down does nothing.::

    >>> zca.LAYER_CLEANUP.testSetUp()

    >>> queryUtility(Interface, name="test-dummy") is None
    True
    >>> queryUtility(Interface, name="test-dummy2")
    <Dummy2>

    >>> zca.LAYER_CLEANUP.testTearDown()

    >>> queryUtility(Interface, name="test-dummy") is None
    True
    >>> queryUtility(Interface, name="test-dummy2")
    <Dummy2>

On tear-down, the registry is cleaned again.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

    >>> queryUtility(Interface, name="test-dummy") is None
    True
    >>> queryUtility(Interface, name="test-dummy2") is None
    True

Basic ZCML directives
~~~~~~~~~~~~~~~~~~~~~

The ``ZCML_DIRECTIVES`` layer creates a ZCML configuration context with the basic ``zope.component`` directives available.
It extends the ``LAYER_CLEANUP`` layer.::

    >>> "%s.%s" % (zca.ZCML_DIRECTIVES.__module__, zca.ZCML_DIRECTIVES.__name__,)
    'plone.testing.zca.ZCMLDirectives'

    >>> zca.ZCML_DIRECTIVES.__bases__
    (<Layer 'plone.testing.zca.LayerCleanup'>,)

Before the test, we cannot use e.g. a ``<utility />`` directive without loading the necessary ``meta.zcml`` files.::

    >>> from zope.configuration import xmlconfig
    >>> from zope.configuration.exceptions import ConfigurationError
    >>> try:
    ...     xmlconfig.string("""\
    ...     <configure package="plone.testing" xmlns="http://namespaces.zope.org/zope">
    ...         <utility factory=".tests.DummyUtility" provides="zope.interface.Interface" name="test-dummy" />
    ...     </configure>""")
    ... except ConfigurationError as e:
    ...     True
    True

Layer setup creates a configuration context we can use to load further configuration.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zca.ZCML_DIRECTIVES, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zca.ZCMLDirectives in ... seconds.

Let's now simulate a test that uses this configuration context to load the same ZCML string.::

    >>> zca.ZCML_DIRECTIVES.testSetUp()

    >>> context = zca.ZCML_DIRECTIVES['configurationContext'] # would normally be self.layer['configurationContext']
    >>> xmlconfig.string("""\
    ... <configure package="plone.testing" xmlns="http://namespaces.zope.org/zope">
    ...     <utility factory=".tests.DummyUtility" provides="zope.interface.Interface" name="test-dummy" />
    ... </configure>""", context=context) is context
    True

The utility is now registered:::

    >>> queryUtility(Interface, name="test-dummy")
    <Dummy utility>

    >>> zca.UNIT_TESTING.testTearDown()

Note that normally, we'd combine this with the ``UNIT_TESTING`` layer to tear down the component architecture as well.

Layer tear-down deletes the configuration context.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zca.ZCMLDirectives in ... seconds.

    >>> zca.ZCML_DIRECTIVES.get('configurationContext', None) is None
    True

Configuration registry sandboxing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For simple unit tests, the full cleanup performed between each test using the ``UNIT_TESTING`` layer is undoubtedly the safest and most convenient way to ensure proper isolation of tests using the global component architecture.
However, if you are writing a complex layer that sets up a lot of components, you may wish to keep some components registered at the layer level, whilst still allowing tests and sub-layers to register their own components in isolation.

This is a tricky problem, because the default ZCML directives and APIs (``provideAdapter()``, ``provideUtility()`` and so on) explicitly work on a single global adapter registry object.
To get around this, you can use two helper methods in the ``zca`` module to push a new global component registry before registering components, and pop the registry after.
Registries are stacked, so the components registered in a "lower" registry are automatically available in a "higher" registry.

Let's illustrate this with a layer that stacks two new global registries.
The first registry is specific to the layer, and is used to house the components registered at the layer level.
The second registry is set up and torn down for each test, allowing tests to register their own components freely.

First, we'll create a simple dummy utility to illustrate registrations.::

    >>> from zope.interface import Interface, implementer

    >>> class IDummyUtility(Interface):
    ...     pass
    >>> @implementer(IDummyUtility)
    ... class DummyUtility(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...     def __repr__(self):
    ...         return "<DummyUtility %s>" % self.name

The two key methods are:

* ``zca.pushGlobalRegistry()``, which creates a new global registry.
* ``zca.popGlobalRegistry()``, which restores the previous global registry.

  **Warning:** You *must* balance your calls to these methods.
  If you call ``pushGlobalRegistry()`` in ``setUp()``, call ``popGlobalRegistry()`` in ``tearDown()``.
  Ditto for ``testSetUp()`` and ``testTearDown()``.

Let's now create our layer.::

    >>> from zope.component import provideUtility
    >>> from plone.testing import Layer
    >>> from plone.testing import zca

    >>> class ComponentSandbox(Layer):
    ...     def setUp(self):
    ...         zca.pushGlobalRegistry()
    ...         provideUtility(DummyUtility("layer"), name="layer")
    ...     def tearDown(self):
    ...         zca.popGlobalRegistry()
    ...     def testSetUp(self):
    ...         zca.pushGlobalRegistry()
    ...     def testTearDown(self):
    ...         zca.popGlobalRegistry()
    >>> COMPONENT_SANDBOX = ComponentSandbox()

Let's now simulate a test using this layer.

To begin with, we have the default registry.::

    >>> from zope.component import getGlobalSiteManager, getSiteManager
    >>> getSiteManager() is getGlobalSiteManager()
    True

    >>> defaultGlobalSiteManager = getGlobalSiteManager()

    >>> from zope.component import queryUtility
    >>> queryUtility(IDummyUtility, name="layer") is None
    True

We'll now simulate layer setup. This will push a new registry onto the stack:::

    >>> COMPONENT_SANDBOX.setUp()

    >>> getSiteManager() is getGlobalSiteManager()
    True
    >>> getGlobalSiteManager() is defaultGlobalSiteManager
    False
    >>> layerGlobalSiteManager = getGlobalSiteManager()

    >>> queryUtility(IDummyUtility, name="layer")
    <DummyUtility layer>

We'll then simulate a test that registers a global component:::

    >>> COMPONENT_SANDBOX.testSetUp()

    >>> getSiteManager() is getGlobalSiteManager()
    True
    >>> getGlobalSiteManager() is defaultGlobalSiteManager
    False
    >>> getGlobalSiteManager() is layerGlobalSiteManager
    False

Our previously registered component is still here.::

    >>> queryUtility(IDummyUtility, name="layer")
    <DummyUtility layer>

We can also register a new one.::

    >>> provideUtility(DummyUtility("test"), name="test")
    >>> queryUtility(IDummyUtility, name="layer")
    <DummyUtility layer>
    >>> queryUtility(IDummyUtility, name="test")
    <DummyUtility test>

On test tear-down, only the second utility disappears:::

    >>> COMPONENT_SANDBOX.testTearDown()

    >>> getSiteManager() is getGlobalSiteManager()
    True
    >>> getGlobalSiteManager() is defaultGlobalSiteManager
    False
    >>> getGlobalSiteManager() is layerGlobalSiteManager
    True

    >>> queryUtility(IDummyUtility, name="layer")
    <DummyUtility layer>
    >>> queryUtility(IDummyUtility, name="test") is None
    True

If we tear down the layer too, we're back where we started:::

    >>> COMPONENT_SANDBOX.tearDown()

    >>> getSiteManager() is getGlobalSiteManager()
    True
    >>> getGlobalSiteManager() is defaultGlobalSiteManager
    True

    >>> queryUtility(IDummyUtility, name="layer") is None
    True
    >>> queryUtility(IDummyUtility, name="test") is None
    True

ZCML files helper class
~~~~~~~~~~~~~~~~~~~~~~~

One of the frequent use cases is a layer that loads a ZCML file and sandbox the resulting registry.

The ``ZCMLSandbox`` can be instantiated with a `filename`` and ``package`` arguments.::

    >>> import plone.testing
    >>> ZCML_SANDBOX = zca.ZCMLSandbox(filename="testing_zca.zcml",
    ...     package=plone.testing)

Before layer setup, the utility is not registered.::

    >>> queryUtility(Interface, name="layer") is None
    True

We'll now simulate layer setup.
This pushes a new registry onto the stack:::

    >>> ZCML_SANDBOX.setUp()

    >>> getSiteManager() is getGlobalSiteManager()
    True
    >>> getGlobalSiteManager() is defaultGlobalSiteManager
    False
    >>> queryUtility(Interface, name="layer")
    <Dummy utility>

The ``ZCMLSandbox`` class can also be used as ancestor for your own classes when you need to load more than a single ZCML file.

Your class then needs to override the ``setUpZCMLFiles()`` method.
It is in charge of calling ``loadZCMLFile()``, once for each ZCML file that the class needs to load.::

    >>> class OtherZCML(zca.ZCMLSandbox):
    ...     def setUpZCMLFiles(self):
    ...         self.loadZCMLFile("testing_zca.zcml", package=plone.testing)
    ...         self.loadZCMLFile("testing_zca_more_specific.zcml",
    ...             package=plone.testing)
    >>> OTHER_ZCML_SANDBOX = OtherZCML()

Before layer setup, a second utility is not registered.::

    >>> queryUtility(Interface, name="more_specific_layer") is None
    True

We'll now simulate the setup of the more specific layer.::

    >>> OTHER_ZCML_SANDBOX.setUp()

After setUp, the second utility is registered:::

    >>> queryUtility(Interface, name="more_specific_layer")
    <Dummy utility>

After layer teardown, the second utility is not registered anymore.::

    >>> OTHER_ZCML_SANDBOX.tearDown()
    >>> queryUtility(Interface, name="more_specific_layer") is None
    True

After teardown of the first layer, the first utility is not registered anymore.::

    >>> ZCML_SANDBOX.tearDown()
    >>> queryUtility(Interface, name="layer") is None
    True


Security
--------

The Zope Security layers are found in the module ``plone.testing.security``:::

    >>> from plone.testing import security

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

Layers
~~~~~~

The ``security.CHECKERS`` layer makes sure that ``zope.security`` checkers are correctly set up and torn down.::

    >>> "%s.%s" % (security.CHECKERS.__module__, security.CHECKERS.__name__,)
    'plone.testing.security.Checkers'

    >>> security.CHECKERS.__bases__
    ()

Before the test, our custom checker is not in the registry.::

    >>> class DummyObject(object):
    ...     pass

    >>> from zope.security.interfaces import IChecker
    >>> from zope.interface import implementer
    >>> @implementer(IChecker)
    ... class FauxChecker(object):
    ...     # we should really implement the interface here, but oh well
    ...     pass

    >>> from zope.security.checker import getCheckerForInstancesOf
    >>> getCheckerForInstancesOf(DummyObject) is None
    True

Layer setup stacks the current checkers.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, security.CHECKERS, setupLayers)
    Set up plone.testing.security.Checkers in ... seconds.

We can now set up a checker.
In real life, this may happen during ZCML configuration, but here will just call the API directlyMost likely, we'd do this in a child layer:::

    >>> from zope.security.checker import defineChecker
    >>> fauxChecker = FauxChecker()
    >>> defineChecker(DummyObject, fauxChecker)

    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker
    True

Let's now simulate a test that may use the checker.::

    >>> security.CHECKERS.testSetUp()
    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker
    True
    >>> security.CHECKERS.testTearDown()

We still have the checker after test tear-down:::

    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker
    True

However, when we tear down the layer, the checker is gone:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.security.Checkers in ... seconds.

    >>> getCheckerForInstancesOf(DummyObject) is None
    True


Zope Publisher layers
---------------------

The Zope Publisher layers are found in the module ``plone.testing.publisher``::

    >>> from plone.testing import publisher

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

ZCML directives
~~~~~~~~~~~~~~~

The ``publisher.PUBLISHER_DIRECTIVES`` layer extends the ``zca.ZCML_DIRECTIVES`` layer to extend its ZCML configuration context with the ``zope.app.publisher`` and ``zope.security`` directives available.
It also extends ``security.CHECKERS``.::

    >>> from plone.testing import zca, security

    >>> "%s.%s" % (publisher.PUBLISHER_DIRECTIVES.__module__, publisher.PUBLISHER_DIRECTIVES.__name__,)
    'plone.testing.publisher.PublisherDirectives'

    >>> publisher.PUBLISHER_DIRECTIVES.__bases__
    (<Layer 'plone.testing.zca.ZCMLDirectives'>, <Layer 'plone.testing.security.Checkers'>)

Before the test, we cannot use e.g.
the ``<permission />`` or ``<browser:view />`` directives without loading the necessary ``meta.zcml`` files.::

    >>> from zope.configuration import xmlconfig
    >>> from zope.configuration.exceptions import ConfigurationError
    >>> try:
    ...     xmlconfig.string("""\
    ...     <configure package="plone.testing"
    ...         xmlns="http://namespaces.zope.org/zope"
    ...         xmlns:browser="http://namespaces.zope.org/browser"
    ...         i18n_domain="plone.testing.tests">
    ...         <permission id="plone.testing.Test" title="plone.testing: Test" />
    ...         <browser:view
    ...             for="*"
    ...             name="plone.testing-test"
    ...             class="plone.testing.tests.DummyView"
    ...             permission="zope.Public"
    ...             />
    ...     </configure>""")
    ... except ConfigurationError as e:
    ...     True
    True

Layer setup creates a configuration context we can use to load further configuration.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, publisher.PUBLISHER_DIRECTIVES, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zca.ZCMLDirectives in ... seconds.
    Set up plone.testing.security.Checkers in ... seconds.
    Set up plone.testing.publisher.PublisherDirectives in ... seconds.


Let's now simulate a test that uses this configuration context to load the same ZCML string.::

    >>> zca.ZCML_DIRECTIVES.testSetUp()
    >>> security.CHECKERS.testSetUp()
    >>> publisher.PUBLISHER_DIRECTIVES.testSetUp()

    >>> context = zca.ZCML_DIRECTIVES['configurationContext'] # would normally be self.layer['configurationContext']
    >>> xmlconfig.string("""\
    ... <configure package="plone.testing"
    ...     xmlns="http://namespaces.zope.org/zope"
    ...     xmlns:browser="http://namespaces.zope.org/browser"
    ...     i18n_domain="plone.testing.tests">
    ...     <permission id="plone.testing.Test" title="plone.testing: Test" />
    ...     <browser:view
    ...         for="*"
    ...         name="plone.testing-test"
    ...         class="plone.testing.tests.DummyView"
    ...         permission="zope.Public"
    ...         />
    ... </configure>""", context=context) is context
    True

The permission and view are now registered:::

    >>> from zope.component import queryUtility
    >>> from zope.security.interfaces import IPermission

    >>> queryUtility(IPermission, name=u"plone.testing.Test")
    <zope.security.permission.Permission object at ...>

    >>> from zope.interface import Interface
    >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
    >>> from zope.component import getSiteManager
    >>> siteManager = getSiteManager()

    >>> [x.factory for x in siteManager.registeredAdapters()
    ...  if x.provided==Interface and x.required==(Interface, IDefaultBrowserLayer)
    ...   and x.name==u"plone.testing-test"]
    [<class '....plone.testing-test'>]

We can then simulate test tear-down:::

    >>> publisher.PUBLISHER_DIRECTIVES.testTearDown()
    >>> security.CHECKERS.testTearDown()
    >>> zca.ZCML_DIRECTIVES.testTearDown()

Note that you'd normally combine this layer with the ``zca.UNIT_TESTING`` or a similar layer to automatically tear down the component architecture between each test.
Here, we need to do it manually.::

    >>> from zope.component.testing import tearDown
    >>> tearDown()

Layer tear-down does nothing.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.publisher.PublisherDirectives in ... seconds.
    Tear down plone.testing.zca.ZCMLDirectives in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.
    Tear down plone.testing.security.Checkers in ... seconds.

    >>> zca.ZCML_DIRECTIVES.get('configurationContext', None) is None
    True


Zope Object Database layers
---------------------------

The ZODB layers are found in the module ``plone.testing.zodb``:::

    >>> from plone.testing import zodb

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

Empty ZODB layer
~~~~~~~~~~~~~~~~

The ``EMPTY_ZODB`` layer is used to set up an empty ZODB using ``DemoStorage``.

The storage and database are set up as layer fixtures.
The database is exposed as the resource ``zodbDB``.

A connection is opened for each test and exposed as ``zodbConnection``.
The ZODB root is also exposed, as ``zodbRoot``.
A new transaction is begun for each test.
On test tear-down, the transaction is aborted, the connection is closed, and the two test-specific resources are deleted.

The layer has no bases.::

    >>> "%s.%s" % (zodb.EMPTY_ZODB.__module__, zodb.EMPTY_ZODB.__name__,)
    'plone.testing.zodb.EmptyZODB'

    >>> zodb.EMPTY_ZODB.__bases__
    ()

Layer setup creates the database, but not a connection.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zodb.EMPTY_ZODB, setupLayers)
    Set up plone.testing.zodb.EmptyZODB in ... seconds.

    >>> db = zodb.EMPTY_ZODB['zodbDB']
    >>> db.storage
    EmptyZODB

    >>> zodb.EMPTY_ZODB.get('zodbConnection', None) is None
    True
    >>> zodb.EMPTY_ZODB.get('zodbRoot', None) is None
    True

Let's now simulate a test.::

    >>> zodb.EMPTY_ZODB.testSetUp()

The test would then execute. It may use the ZODB root.::

    >>> zodb.EMPTY_ZODB['zodbConnection']
    <...Connection...at ...>

    >>> zodb.EMPTY_ZODB['zodbRoot']
    {}

    >>> zodb.EMPTY_ZODB['zodbRoot']['foo'] = 'bar'

On test tear-down, the transaction is aborted and the connection is closed.::

    >>> zodb.EMPTY_ZODB.testTearDown()

    >>> zodb.EMPTY_ZODB.get('zodbConnection', None) is None
    True

    >>> zodb.EMPTY_ZODB.get('zodbRoot', None) is None
    True

The transaction has been rolled back.::

    >>> conn = zodb.EMPTY_ZODB['zodbDB'].open()
    >>> conn.root()
    {}
    >>> conn.close()

Layer tear-down closes and deletes the database.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zodb.EmptyZODB in ... seconds.

    >>> zodb.EMPTY_ZODB.get('zodbDB', None) is None
    True

Extending the ZODB layer
~~~~~~~~~~~~~~~~~~~~~~~~

When creating a test fixture, it is often desirable to add some initial data to the database.
If you want to do that once on layer setup, you can create your own layer class based on ``EmptyZODB`` and override its ``createStorage()`` and/or ``createDatabase()`` methods to return a pre-populated database.::

    >>> import transaction
    >>> from ZODB.DemoStorage import DemoStorage
    >>> from ZODB.DB import DB

    >>> class PopulatedZODB(zodb.EmptyZODB):
    ...
    ...     def createStorage(self):
    ...         return DemoStorage("My storage")
    ...
    ...     def createDatabase(self, storage):
    ...         db = DB(storage)
    ...         conn = db.open()
    ...
    ...         conn.root()['someData'] = 'a string'
    ...
    ...         transaction.commit()
    ...         conn.close()
    ...
    ...         return db

    >>> POPULATED_ZODB = PopulatedZODB()

We'll use this new layer in a similar manner to the test above, showing that the data is there for each test, but that other changes are rolled back.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, POPULATED_ZODB, setupLayers)
    Set up ...PopulatedZODB in ... seconds.

    >>> db = POPULATED_ZODB['zodbDB']
    >>> db.storage
    My storage

    >>> POPULATED_ZODB.get('zodbConnection', None) is None
    True
    >>> POPULATED_ZODB.get('zodbRoot', None) is None
    True

Let's now simulate a test.::

    >>> POPULATED_ZODB.testSetUp()

The test would then execute. It may use the ZODB root.::

    >>> POPULATED_ZODB['zodbConnection']
    <...Connection...at ...>

    >>> POPULATED_ZODB['zodbRoot']
    {'someData': 'a string'}

    >>> POPULATED_ZODB['zodbRoot']['foo'] = 'bar'

On test tear-down, the transaction is aborted and the connection is closed.::

    >>> POPULATED_ZODB.testTearDown()

    >>> POPULATED_ZODB.get('zodbConnection', None) is None
    True

    >>> POPULATED_ZODB.get('zodbRoot', None) is None
    True

The transaction has been rolled back.::

    >>> conn = POPULATED_ZODB['zodbDB'].open()
    >>> conn.root()
    {'someData': 'a string'}
    >>> conn.close()

Layer tear-down closes and deletes the database.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down ...PopulatedZODB in ... seconds.

    >>> POPULATED_ZODB.get('zodbDB', None) is None
    True

Stacking ``DemoStorage`` storages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The example above shows how to create a simple test fixture with a custom database.
It is sometimes useful to be able to stack these fixtures, so that a base layer sets up some data for one set of tests, and a child layer extends this, temporarily, with more data.

This can be achieved using layer bases and resource shadowing, combined with ZODB's stackable DemoStorage.
There is even a helper function available:::

    >>> from plone.testing import Layer
    >>> from plone.testing import zodb
    >>> import transaction

    >>> class ExpandedZODB(Layer):
    ...     defaultBases = (POPULATED_ZODB,)
    ...
    ...     def setUp(self):
    ...         # Get the database from the base layer
    ...
    ...         self['zodbDB'] = db = zodb.stackDemoStorage(self.get('zodbDB'), name='ExpandedZODB')
    ...
    ...         conn = db.open()
    ...         conn.root()['additionalData'] = "Some new data"
    ...         transaction.commit()
    ...         conn.close()
    ...
    ...     def tearDown(self):
    ...         # Close the database and delete the shadowed copy
    ...
    ...         self['zodbDB'].close()
    ...         del self['zodbDB']

    >>> EXPANDED_ZODB = ExpandedZODB()

Notice that we are using plain ``Layer`` as a base class here.
We obtain the underlying database from our bases using the resource manager, and then create a shadow copy using a stacked storage.
Stacked storages contain the data of the original storage, but save changes in a separate (and, in this case, temporary) storage.

Let's simulate a test run again to show how this would work.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, EXPANDED_ZODB, setupLayers)
    Set up ...PopulatedZODB in ... seconds.
    Set up ...ExpandedZODB in ... seconds.

    >>> db = EXPANDED_ZODB['zodbDB']
    >>> db.storage
    ExpandedZODB

    >>> EXPANDED_ZODB.get('zodbConnection', None) is None
    True
    >>> EXPANDED_ZODB.get('zodbRoot', None) is None
    True

Let's now simulate a test.::

    >>> POPULATED_ZODB.testSetUp()
    >>> EXPANDED_ZODB.testSetUp()

The test would then execute. It may use the ZODB root.::

    >>> EXPANDED_ZODB['zodbConnection']
    <...Connection...at ...>

    >>> EXPANDED_ZODB['zodbRoot'] == dict(someData='a string', additionalData='Some new data')
    True

    >>> POPULATED_ZODB['zodbRoot']['foo'] = 'bar'

On test tear-down, the transaction is aborted and the connection is closed.::

    >>> EXPANDED_ZODB.testTearDown()
    >>> POPULATED_ZODB.testTearDown()

    >>> EXPANDED_ZODB.get('zodbConnection', None) is None
    True

    >>> EXPANDED_ZODB.get('zodbRoot', None) is None
    True

The transaction has been rolled back.::

    >>> conn = EXPANDED_ZODB['zodbDB'].open()
    >>> conn.root() == dict(someData='a string', additionalData='Some new data')
    True
    >>> conn.close()

We'll now tear down the expanded layer and inspect the database again.::

    >>> runner.tear_down_unneeded(options, [POPULATED_ZODB], setupLayers, [])
    Tear down ...ExpandedZODB in ... seconds.

    >>> conn = EXPANDED_ZODB['zodbDB'].open()
    >>> conn.root()
    {'someData': 'a string'}

    >>> conn.close()

Finally, we'll tear down the rest of the layers.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down ...PopulatedZODB in ... seconds.

    >>> EXPANDED_ZODB.get('zodbDB', None) is None
    True
    >>> POPULATED_ZODB.get('zodbDB', None) is None
    True


Zope WSGI layers
----------------

The Zope WSGI layers are found in the module ``plone.testing.zope``:::

    >>> from plone.testing import zope

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

Startup
~~~~~~~

``STARTUP`` is the base layer for all Zope WSGI testing.
It sets up a Zope WSGI sandbox environment that is suitable for testing.
It extends the ``zca.LAYER_CLEANUP`` layer to maximise the chances of having and leaving a pristine environment.

**Note**: You should probably use at least ``INTEGRATION_TESTING`` for any real test, although ``STARTUP`` is a useful base layer if you are setting up your own fixture.
See the description of ``INTEGRATION_TESTING`` below.::

    >>> "%s.%s" % (zope.STARTUP.__module__, zope.STARTUP.__name__,)
    'plone.testing.zope.Startup'

    >>> zope.STARTUP.__bases__
    (<Layer 'plone.testing.zca.LayerCleanup'>,)

On layer setup, Zope is initialised in a lightweight manner.
This involves certain patches to global modules that Zope manages, to reduce setup time, a database based on ``DemoStorage``, and a minimal set of products that must be installed for Zope 2 to work.
A minimal set of ZCML is loaded, but packages in the ``Products`` namespace are not automatically configured.

Let's just verify that we have an empty component registry before the test:::

    >>> from zope.component import getSiteManager
    >>> list(getSiteManager().registeredAdapters())
    []

Five sets a special vocabulary registry upon the layer setup, but there's a default one set before:::

    >>> from zope.schema.vocabulary import getVocabularyRegistry
    >>> getVocabularyRegistry()
    <zope.schema.vocabulary.VocabularyRegistry object ...>

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zope.STARTUP, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zope.Startup in ... seconds.

After layer setup, the ``zodbDB`` resource is available, pointing to the default ZODB.::

    >>> zope.STARTUP['zodbDB']
    <ZODB.DB.DB object at ...>

    >>> zope.STARTUP['zodbDB'].storage
    Startup

In addition, the resources ``host`` and ``port`` are set to the default hostname and port that are used for URLs generated from Zope.
These are hardcoded, but shadowed by layers that provide actual running Zope instances.::

    >>> zope.STARTUP['host']
    'nohost'
    >>> zope.STARTUP['port']
    80

At this point, it is also possible to get hold of a Zope application root.
If you are setting up a layer fixture, you can obtain an application root with the correct database that is properly closed by using the ``zopeApp()`` context manager.::

    >>> with zope.zopeApp() as app:
    ...     'acl_users' in app.objectIds()
    True

If you want to use a specific database, you can pass that to ``zopeApp()`` as the ``db`` parameter.
A new connection will be opened and closed.::

    >>> with zope.zopeApp(db=zope.STARTUP['zodbDB']) as app:
    ...     'acl_users' in app.objectIds()
    True

If you want to reuse an existing connection, you can pass one to ``zopeApp()`` as the ``connection`` argument.
In this case, you will need to close the connection yourself.::

    >>> conn = zope.STARTUP['zodbDB'].open()
    >>> with zope.zopeApp(connection=conn) as app:
    ...     'acl_users' in app.objectIds()
    True

    >>> conn.opened is not None
    True

    >>> conn.close()

If an exception is raised within the ``with`` block, the transaction is aborted, but the connection is still closed (if it was opened by the context manager):::

    >>> with zope.zopeApp() as app:
    ...     raise Exception("Test error")
    Traceback (most recent call last):
    ...
    Exception: Test error

It is common to combine the ``zopeApp()`` context manager with a stacked ``DemoStorage`` to set up a layer-specific fixture.
As a sketch:::

    from plone.testing import Layer, zope, zodb

    class MyLayer(Layer):
        defaultBases = (zope.STARTUP,)

        def setUp(self):
            self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')
            with zope.zopeApp() as app:

                # Set up a fixture, e.g.:
                app.manage_addFolder('folder1')
                folder = app['folder1']
                folder._addRole('role1')
                folder.manage_addUserFolder()

                userFolder = folder['acl_users']
                ignore = userFolder.userFolderAddUser('user1', 'secret', ['role1'], [])
                folder.manage_role('role1', ('Access contents information',))

        def tearDown(self):
            self['zodbDB'].close()
            del self['zodbDB']

Note that you would normally *not* use the ``zope.zopeApp()`` in a test or in a ``testSetUp()`` or ``testTearDown()`` method.
The ``IntegrationTesting`` and ``FunctionalTesting`` layer classes manage the application object for you, exposing them as the resource ``app`` (see below).

After layer setup, the global component registry contains a number of components needed by Zope.::

    >>> len(list(getSiteManager().registeredAdapters())) > 1 # in fact, > a lot
    True

And Five has set a ``Zope2VocabularyRegistry`` vocabulary registry:::

    >>> getVocabularyRegistry()
    <....Zope2VocabularyRegistry object at ...>

To load additional ZCML, you can use the ``configurationContext`` resource:::

    >>> zope.STARTUP['configurationContext']
    <zope.configuration.config.ConfigurationMachine object ...>

See ``zca.rst`` for details about how to use ``zope.configuration`` for this purpose.

The ``STARTUP`` layer does not perform any specific test setup or tear-down.
That is left up to the ``INTEGRATION_TESTING`` and ``FUNCTIONAL_TESTING`` layers, or other layers using their layer classes - ``IntegrationTesting`` and ``FunctionalTesting``.::

    >>> zope.STARTUP.testSetUp()
    >>> zope.STARTUP.testTearDown()

Layer tear-down resets the environment.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zope.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

    >>> import Zope2
    >>> Zope2._began_startup
    0
    >>> Zope2.DB is None
    True
    >>> Zope2.bobo_application is None
    True

    >>> list(getSiteManager().registeredAdapters())
    []

    >>> getVocabularyRegistry()
    <zope.schema.vocabulary.VocabularyRegistry object at ...>

Integration test
~~~~~~~~~~~~~~~~

``INTEGRATION_TESTING`` is intended for simple Zope WSGI integration testing.
It extends ``STARTUP`` to ensure that a transaction is begun before and rolled back after each test.
Two resources, ``app`` and ``request``, are available during testing as well.
It does not manage any layer state - it implements the test lifecycle methods only.

**Note:** You would normally *not* use ``INTEGRATION_TESTING`` as a base layer.
Instead, you'd use the ``IntegrationTesting`` class to create your own layer with the testing lifecycle semantics of ``INTEGRATION_TESTING``.
See the ``plone.testing`` ``README`` file for an example.

``app`` is the application root.
In a test, you should use this instead of the ``zopeApp`` context manager (which remains the weapon of choice for setting up persistent fixtures), because the ``app`` resource is part of the transaction managed by the layer.

``request`` is a test request. It is the same as ``app.REQUEST``.::

    >>> "%s.%s" % (zope.INTEGRATION_TESTING.__module__, zope.INTEGRATION_TESTING.__name__,)
    'plone.testing.zope.IntegrationTesting'

    >>> zope.INTEGRATION_TESTING.__bases__
    (<Layer 'plone.testing.zope.Startup'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zope.INTEGRATION_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zope.Startup in ... seconds.
    Set up plone.testing.zope.IntegrationTesting in ... seconds.

Let's now simulate a test.
On test setup, the ``app`` resource is made available.
In a test, you should always use this to access the application root.::

    >>> zope.STARTUP.testSetUp()
    >>> zope.INTEGRATION_TESTING.testSetUp()

The test may now inspect and modify the environment.::

    >>> app = zope.INTEGRATION_TESTING['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')
    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()
    True

The request is also available:::

    >>> zope.INTEGRATION_TESTING['request'] # would normally be self.layer['request']
    <HTTPRequest, URL=http://nohost>

We can create a user and simulate logging in as that user, using the ``zope.login()`` helper:::

    >>> app._addRole('role1')
    >>> ignore = app['acl_users'].userFolderAddUser('user1', 'secret', ['role1'], [])
    >>> zope.login(app['acl_users'], 'user1')

The first argument to ``zope.login()`` is the user folder that contains the relevant user.
The second argument is the user's name.
There is no need to give the password.::

    >>> from AccessControl import getSecurityManager
    >>> getSecurityManager().getUser()
    <User 'user1'>

You can change the roles of a user using the ``zope.setRoles()`` helper:::

    >>> sorted(getSecurityManager().getUser().getRolesInContext(app))
    ['Authenticated', 'role1']

    >>> zope.setRoles(app['acl_users'], 'user1', [])
    >>> getSecurityManager().getUser().getRolesInContext(app)
    ['Authenticated']

To become the anonymous user again, use ``zope.logout()``:::

    >>> zope.logout()
    >>> getSecurityManager().getUser()
    <SpecialUser 'Anonymous User'>

On tear-down, the transaction is rolled back:::

    >>> zope.INTEGRATION_TESTING.testTearDown()
    >>> zope.STARTUP.testTearDown()

    >>> 'app' in zope.INTEGRATION_TESTING
    False

    >>> 'request' in zope.INTEGRATION_TESTING
    False

    >>> with zope.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True


Let's tear down the layers:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zope.IntegrationTesting in ... seconds.
    Tear down plone.testing.zope.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

Functional testing
~~~~~~~~~~~~~~~~~~

The ``FUNCTIONAL_TESTING`` layer is very similar to ``INTEGRATION_TESTING``, and exposes the same fixture and resources.
However, it has different transaction semantics.
``INTEGRATION_TESTING`` creates a single database storage, and rolls back the transaction after each test.
``FUNCTIONAL_TESTING`` creates a whole new database storage (stacked on top of the basic fixture) for each test.
This allows testing of code that performs an explicit commit, which is usually required for end-to-end testing.
The downside is that the set-up and tear-down of each test takes longer.

**Note:** Again, you would normally *not* use ``FUNCTIONAL_TESTING`` as a base layer.
Instead, you'd use the ``FunctionalTesting`` class to create your own layer with the testing lifecycle semantics of ``FUNCTIONAL_TESTING``.
See the ``plone.testing`` ``README`` file for an example.

Like ``INTEGRATION_TESTING``, ``FUNCTIONAL_TESTING`` is based on ``STARTUP``.::

    >>> "%s.%s" % (zope.FUNCTIONAL_TESTING.__module__, zope.FUNCTIONAL_TESTING.__name__,)
    'plone.testing.zope.FunctionalTesting'

    >>> zope.FUNCTIONAL_TESTING.__bases__
    (<Layer 'plone.testing.zope.Startup'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zope.FUNCTIONAL_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zope.Startup in ... seconds.
    Set up plone.testing.zope.FunctionalTesting in ... seconds.

Let's now simulate a test.
On test setup, the ``app`` resource is made available.
In a test, you should always use this to access the application root.
The ``request`` resource can be used to access the test request.::

    >>> zope.STARTUP.testSetUp()
    >>> zope.FUNCTIONAL_TESTING.testSetUp()

The test may now inspect and modify the environment.
It may also commit things.::

    >>> app = zope.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')
    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()
    True

    >>> import transaction
    >>> transaction.commit()

On tear-down, the database is torn down.::

    >>> zope.FUNCTIONAL_TESTING.testTearDown()
    >>> zope.STARTUP.testTearDown()

    >>> 'app' in zope.FUNCTIONAL_TESTING
    False

    >>> 'request' in zope.FUNCTIONAL_TESTING
    False

    >>> with zope.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True

Let's tear down the layer:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zope.FunctionalTesting in ... seconds.
    Tear down plone.testing.zope.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

The test browser
~~~~~~~~~~~~~~~~

The ``FUNCTIONAL_TESTING`` layer and ``FunctionalTesting`` layer class are the basis for functional testing using ``zope.testbrowser``.
This simulates a web browser, allowing an application to be tested "end-to-end" via its user-facing interface.

To use the test browser with a ``FunctionalTesting`` layer (such as the default ``FUNCTIONAL_TESTING`` layer instance), we need to use a custom browser client, which ensures that the test browser uses the correct ZODB and is appropriately isolated from the test code.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zope.FUNCTIONAL_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zope.Startup in ... seconds.
    Set up plone.testing.zope.FunctionalTesting in ... seconds.

Let's simulate a test:::

    >>> zope.STARTUP.testSetUp()
    >>> zope.FUNCTIONAL_TESTING.testSetUp()

In the test, we can create a test browser client like so:::

    >>> app = zope.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']
    >>> browser = zope.Browser(app)

It is usually best to let Zope errors be shown with full tracebacks:::

    >>> browser.handleErrors = False

We can add to the test fixture in the test.
For those changes to be visible to the test browser, however, we need to commit the transaction.::

    >>> _ = app.manage_addDTMLDocument('dtml-doc-1')
    >>> import transaction; transaction.commit()

We can now view this via the test browser:::

    >>> browser.open(app.absolute_url() + '/dtml-doc-1')
    >>> 'This is the dtml-doc-1 Document.' in browser.contents
    True

The test browser integration converts the URL into a request and passes control to Zope's publisher.
Let's check that query strings are available for input processing:::

    >>> from urllib.parse import urlencode
    >>> _ = app.manage_addDTMLDocument('dtml-doc-2', file='<dtml-var foo>')
    >>> import transaction; transaction.commit()
    >>> qs = urlencode({'foo': 'boo, bar & baz'})  # sic: the ampersand.
    >>> browser.open(app.absolute_url() + '/dtml-doc-2?' + qs)
    >>> browser.contents
    'boo, bar & baz'

The test browser also works with iterators.
Let's test that with a simple file implementation that uses an iterator.::

    >>> from plone.testing.tests import DummyFile
    >>> app._setObject('file1', DummyFile('file1'))
    'file1'

    >>> import transaction; transaction.commit()

    >>> browser.open(app.absolute_url() + '/file1')
    >>> 'The test browser also works with iterators' in browser.contents
    True

See the ``zope.testbrowser`` documentation for more information about how to use the browser client.

On tear-down, the database is torn down.::

    >>> zope.FUNCTIONAL_TESTING.testTearDown()
    >>> zope.STARTUP.testTearDown()

    >>> 'app' in zope.FUNCTIONAL_TESTING
    False

    >>> 'request' in zope.FUNCTIONAL_TESTING
    False

    >>> with zope.zopeApp() as app:
    ...     'acl_users' in app.objectIds()\
    ...         and 'folder1' not in app.objectIds()\
    ...         and 'file1' not in app.objectIds()
    True

Let's tear down the layer:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zope.FunctionalTesting in ... seconds.
    Tear down plone.testing.zope.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

HTTP server
~~~~~~~~~~~

The ``WSGI_SERVER_FIXTURE`` layer extends ``STARTUP`` to start a single-threaded Zope server in a separate thread.
This makes it possible to connect to the test instance using a web browser or a testing tool like Selenium or Windmill.

The ``WSGI_SERVER`` layer provides a ``FunctionalTesting`` layer that has ``WSGI_SERVER_FIXTURE`` as its base.::

    >>> "%s.%s" % (zope.WSGI_SERVER_FIXTURE.__module__, zope.WSGI_SERVER_FIXTURE.__name__,)
    'plone.testing.zope.WSGIServer'

    >>> zope.WSGI_SERVER_FIXTURE.__bases__
    (<Layer 'plone.testing.zope.Startup'>,)


    >>> "%s.%s" % (zope.WSGI_SERVER.__module__, zope.WSGI_SERVER.__name__,)
    'plone.testing.zope.WSGIServer:Functional'

    >>> zope.WSGI_SERVER.__bases__
    (<Layer 'plone.testing.zope.WSGIServer'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zope.WSGI_SERVER, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zope.Startup in ... seconds.
    Set up plone.testing.zope.WSGIServer in ... seconds.
    Set up plone.testing.zope.WSGIServer:Functional in ... seconds.

After layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::

    >>> host = zope.WSGI_SERVER['host']
    >>> host
    'localhost'

    >>> port = zope.WSGI_SERVER['port']

Let's now simulate a test.
Test setup does nothing beyond what the base layers do.::

    >>> zope.STARTUP.testSetUp()
    >>> zope.FUNCTIONAL_TESTING.testSetUp()
    >>> zope.WSGI_SERVER.testSetUp()

It is common in a test to use the Python API to change the state of the server (e.g.
create some content or change a setting) and then use the HTTP protocol to look at the results.
Bear in mind that the server is running in a separate thread, with a separate security manager, so calls to ``zope.login()`` and ``zope.logout()``, for instance, do not affect the server thread.::

    >>> app = zope.WSGI_SERVER['app'] # would normally be self.layer['app']
    >>> _ = app.manage_addDTMLDocument('dtml-doc-3')

Note that we need to commit the transaction before it will show up in the other thread.::

    >>> import transaction; transaction.commit()

We can now look for this new object through the server.::

    >>> app_url = app.absolute_url()
    >>> app_url.split(':')[:-1]
    ['http', '//localhost']

    >>> from urllib.request import urlopen
    >>> conn = urlopen(app_url + '/dtml-doc-3', timeout=5)
    >>> b'This is the dtml-doc-3 Document.' in conn.read()
    True
    >>> conn.close()

Test tear-down does nothing beyond what the base layers do.::

    >>> zope.WSGI_SERVER.testTearDown()
    >>> zope.FUNCTIONAL_TESTING.testTearDown()
    >>> zope.STARTUP.testTearDown()

    >>> 'app' in zope.WSGI_SERVER
    False

    >>> 'request' in zope.WSGI_SERVER
    False

    >>> with zope.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True

When the server is torn down, the WSGIServer thread is stopped.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zope.WSGIServer:Functional in ... seconds.
    Tear down plone.testing.zope.WSGIServer in ... seconds.
    Tear down plone.testing.zope.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

We can expect one of these exceptions:
- URLError: <urlopen error [Errno ...] Connection refused>
- error: [Errno 104] Connection reset by peer

    >>> try:
    ...     conn = urlopen(app_url + '/folder1', timeout=5)
    ... except Exception as exc:
    ...     if 'Connection refused' not in str(exc) and 'Connection reset' not in str(exc):
    ...         raise exc
    ... else:
    ...     print('urlopen should have raised exception')


Zope 2 layers
-------------

The Zope 2 layers are found in the module ``plone.testing.zserver``:::

    >>> from plone.testing import zserver

For testing, we need a testrunner:::

    >>> from zope.testrunner import runner

Startup
~~~~~~~

``STARTUP`` is the base layer for all Zope 2 testing.
It sets up a Zope 2 sandbox environment that is suitable for testing.
It extends the ``zca.LAYER_CLEANUP`` layer to maximise the chances of having and leaving a pristine environment.

**Note**: You should probably use at least ``INTEGRATION_TESTING`` for any real test, although ``STARTUP`` is a useful base layer if you are setting up your own fixture.
See the description of ``INTEGRATION_TESTING`` below.::

    >>> "%s.%s" % (zserver.STARTUP.__module__, zserver.STARTUP.__name__,)
    'plone.testing.zserver.Startup'

    >>> zserver.STARTUP.__bases__
    (<Layer 'plone.testing.zca.LayerCleanup'>,)

On layer setup, Zope is initialised in a lightweight manner.
This involves certain patches to global modules that Zope manages, to reduce setup time, a database based on ``DemoStorage``, and a minimal set of products that must be installed for Zope 2 to work.
A minimal set of ZCML is loaded, but packages in the ``Products`` namespace are not automatically configured.

Let's just verify that we have an empty component registry before the test:::

    >>> from zope.component import getSiteManager
    >>> list(getSiteManager().registeredAdapters())
    []

Five sets a special vocabulary registry upon the layer setup, but there's a default one set before:::

    >>> from zope.schema.vocabulary import getVocabularyRegistry
    >>> getVocabularyRegistry()
    <zope.schema.vocabulary.VocabularyRegistry object ...>

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.STARTUP, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.

After layer setup, the ``zodbDB`` resource is available, pointing to the default ZODB.::

    >>> zserver.STARTUP['zodbDB']
    <ZODB.DB.DB object at ...>

    >>> zserver.STARTUP['zodbDB'].storage
    Startup

In addition, the resources ``host`` and ``port`` are set to the default hostname and port that are used for URLs generated from Zope.
These are hardcoded, but shadowed by layers that provide actual running Zope instances.::

    >>> zserver.STARTUP['host']
    'nohost'
    >>> zserver.STARTUP['port']
    80

At this point, it is also possible to get hold of a Zope application root.
If you are setting up a layer fixture, you can obtain an application root with the correct database that is properly closed by using the ``zopeApp()`` context manager.::

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds()
    True

If you want to use a specific database, you can pass that to ``zopeApp()`` as the ``db`` parameter.
A new connection will be opened and closed.::

    >>> with zserver.zopeApp(db=zserver.STARTUP['zodbDB']) as app:
    ...     'acl_users' in app.objectIds()
    True

If you want to reuse an existing connection, you can pass one to ``zopeApp()`` as the ``connection`` argument.
In this case, you will need to close the connection yourself.::

    >>> conn = zserver.STARTUP['zodbDB'].open()
    >>> with zserver.zopeApp(connection=conn) as app:
    ...     'acl_users' in app.objectIds()
    True

    >>> conn.opened is not None
    True

    >>> conn.close()

If an exception is raised within the ``with`` block, the transaction is aborted, but the connection is still closed (if it was opened by the context manager):::

    >>> with zserver.zopeApp() as app:
    ...     raise Exception("Test error")
    Traceback (most recent call last):
    ...
    Exception: Test error

It is common to combine the ``zopeApp()`` context manager with a stacked ``DemoStorage`` to set up a layer-specific fixture.
As a sketch:::

    from plone.testing import Layer, zserver, zodb

    class MyLayer(Layer):
        defaultBases = (zserver.STARTUP,)

        def setUp(self):
            self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')
            with zserver.zopeApp() as app:

                # Set up a fixture, e.g.:
                app.manage_addFolder('folder1')
                folder = app['folder1']
                folder._addRole('role1')
                folder.manage_addUserFolder()

                userFolder = folder['acl_users']
                ignore = userFolder.userFolderAddUser('user1', 'secret', ['role1'], [])
                folder.manage_role('role1', ('Access contents information',))

        def tearDown(self):
            self['zodbDB'].close()
            del self['zodbDB']

Note that you would normally *not* use the ``zserver.zopeApp()`` in a test or in a ``testSetUp()`` or ``testTearDown()`` method.
The ``IntegrationTesting`` and ``FunctionalTesting`` layer classes manage the application object for you, exposing them as the resource ``app`` (see below).

After layer setup, the global component registry contains a number of components needed by Zope.::

    >>> len(list(getSiteManager().registeredAdapters())) > 1 # in fact, > a lot
    True

And Five has set a ``Zope2VocabularyRegistry`` vocabulary registry:::

    >>> getVocabularyRegistry()
    <....Zope2VocabularyRegistry object at ...>

To load additional ZCML, you can use the ``configurationContext`` resource:::

    >>> zserver.STARTUP['configurationContext']
    <zope.configuration.config.ConfigurationMachine object ...>

See ``zca.rst`` for details about how to use ``zope.configuration`` for this purpose.

The ``STARTUP`` layer does not perform any specific test setup or tear-down.
That is left up to the ``INTEGRATION_TESTING`` and ``FUNCTIONAL_TESTING`` layers, or other layers using their layer classes - ``IntegrationTesting`` and ``FunctionalTesting``.::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.STARTUP.testTearDown()

Layer tear-down resets the environment.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

    >>> import ZServer.Zope2
    >>> ZServer.Zope2._began_startup
    0
    >>> import Zope2
    >>> Zope2.DB is None
    True
    >>> Zope2.bobo_application is None
    True

    >>> list(getSiteManager().registeredAdapters())
    []

    >>> getVocabularyRegistry()
    <zope.schema.vocabulary.VocabularyRegistry object at ...>

Integration test
~~~~~~~~~~~~~~~~

``INTEGRATION_TESTING`` is intended for simple Zope 2 integration testing.
It extends ``STARTUP`` to ensure that a transaction is begun before and rolled back after each test.
Two resources, ``app`` and ``request``, are available during testing as well.
It does not manage any layer state - it implements the test lifecycle methods only.

**Note:** You would normally *not* use ``INTEGRATION_TESTING`` as a base layer.
Instead, you'd use the ``IntegrationTesting`` class to create your own layer with the testing lifecycle semantics of ``INTEGRATION_TESTING``.
See the ``plone.testing`` ``README`` file for an example.

``app`` is the application root.
In a test, you should use this instead of the ``zopeApp`` context manager (which remains the weapon of choice for setting up persistent fixtures), because the ``app`` resource is part of the transaction managed by the layer.

``request`` is a test request. It is the same as ``app.REQUEST``.::

    >>> "%s.%s" % (zserver.INTEGRATION_TESTING.__module__, zserver.INTEGRATION_TESTING.__name__,)
    'plone.testing.zserver.IntegrationTesting'

    >>> zserver.INTEGRATION_TESTING.__bases__
    (<Layer 'plone.testing.zserver.Startup'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.INTEGRATION_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.
    Set up plone.testing.zserver.IntegrationTesting in ... seconds.

Let's now simulate a test.
On test setup, the ``app`` resource is made available.
In a test, you should always use this to access the application root.::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.INTEGRATION_TESTING.testSetUp()

The test may now inspect and modify the environment.::

    >>> app = zserver.INTEGRATION_TESTING['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')
    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()
    True

The request is also available:::

    >>> zserver.INTEGRATION_TESTING['request'] # would normally be self.layer['request']
    <HTTPRequest, URL=http://nohost>

We can create a user and simulate logging in as that user, using the ``zserver.login()`` helper:::

    >>> app._addRole('role1')
    >>> ignore = app['acl_users'].userFolderAddUser('user1', 'secret', ['role1'], [])
    >>> zserver.login(app['acl_users'], 'user1')

The first argument to ``zserver.login()`` is the user folder that contains the relevant user.
The second argument is the user's name.
There is no need to give the password.::

    >>> from AccessControl import getSecurityManager
    >>> getSecurityManager().getUser()
    <User 'user1'>

You can change the roles of a user using the ``zserver.setRoles()`` helper:::

    >>> sorted(getSecurityManager().getUser().getRolesInContext(app))
    ['Authenticated', 'role1']

    >>> zserver.setRoles(app['acl_users'], 'user1', [])
    >>> getSecurityManager().getUser().getRolesInContext(app)
    ['Authenticated']

To become the anonymous user again, use ``zserver.logout()``:::

    >>> zserver.logout()
    >>> getSecurityManager().getUser()
    <SpecialUser 'Anonymous User'>

On tear-down, the transaction is rolled back:::

    >>> zserver.INTEGRATION_TESTING.testTearDown()
    >>> zserver.STARTUP.testTearDown()

    >>> 'app' in zserver.INTEGRATION_TESTING
    False

    >>> 'request' in zserver.INTEGRATION_TESTING
    False

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True


Let's tear down the layers:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.IntegrationTesting in ... seconds.
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

Functional testing
~~~~~~~~~~~~~~~~~~

The ``FUNCTIONAL_TESTING`` layer is very similar to ``INTEGRATION_TESTING``, and exposes the same fixture and resources.
However, it has different transaction semantics.
``INTEGRATION_TESTING`` creates a single database storage, and rolls back the transaction after each test.
``FUNCTIONAL_TESTING`` creates a whole new database storage (stacked on top of the basic fixture) for each test.
This allows testing of code that performs an explicit commit, which is usually required for end-to-end testing.
The downside is that the set-up and tear-down of each test takes longer.

**Note:** Again, you would normally *not* use ``FUNCTIONAL_TESTING`` as a base layer.
Instead, you'd use the ``FunctionalTesting`` class to create your own layer with the testing lifecycle semantics of ``FUNCTIONAL_TESTING``.
See the ``plone.testing`` ``README`` file for an example.

Like ``INTEGRATION_TESTING``, ``FUNCTIONAL_TESTING`` is based on ``STARTUP``.::

    >>> "%s.%s" % (zserver.FUNCTIONAL_TESTING.__module__, zserver.FUNCTIONAL_TESTING.__name__,)
    'plone.testing.zserver.FunctionalTesting'

    >>> zserver.FUNCTIONAL_TESTING.__bases__
    (<Layer 'plone.testing.zserver.Startup'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.FUNCTIONAL_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.
    Set up plone.testing.zserver.FunctionalTesting in ... seconds.

Let's now simulate a test.
On test setup, the ``app`` resource is made available.
In a test, you should always use this to access the application root.
The ``request`` resource can be used to access the test request.::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.FUNCTIONAL_TESTING.testSetUp()

The test may now inspect and modify the environment.
It may also commit things.::

    >>> app = zserver.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')
    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()
    True

    >>> import transaction
    >>> transaction.commit()

On tear-down, the database is torn down.::

    >>> zserver.FUNCTIONAL_TESTING.testTearDown()
    >>> zserver.STARTUP.testTearDown()

    >>> 'app' in zserver.FUNCTIONAL_TESTING
    False

    >>> 'request' in zserver.FUNCTIONAL_TESTING
    False

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True

Let's tear down the layer:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.FunctionalTesting in ... seconds.
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

The test browser
~~~~~~~~~~~~~~~~

The ``FUNCTIONAL_TESTING`` layer and ``FunctionalTesting`` layer class are the basis for functional testing using ``zope.testbrowser``.
This simulates a web browser, allowing an application to be tested "end-to-end" via its user-facing interface.

To use the test browser with a ``FunctionalTesting`` layer (such as the default ``FUNCTIONAL_TESTING`` layer instance), we need to use a custom browser client, which ensures that the test browser uses the correct ZODB and is appropriately isolated from the test code.::

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.FUNCTIONAL_TESTING, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.
    Set up plone.testing.zserver.FunctionalTesting in ... seconds.

Let's simulate a test:::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.FUNCTIONAL_TESTING.testSetUp()

In the test, we can create a test browser client like so:::

    >>> app = zserver.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']
    >>> browser = zserver.Browser(app)

It is usually best to let Zope errors be shown with full tracebacks:::

    >>> browser.handleErrors = False

We can add to the test fixture in the test.
For those changes to be visible to the test browser, however, we need to commit the transaction.::

    >>> app.manage_addFolder('folder1')
    >>> import transaction; transaction.commit()

We can now view this via the test browser:::

    >>> browser.open(app.absolute_url() + '/folder1')

    >>> browser.contents.replace('"', '').replace("'", "")
    '<Folder ...'

The __repr__ of Zope objects is not stable anymore.

The test browser integration converts the URL into a request and passes control to Zope's publisher.
Let's check that query strings are available for input processing:::

    >>> import urllib
    >>> qs = urllib.urlencode({'foo': 'boo, bar & baz'})  # sic: the ampersand.
    >>> _ = app['folder1'].addDTMLMethod('index_html', file='<dtml-var foo>')
    >>> import transaction; transaction.commit()
    >>> browser.open(app.absolute_url() + '/folder1?' + qs)
    >>> browser.contents
    'boo, bar & baz'

The test browser also works with iterators.
Let's test that with a simple file implementation that uses an iterator.::

    >>> from plone.testing.tests import DummyFile
    >>> app._setObject('file1', DummyFile('file1'))
    'file1'

    >>> import transaction; transaction.commit()

    >>> browser.open(app.absolute_url() + '/file1')
    >>> 'The test browser also works with iterators' in browser.contents
    True

See the ``zope.testbrowser`` documentation for more information about how to use the browser client.

On tear-down, the database is torn down.::

    >>> zserver.FUNCTIONAL_TESTING.testTearDown()
    >>> zserver.STARTUP.testTearDown()

    >>> 'app' in zserver.FUNCTIONAL_TESTING
    False

    >>> 'request' in zserver.FUNCTIONAL_TESTING
    False

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds()\
    ...         and 'folder1' not in app.objectIds()\
    ...         and 'file1' not in app.objectIds()
    True

Let's tear down the layer:::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.FunctionalTesting in ... seconds.
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

HTTP server
~~~~~~~~~~~

The ``ZSERVER_FIXTURE`` layer extends ``STARTUP`` to start a single-threaded Zope server in a separate thread.
This makes it possible to connect to the test instance using a web browser or a testing tool like Selenium or Windmill.

The ``ZSERVER`` layer provides a ``FunctionalTesting`` layer that has ``ZSERVER_FIXTURE`` as its base.::

    >>> "%s.%s" % (zserver.ZSERVER_FIXTURE.__module__, zserver.ZSERVER_FIXTURE.__name__,)
    'plone.testing.zserver.ZServer'

    >>> zserver.ZSERVER_FIXTURE.__bases__
    (<Layer 'plone.testing.zserver.Startup'>,)


    >>> "%s.%s" % (zserver.ZSERVER.__module__, zserver.ZSERVER.__name__,)
    'plone.testing.zserver.ZServer:Functional'

    >>> zserver.ZSERVER.__bases__
    (<Layer 'plone.testing.zserver.ZServer'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.ZSERVER, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.
    Set up plone.testing.zserver.ZServer in ... seconds.
    Set up plone.testing.zserver.ZServer:Functional in ... seconds.

After layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::

    >>> host = zserver.ZSERVER['host']
    >>> port = zserver.ZSERVER['port']

Let's now simulate a test.
Test setup does nothing beyond what the base layers do.::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.FUNCTIONAL_TESTING.testSetUp()
    >>> zserver.ZSERVER.testSetUp()

It is common in a test to use the Python API to change the state of the server (e.g.
create some content or change a setting) and then use the HTTP protocol to look at the results.
Bear in mind that the server is running in a separate thread, with a separate security manager, so calls to ``zserver.login()`` and ``zserver.logout()``, for instance, do not affect the server thread.::

    >>> app = zserver.ZSERVER['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')

Note that we need to commit the transaction before it will show up in the other thread.::

    >>> import transaction; transaction.commit()

We can now look for this new object through the server.::

    >>> app_url = app.absolute_url()
    >>> app_url.split(':')[:-1]
    ['http', '//localhost']

    >>> import urllib2
    >>> conn = urllib2.urlopen(app_url + '/folder1', timeout=5)
    >>> conn.read().replace('"', '').replace("'", "")
    '<Folder ...'
    >>> conn.close()

The __repr__ of Zope objects is not stable anymore.

Test tear-down does nothing beyond what the base layers do.::

    >>> zserver.ZSERVER.testTearDown()
    >>> zserver.FUNCTIONAL_TESTING.testTearDown()
    >>> zserver.STARTUP.testTearDown()

    >>> 'app' in zserver.ZSERVER
    False

    >>> 'request' in zserver.ZSERVER
    False

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True

When the server is torn down, the ZServer thread is stopped.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.ZServer:Functional in ... seconds.
    Tear down plone.testing.zserver.ZServer in ... seconds.
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

We can expect one of these exceptions:
- URLError: <urlopen error [Errno ...] Connection refused>
- error: [Errno 104] Connection reset by peer

    >>> try:
    ...     conn = urllib2.urlopen(app_url + '/folder1', timeout=5)
    ... except Exception as exc:
    ...     if 'Connection refused' not in str(exc) and 'Connection reset' not in str(exc):
    ...         raise exc
    ... else:
    ...     print('urllib2.urlopen should have raised exception')


FTP server
~~~~~~~~~~

The ``FTP_SERVER`` layer is identical similar to ``ZSERVER``, except that it starts an FTP server instead of an HTTP server.
The fixture is contained in the ``FTP_SERVER_FIXTURE`` layer.

    **Warning:** It is generally not safe to run the ``ZSERVER`` and ``FTP_SERVER`` layers concurrently, because they both start up the same ``asyncore`` loop.
    If you need concurrent HTTP and FTP servers in a test, you can create your own layer by subclassing the ``ZServer`` layer class, and overriding the ``setUpServer()`` and ``tearDownServer()`` hooks to set up and close both servers.
    See the code for an example.

The ``FTP_SERVER_FIXTURE`` layer is based on the ``STARTUP`` layer.::

    >>> "%s.%s" % (zserver.FTP_SERVER_FIXTURE.__module__, zserver.FTP_SERVER_FIXTURE.__name__,)
    'plone.testing.zserver.FTPServer'

    >>> zserver.FTP_SERVER_FIXTURE.__bases__
    (<Layer 'plone.testing.zserver.Startup'>,)

The ``FTP_SERVER`` layer is based on ``FTP_SERVER_FIXTURE``, using the ``FunctionalTesting`` layer class.::

    >>> "%s.%s" % (zserver.FTP_SERVER.__module__, zserver.FTP_SERVER.__name__,)
    'plone.testing.zserver.FTPServer:Functional'

    >>> zserver.FTP_SERVER.__bases__
    (<Layer 'plone.testing.zserver.FTPServer'>,)

    >>> options = runner.get_options([], [])
    >>> setupLayers = {}
    >>> runner.setup_layer(options, zserver.FTP_SERVER, setupLayers)
    Set up plone.testing.zca.LayerCleanup in ... seconds.
    Set up plone.testing.zserver.Startup in ... seconds.
    Set up plone.testing.zserver.FTPServer in ... seconds.
    Set up plone.testing.zserver.FTPServer:Functional in ... seconds.

After layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::

    >>> host = zserver.FTP_SERVER['host']
    >>> port = zserver.FTP_SERVER['port']

Let's now simulate a test.
Test setup does nothing beyond what the base layers do.::

    >>> zserver.STARTUP.testSetUp()
    >>> zserver.FUNCTIONAL_TESTING.testSetUp()
    >>> zserver.FTP_SERVER.testSetUp()

As with ``ZSERVER``, we will set up some content for the test and then access it over the FTP port.::

    >>> app = zserver.FTP_SERVER['app'] # would normally be self.layer['app']
    >>> app.manage_addFolder('folder1')

We'll also create a user in the root user folder to make FTP access easier.::

    >>> ignore = app['acl_users'].userFolderAddUser('admin', 'secret', ['Manager'], ())

Note that we need to commit the transaction before it will show up in the other thread.::

    >>> import transaction; transaction.commit()

We can now look for this new object through the server.::

    >>> app_path = app.absolute_url_path()

    >>> import ftplib
    >>> ftpClient = ftplib.FTP()
    >>> ftpClient.connect(host, port, timeout=5)
    '220 ... FTP server (...) ready.'

    >>> ftpClient.login('admin', 'secret')
    '230 Login successful.'

    >>> ftpClient.cwd(app_path)
    '250 CWD command successful.'

    >>> ftpClient.retrlines('LIST')
    drwxrwx---   1 Zope     Zope            0 ... .
    ...--w--w----   1 Zope     Zope            0 ... acl_users
    drwxrwx---   1 Zope     Zope            0 ... folder1
    '226 Transfer complete'

    >>> ftpClient.quit()
    '221 Goodbye.'

Test tear-down does nothing beyond what the base layers do.::

    >>> zserver.FTP_SERVER.testTearDown()
    >>> zserver.FUNCTIONAL_TESTING.testTearDown()
    >>> zserver.STARTUP.testTearDown()

    >>> 'app' in zserver.ZSERVER
    False

    >>> 'request' in zserver.ZSERVER
    False

    >>> with zserver.zopeApp() as app:
    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()
    True

When the server is torn down, the FTP thread is stopped.::

    >>> runner.tear_down_unneeded(options, [], setupLayers, [])
    Tear down plone.testing.zserver.FTPServer:Functional in ... seconds.
    Tear down plone.testing.zserver.FTPServer in ... seconds.
    Tear down plone.testing.zserver.Startup in ... seconds.
    Tear down plone.testing.zca.LayerCleanup in ... seconds.

    >>> ftpClient.connect(host, port, timeout=5)
    Traceback (most recent call last):
    ...
    error: [Errno ...] Connection refused

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/plone/plone.testing",
    "name": "plone.testing",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "plone zope testing",
    "author": "Plone Foundation",
    "author_email": "plone-developers@lists.sourceforge.net",
    "download_url": "https://files.pythonhosted.org/packages/8f/1b/9e7a5a00f8098e0632d8bc32fbf1abbc67d4abdb5e8c0e4b56ddd9ee2eae/plone.testing-9.0.1.tar.gz",
    "platform": null,
    "description": "Introduction\n============\n\n.. contents:: Table of contents\n\n``plone.testing`` provides tools for writing unit and integration tests in a Zope and Plone environment.\nIt is not tied to Plone, and it does not depend on Zope (although it has some optional Zope-only features).\n\n``plone.testing`` builds on `zope.testing`_, in particular its layers concept.\nThis package also aims to promote some \"good practice\" for writing tests of various types.\n\n.. note::\n\n   If you are working with Plone, there is a complementary package `plone.app.testing`_, which builds on ``plone.testing`` to provide additional layers useful for testing Plone add-ons.\n\nIf you are new to automated testing and test driven development, you should spend some time learning about those concepts.\nSome useful references include:\n\n* `The Wikipedia article on unit testing <https://en.wikipedia.org/wiki/Unit_testing>`_\n* `The Dive Into Python chapter on testing <https://diveintopython3.problemsolving.io/unit-testing.html>`_\n\nBear in mind that different Python frameworks have slightly different takes on how to approach testing.\nTherefore, you may find examples that are different to those shown below.\nThe core concepts should be consistent, however.\n\nCompatibility\n-------------\n\n``plone.testing`` 7.x has been tested with Python 2.7 and 3.6.\nIf you're using the optional Zope layers, you must use Zope version 4 or later.\nLook at older ``plone.testing`` versions for supporting older Zope versions.\n\nDefinitions\n-----------\n\nIn this documentation, we will use a number of testing-related terms.\nThe following definitions apply:\n\nUnit test\n    An automated test (i.e. one written in code) that tests a single unit (normally a function) in isolation.\n    A unit test attempts to prove that the given function works as expected and gives the correct output given a particular input.\n    It is common to have a number of unit tests for a single function, testing different inputs, including boundary cases and errors.\n    Unit tests are typically quick to write and run.\n\nIntegration test\n    An automated test that tests how a number of units interact.\n    In a Zope context, this often pertains to how a particular object or view interacts with the Zope framework, the ZODB persistence engine, and so on.\n    Integration tests usually require some setup and can be slower to run than unit tests.\n    It is common to have fewer integration tests than unit test.\n\nFunctional test\n    An automated test that tests a feature in an \"end-to-end\" fashion.\n    In a Zope context, that normally means that it invokes an action in the same way that a user would, i.e. through a web request.\n    Functional tests are normally slower to run than either unit or integration tests, and can be significantly slower to run.\n    It is therefore common to have only a few functional tests for each major feature, relying on unit and integration tests for the bulk of testing.\n\nBlack box testing\n    Testing which only considers the system's defined inputs and outputs.\n    For example, a functional test is normally a black box test that provides inputs only through the defined interface (e.g. URLs published in a web application), and makes assertions only on end outputs (e.g. the response returned for requests to those URLs).\n\nWhite box testing\n    Testing which examines the internal state of a system to make assertions.\n    Authors of unit and integration tests normally have significant knowledge of the implementation of the code under test, and can examine such things as data in a database or changes to the system's environment to determine if the test succeeded or failed.\n\nAssertion\n    A check that determines whether a test succeeds or fails.\n    For example, if a unit test for the function ``foo()`` expects it to return the value 1, an assertion could be written to verify this fact.\n    A test is said to *fail* if any of its assertions fail.\n    A test always contains one or more assertions.\n\nTest case\n    A single unit, integration or functional test.\n    Often shortened to just *test*.\n    A test case sets up, executes and makes assertions against a single scenario that bears testing.\n\nTest fixture\n    The state used as a baseline for one or more tests.\n    The test fixture is *set up* before each test is executed, and *torn down* afterwards.\n    This is a pre-requisite for *test isolation* - the principle that tests should be independent of one another.\n\nLayer\n    The configuration of a test fixture shared by a number of tests.\n    All test cases that belong to a particular layer will be executed together.\n    The layer is *set up* once before the tests are executed, and *torn down* once after.\n    Layers may depend on one another.\n    Any *base layers* are set up before and torn down after a particular *child layer* is used.\n    The test runner will order test execution to minimise layer setup and tear-down.\n\nTest suite\n    A collection of test cases (and layers) that are executed together.\n\nTest runner\n    The program which executes tests.\n    This is responsible for calling layer and test fixture set-up and tear-down methods.\n    It also reports on the test run, usually by printing output to the console.\n\nCoverage\n    To have confidence in your code, you should ensure it is adequately covered by tests.\n    That is, each line of code, and each possible branching point (loops, ``if`` statements) should be executed by a test.\n    This is known as *coverage*, and is normally measured as a percentage of lines of non-test code covered by tests.\n    Coverage can be measured by the test runner, which keeps track of which lines of code were executed in a given test run.\n\nDoctest\n    A style of testing where tests are written as examples that could be typed into the interactive Python interpreter.\n    The test runner executes each example and checks the actual output against the expected output.\n    Doctests can either be placed in the docstring of a method, or in a separate file.\n    The use of doctests is largely a personal preference.\n    Some developers like to write documentation as doctests, which has the advantage that code samples can be automatically tested for correctness.\n    You can read more about doctests on `Wikipedia <http://en.wikipedia.org/wiki/Doctest>`_.\n\nInstallation and usage\n======================\n\nTo use ``plone.testing`` in your own package, you need to add it as a dependency.\nMost people prefer to keep test-only dependencies separate, so that they do not need to be installed in scenarios (such as on a production server) where the tests will not be run.\nThis can be achieved using a ``test`` extra.\n\nIn ``setup.py``, add or modify the ``extras_require`` option, like so:::\n\n    extras_require = {\n        'test': [\n                'plone.testing',\n            ]\n    },\n\nYou can add other test-only dependencies to that list as well, of course.\n\nTo run tests, you need a test runner.\nIf you are using ``zc.buildout``, you can install a test runner using the `zc.recipe.testrunner`_ recipe.\nFor example, you could add the following to your ``buildout.cfg``:::\n\n    [test]\n    recipe = zc.recipe.testrunner\n    eggs =\n        my.package [test]\n    defaults = ['--auto-color', '--auto-progress']\n\nYou'll also need to add this part to the ``parts`` list, of course:::\n\n    [buildout]\n    parts =\n        ...\n        test\n\nIn this example, have listed a single package to test, called ``my.package``, and asked for it to be installed with the ``[test]`` extra.\nThis will install any regular dependencies (listed in the ``install_requires`` option in ``setup.py``), as well as those in the list associated with the ``test`` key in the ``extras_require`` option.\n\nNote that it becomes important to properly list your dependencies here, because the test runner will only be aware of the packages explicitly listed, and their dependencies.\nFor example, if your package depends on Zope, you need to list ``Zope`` in the ``install_requires`` list in ``setup.py``;\nditto for ``Plone``, or indeed any other package you import from.\n\nOnce you have re-run buildout, the test runner will be installed as ``bin/test`` (the executable name is taken from the name of the buildout part).\nYou can execute it without arguments to run all tests of each egg listed in the ``eggs`` list::\n\n    $ bin/test\n\nIf you have listed several eggs, and you want to run the tests for a particular one, you can do::\n\n    $ bin/test -s my.package\n\nIf you want to run only a particular test within this package, use the ``-t`` option.\nThis can be passed a regular expression matching either a doctest file name or a test method name.::\n\n    $ bin/test -s my.package -t test_spaceship\n\nThere are other command line options, which you can find by running::\n\n    $ bin/test --help\n\nAlso note the ``defaults`` option in the buildout configuration.\nThis can be used to set default command line options.\nSome commonly useful options are shown above.\n\nCoverage reporting\n------------------\n\nWhen writing tests, it is useful to know how well your tests cover your code.\nYou can create coverage reports via the excellent `coverage`_ library.\nIn order to use it, we need to install it and a reporting script::\n\n    [buildout]\n    parts =\n        ...\n        test\n        coverage\n        report\n\n    [coverage]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    initialization =\n        include = '--source=${buildout:directory}/src'\n        sys.argv = sys.argv[:] + ['run', include, 'bin/test', '--all']\n\n    [report]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    scripts = coverage=report\n    initialization =\n        sys.argv = sys.argv[:] + ['html', '-i']\n\nThis will run the ``bin/test`` script with arguments like `--all` to run all layers.\nYou can also specify no or some other arguments.\nIt will place coverage reporting information in a ``.coverage`` file inside your buildout root.\nVia the ``--source`` argument you specify the directories containing code you want to cover.\nThe coverage script would otherwise generate coverage information for all executed code, including other packages and even the standard library.\n\nRunning the ``bin/report`` script will generate a human readable HTML representation of the run in the `htmlcov` directory.\nOpen the contained `index.html` in a browser to see the result.\n\nIf you want to generate an XML representation suitable for the `Cobertura`_ plugin of `Jenkins`_, you can add another part::\n\n    [buildout]\n    parts =\n        ...\n        report-xml\n\n    [report-xml]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    scripts = coverage=report-xml\n    initialization =\n        sys.argv = sys.argv[:] + ['xml', '-i']\n\nThis will generate a ``coverage.xml`` file in the buildout root.\n\nOptional dependencies\n---------------------\n\n``plone.testing`` comes with a core set of tools for managing layers, which depends only on `zope.testing`_.\nIn addition, there are several layers and helper functions which can be used in your own tests (or as bases for your own layers).\nSome of these have deeper dependencies.\nHowever, these dependencies are optional and not installed by default.\nIf you don't use the relevant layers, you can safely ignore them.\n\n``plone.testing`` does specify these dependencies, however, using the ``setuptools`` \"extras\" feature.\nYou can depend on one or more extras in your own ``setup.py`` ``install_requires`` or ``extras_require`` option using the same square bracket notation shown for the ``[test]`` buildout part above.\nFor example, if you need both the ``zca`` and ``publisher`` extras, you can have the following in your ``setup.py``::\n\n    extras_require = {\n        'test': [\n                'plone.testing [zca, publisher]',\n            ]\n    },\n\nThe available extras are:\n\n``zodb``\n    ZODB testing.\n    Depends on ``ZODB``.\n    The relevant layers and helpers are in the module ``plone.testing.zodb``.\n\n``zca``\n    Zope Component Architecture testing.\n    Depends on core Zope Component Architecture packages such as ``zope.component`` and ``zope.event``.\n    The relevant layers and helpers are in the module ``plone.testing.zca``.\n\n``security``\n    Security testing.\n    Depends on ``zope.security``.\n    The relevant layers and helpers are in the module ``plone.testing.security``.\n\n``publisher``\n    Zope Publisher testing.\n    Depends on ``zope.publisher``, ``zope.browsermenu``, ``zope.browserpage``, ``zope.browserresource`` and ``zope.security`` and sets up ZCML directives.\n    The relevant layers and helpers are in the module ``plone.testing.publisher``.\n\n``zope`` (For backwards compatibility there is also ``z2``.)\n\n    Zope testing.\n    Depends on the ``Zope`` egg, which includes all the dependencies of the Zope application server.\n    The relevant layers and helpers are in the module ``plone.testing.zope``.\n\n``zserver``\n\n    Tests against the ``ZServer``. (Python 2 only!) Requires additionally to use the ``zope`` extra.\n    The relevant layers and helpers are in the module ``plone.testing.zserver``\n\n\nAdding a test buildout to your package\n--------------------------------------\n\nWhen creating reusable, mostly stand-alone packages, it is often useful to be able to include a buildout with the package sources itself that can be used to create a test runner.\nThis is a popular approach for many Zope packages, for example.\nIn fact, ``plone.testing`` itself uses this kind of layout.\n\nTo have a self-contained buildout in your package, the following is required:\n\n* You need a ``buildout.cfg`` at the root of the package.\n\n* In most cases, you always want a ``bootstrap.py`` file to make it easier for people to set up a fresh buildout.\n\n* Your package sources need to be inside a ``src`` directory.\n  If you're using namespace packages, that means the top level package should be in the ``src`` directory.\n\n* The ``src`` directory must be referenced in ``setup.py``.\n\nFor example, ``plone.testing`` has the following layout::\n\n    plone.testing/\n    plone.testing/setup.py\n    plone.testing/bootstrap.py\n    plone.testing/buildout.cfg\n    plone.testing/README.rst\n    plone.testing/src/\n    plone.testing/src/plone\n    plone.testing/src/plone/__init__.py\n    plone.testing/src/plone/testing/\n    plone.testing/src/plone/testing/*\n\nIn ``setup.py``, the following arguments are required::\n\n        packages=find_packages('src'),\n        package_dir={'': 'src'},\n\nThis tells ``setuptools`` where to find the source code.\n\nThe ``buildout.cfg`` for ``plone.testing`` looks like this::\n\n    [buildout]\n    extends =\n        http://download.zope.org/Zope2/index/2.12.12/versions.cfg\n    parts = coverage test report report-xml\n    develop = .\n\n    [test]\n    recipe = collective.xmltestreport\n    eggs =\n        plone.testing [test]\n    defaults = ['--auto-color', '--auto-progress']\n\n    [coverage]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    initialization =\n        include = '--source=${buildout:directory}/src'\n        sys.argv = sys.argv[:] + ['run', include, 'bin/test', '--all', '--xml']\n\n    [report]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    scripts = coverage=report\n    initialization =\n        sys.argv = sys.argv[:] + ['html', '-i']\n\n    [report-xml]\n    recipe = zc.recipe.egg\n    eggs = coverage\n    scripts = coverage=report-xml\n    initialization =\n        sys.argv = sys.argv[:] + ['xml', '-i']\n\nObviously, you should adjust the package name in the ``eggs`` list and the version set in the ``extends`` line as appropriate.\n\nYou can of course also add additional buildout parts, for example to include some development/debugging tools, or even a running application server for testing purposes.\n\n    *Hint:* If you use this package layout, you should avoid checking any files or directories generated by buildout into your version control repository.\n    You want to ignore:\n\n    * ``.coverage``\n    * ``.installed.cfg``\n    * ``bin``\n    * ``coverage.xml``\n    * ``develop-eggs``\n    * ``htmlcov``\n    * ``parts``\n    * ``src/*.egg-info``\n\nLayers\n======\n\nIn large part, ``plone.testing`` is about layers.\nIt provides:\n\n* A set of layers (outlined below), which you can use or extend.\n\n* A set of tools for working with layers\n\n* A mini-framework to make it easy to write layers and manage shared resources associated with layers.\n\nWe'll discuss the last two items here, before showing how to write tests that use layers.\n\nLayer basics\n------------\n\nLayers are used to create test fixtures that are shared by multiple test cases.\nFor example, if you are writing a set of integration tests, you may need to set up a database and configure various components to access that database.\nThis type of test fixture setup can be resource-intensive and time-consuming.\nIf it is possible to only perform the setup and tear-down once for a set of tests without losing isolation between those tests, test runs can often be sped up significantly.\n\nLayers also allow reuse of test fixtures and set-up/tear-down code.\n``plone.testing`` provides a number of useful (but optional) layers that manage test fixtures for common Zope testing scenarios, letting you focus on the actual test authoring.\n\nAt the most basic, a layer is an object with the following methods and attributes:\n\n``setUp()``\n    Called by the test runner when the layer is to be set up.\n    This is called exactly once for each layer used during a test run.\n\n``tearDown()``\n    Called by the test runner when the layer is to be torn down.\n    As with ``setUp()``, this is called exactly once for each layer.\n\n``testSetUp()``\n    Called immediately before each test case that uses the layer is executed.\n    This is useful for setting up aspects of the fixture that are managed on a per-test basis, as opposed to fixture shared among all tests.\n\n``testTearDown()``\n    Called immediately after each test case that uses the layer is executed.\n    This is a chance to perform any post-test cleanup to ensure the fixture is ready for the next test.\n\n``__bases__``\n    A tuple of base layers.\n\nEach test case is associated with zero or one layer.\n(The syntax for specifying the layer is shown in the section \"Writing tests\" below.) All the tests associated with a given layer will be executed together.\n\nLayers can depend on one another (as indicated in the ``__bases__`` tuple), allowing one layer to build on the fixture created by another.\nBase layers are set up before and torn down after their dependants.\n\nFor example, if the test runner is executing some tests that belong to layer A, and some other tests that belong to layer B, both of which depend on layer C, the order of execution might be::\n\n    1. C.setUp()\n    1.1. A.setUp()\n\n    1.1.1. C.testSetUp()\n    1.1.2. A.testSetUp()\n    1.1.3. [One test using layer A]\n    1.1.4. A.testTearDown()\n    1.1.5. C.testTearDown()\n\n    1.1.6. C.testSetUp()\n    1.1.7. A.testSetUp()\n    1.1.8. [Another test using layer A]\n    1.1.9. A.testTearDown()\n    1.1.10. C.testTearDown()\n\n    1.2. A.tearDown()\n    1.3. B.setUp()\n\n    1.3.1. C.testSetUp()\n    1.3.2. B.testSetUp()\n    1.3.3. [One test using layer B]\n    1.3.4. B.testTearDown()\n    1.3.5. C.testTearDown()\n\n    1.3.6. C.testSetUp()\n    1.3.7. B.testSetUp()\n    1.3.8. [Another test using layer B]\n    1.3.9. B.testTearDown()\n    1.3.10. C.testTearDown()\n\n    1.4. B.tearDown()\n    2. C.tearDown()\n\nA base layer may of course depend on other base layers.\nIn the case of nested dependencies like this, the order of set up and tear-down as calculated by the test runner is similar to the way in which Python searches for the method to invoke in the case of multiple inheritance.\n\nWriting layers\n--------------\n\nThe easiest way to create a new layer is to use the ``Layer`` base class and implement the ``setUp()``, ``tearDown()``, ``testSetUp()`` and ``testTearDown()`` methods as needed.\nAll four are optional.\nThe default implementation of each does nothing.\n\nBy convention, layers are created in a module called ``testing.py`` at the top level of your package.\nThe idea is that other packages that extend your package can reuse your layers for their own testing.\n\nA simple layer may look like this::\n\n    >>> from plone.testing import Layer\n    >>> class SpaceShip(Layer):\n    ...\n    ...     def setUp(self):\n    ...         print(\"Assembling space ship\")\n    ...\n    ...     def tearDown(self):\n    ...         print(\"Disasembling space ship\")\n    ...\n    ...     def testSetUp(self):\n    ...         print(\"Fuelling space ship in preparation for test\")\n    ...\n    ...     def testTearDown(self):\n    ...         print(\"Emptying the fuel tank\")\n\nBefore this layer can be used, it must be instantiated.\nLayers are normally instantiated exactly once, since by nature they are shared between tests.\nThis becomes important when you start to manage resources (such as persistent data, database connections, or other shared resources) in layers.\n\nThe layer instance is conventionally also found in ``testing.py``, just after the layer class definition.::\n\n    >>> SPACE_SHIP = SpaceShip()\n\n.. note::\n\n    Since the layer is instantiated in module scope, it will be created as soon as the ``testing`` module is imported.\n    It is therefore very important that the layer class is inexpensive and safe to create.\n    In general, you should avoid doing anything non-trivial in the ``__init__()`` method of your layer class.\n    All setup should happen in the ``setUp()`` method.\n    If you *do* implement ``__init__()``, be sure to call the ``super`` version as well.\n\nThe layer shown above did not have any base layers (dependencies).\nHere is an example of another layer that depends on it:::\n\n    >>> class ZIGSpaceShip(Layer):\n    ...     defaultBases = (SPACE_SHIP,)\n    ...\n    ...     def setUp(self):\n    ...         print(\"Installing main canon\")\n\n    >>> ZIG = ZIGSpaceShip()\n\nHere, we have explicitly listed the base layers on which ``ZIGSpaceShip`` depends, in the ``defaultBases`` attribute.\nThis is used by the ``Layer`` base class to set the layer bases in a way that can also be overridden: see below.\n\nNote that we use the layer *instance* in the ``defaultBases`` tuple, not the class.\nLayer dependencies always pertain to specific layer instances.\nAbove, we are really saying that *instances* of ``ZIGSpaceShip`` will, by default, require the ``SPACE_SHIP`` layer to be set up first.\n\n.. note::\n\n    You may find it useful to create other layer base/mix-in classes that extend ``plone.testing.Layer`` and provide helper methods for use in your own layers.\n    This is perfectly acceptable, but please do not confuse a layer base class used in this manner with the concept of a *base layer* as described above:\n\n    * A class deriving from ``plone.testing.Layer`` is known as a *layer class*.\n      It defines the behaviour of the layer by implementing the lifecycle methods ``setUp()``, ``tearDown()``, ``testSetUp()`` and/or ``testTearDown()``.\n\n    * A layer class can be instantiated into an actual layer.\n      When a layer is associated with a test, it is the layer *instance* that is used.\n\n    * The instance is usually a shared, module-global object, although in some cases it is useful to create copies of layers by instantiating the class more than once.\n\n    * Subclassing an existing layer class is just straightforward OOP reuse: the test runner is not aware of the subclassing relationship.\n\n    * A layer *instance* can be associated with any number of layer *bases*, via its ``__bases__`` property (which is usually via the ``defaultBases`` variable in the class body and/or overridden using the ``bases`` argument to the ``Layer`` constructor).\n      These bases are layer *instances*, not classes.\n      The test runner will inspect the ``__bases__`` attribute of each layer instance it sets up to calculate layer pre-requisites and dependencies.\n\n    Also note that the `zope.testing`_ documentation contains examples of layers that are \"old-style\" classes where the ``setUp()`` and ``tearDown()`` methods are ``classmethod`` methods and class inheritance syntax is used to specify base layers.\n    Whilst this pattern works, we discourage its use, because the classes created using this pattern are not really used as classes.\n    The concept of layer bases is slightly different from class inheritance, and using the ``class`` keyword to create layers with base layers leads to a number of \"gotchas\" that are best avoided.\n\nAdvanced - overriding bases\n---------------------------\n\nIn some cases, it may be useful to create a copy of a layer, but change its bases.\nOne reason to do this may if you are reusing a layer from another module, and you need to change the order in which layers are set up and torn down.\n\nNormally, of course, you would just reuse the layer instance, either directly in a test, or in the ``defaultBases`` tuple of another layer, but if you need to change the bases, you can pass a new list of bases to the layer instance constructor:::\n\n    >>> class CATSMessage(Layer):\n    ...\n    ...     def setUp(self):\n    ...         print(\"All your base are belong to us\")\n    ...\n    ...     def tearDown(self):\n    ...         print(\"For great justice\")\n\n    >>> CATS_MESSAGE = CATSMessage()\n\n    >>> ZERO_WING = ZIGSpaceShip(bases=(SPACE_SHIP, CATS_MESSAGE,), name=\"ZIGSpaceShip:CATSMessage\")\n\nPlease note that when overriding bases like this, the ``name`` argument is required.\nThis is because each layer (using in a given test run) must have a unique name.\nThe default is to use the layer class name, but this obviously only works for one instantiation.\nTherefore, ``plone.testing`` requires a name when setting ``bases`` explicitly.\n\nPlease take great care when changing layer bases like this.\nThe layer implementation may make assumptions about the test fixture that was set up by its bases.\nIf you change the order in which the bases are listed, or remove a base altogether, the layer may fail to set up correctly.\n\nAlso, bear in mind that the new layer instance is independent of the original layer instance, so any resources defined in the layer are likely to be duplicated.\n\nLayer combinations\n------------------\n\nSometimes, it is useful to be able to combine several layers into one, without adding any new fixture.\nOne way to do this is to use the ``Layer`` class directly and instantiate it with new bases:::\n\n    >>> COMBI_LAYER = Layer(bases=(CATS_MESSAGE, SPACE_SHIP,), name=\"Combi\")\n\nHere, we have created a \"no-op\" layer with two bases: ``CATS_MESSAGE`` and ``SPACE_SHIP``, named ``Combi``.\n\nPlease note that when using ``Layer`` directly like this, the ``name`` argument is required.\nThis is to allow the test runner to identify the layer correctly.\nNormally, the class name of the layer is used as a basis for the name, but when using the ``Layer`` base class directly, this is unlikely to be unique or descriptive.\n\nLayer resources\n---------------\n\nMany layers will manage one or more resources that are used either by other layers, or by tests themselves.\nExamples may include database connections, thread-local objects, or configuration data.\n\n``plone.testing`` contains a simple resource storage abstraction that makes it easy to access resources from dependent layers or tests.\nThe resource storage uses dictionary notation:::\n\n    >>> class WarpDrive(object):\n    ...     \"\"\"A shared resource\"\"\"\n    ...\n    ...     def __init__(self, maxSpeed):\n    ...         self.maxSpeed = maxSpeed\n    ...         self.running = False\n    ...\n    ...     def start(self, speed):\n    ...         if speed > self.maxSpeed:\n    ...             print(\"We need more power!\")\n    ...         else:\n    ...             print(\"Going to warp at speed\", speed)\n    ...             self.running = True\n    ...\n    ...     def stop(self):\n    ...         self.running = False\n\n    >>> class ConstitutionClassSpaceShip(Layer):\n    ...     defaultBases = (SPACE_SHIP,)\n    ...\n    ...     def setUp(self):\n    ...         self['warpDrive'] = WarpDrive(8.0)\n    ...\n    ...     def tearDown(self):\n    ...         del self['warpDrive']\n\n    >>> CONSTITUTION_CLASS_SPACE_SHIP = ConstitutionClassSpaceShip()\n\n    >>> class GalaxyClassSpaceShip(Layer):\n    ...     defaultBases = (CONSTITUTION_CLASS_SPACE_SHIP,)\n    ...\n    ...     def setUp(self):\n    ...         # Upgrade the warp drive\n    ...         self.previousMaxSpeed = self['warpDrive'].maxSpeed\n    ...         self['warpDrive'].maxSpeed = 9.5\n    ...\n    ...     def tearDown(self):\n    ...         # Restore warp drive to its previous speed\n    ...         self['warpDrive'].maxSpeed = self.previousMaxSpeed\n\n    >>> GALAXY_CLASS_SPACE_SHIP = GalaxyClassSpaceShip()\n\nAs shown, layers (that derive from ``plone.testing.Layer``) support item (dict-like) assignment, access and deletion of arbitrary resources under string keys.\n\n    **Important:** If a layer creates a resource (by assigning an object to a key on ``self`` as shown above) during fixture setup-up, it must also delete the resource on tear-down.\n    Set-up and deletion should be symmetric: if the resource is assigned during ``setUp()`` it should be deleted in ``tearDown()``;\n    if it's created in ``testSetUp()`` it should be deleted in ``testTearDown()``.\n\nA resource defined in a base layer is accessible from and through a child layer.\nIf a resource is set on a child using a key that also exists in a base layer, the child version will shadow the base version until the child layer is torn down (presuming it deletes the resource, which it should), but the base layer version remains intact.\n\n.. note::\n\n    Accessing a resource is analogous to accessing an instance variable.\n    For example, if a base layer assigns a resource to a given key in its ``setUp()`` method, a child layer shadows that resource with another object under the same key, the shadowed resource will by used during the ``testSetUp()`` and ``testTearDown()`` lifecycle methods if implemented by the *base* layer as well.\n    This will be the case until the child layer \"pops\" the resource by deleting it, normally in its ``tearDown()``.\n\nConversely, if (as shown above) the child layer accesses and modifies the object, it will modify the original.\n\n.. note::\n\n   It is sometimes necessary (or desirable) to modify a shared resource in a child layer, as shown in the example above.  In this case, however, it is very important to restore the original state when the layer is torn down.  Otherwise, other layers or tests using the base layer directly may be affected in difficult-to-debug ways.\n\nIf the same key is used in multiple base layers, the rules for choosing which version to use are similar to those that apply when choosing an attribute or method to use in the case of multiple inheritance.\n\nIn the example above, we used the resource manager for the ``warpDrive`` object, but we assigned the ``previousMaxSpeed`` variable to ``self``.\nThis is because ``previousMaxSpeed`` is internal to the layer and should not be shared with any other layers that happen to use this layer as a base.\nNor should it be used by any test cases.\nConversely, ``warpDrive`` is a shared resource that is exposed to other layers and test cases.\n\nThe distinction becomes even more important when you consider how a test case may access the shared resource.\nWe'll discuss how to write test cases that use layers shortly, but consider the following test:::\n\n    >>> import unittest\n    >>> class TestFasterThanLightTravel(unittest.TestCase):\n    ...     layer = GALAXY_CLASS_SPACE_SHIP\n    ...\n    ...     def test_hyperdrive(self):\n    ...         warpDrive = self.layer['warpDrive']\n    ...         warpDrive.start(8)\n\nThis test needs access to the shared resource.\nIt knows that its layer defines one called ``warpDrive``.\nIt does not know or care that the warp drive was actually initiated by the ``ConstitutionClassSpaceShip`` base layer.\n\nIf, however, the base layer had assigned the resource as an instance variable, it would not inherit to child layers (remember: layer bases are not base classes!).\nThe syntax to access it would be:::\n\n    self.layer.__bases__[0].warpDrive\n\nwhich is not only ugly, but brittle: if the list of bases is changed, the expression above may lead to an attribute error.\n\nWriting tests\n=============\n\nTests are usually written in one of two ways: As methods on a class that derives from ``unittest.TestCase`` (this is sometimes known as \"Python tests\" or \"JUnit-style tests\"), or using doctest syntax.\n\nYou should realise that although the relevant frameworks (``unittest`` and ``doctest``) often talk about unit testing, these tools are also used to write integration and functional tests.\nThe distinction between unit, integration and functional tests is largely practical: you use the same techniques to set up a fixture or write assertions for an integration test as you would for a unit test.\nThe difference lies in what that fixture contains, and how you invoke the code under test.\nIn general, a true unit test will have a minimal or no test fixture, whereas an integration test will have a fixture that contains the components your code is integrating with.\nA functional test will have a fixture that contains enough of the full system to execute and test an \"end-to-end\" scenario.\n\nPython tests\n------------\n\nPython tests use the Python `unittest`_ module.\nThey should be placed in a module or package called ``tests`` for the test runner to pick them up.\n\nFor small packages, a single module called ``tests.py`` will normally contain all tests.\nFor larger packages, it is common to have a ``tests`` package that contains a number of modules with tests.\nThese need to start with the word ``test``, e.g.\n``tests/test_foo.py`` or ``tests/test_bar.py``.\nDon't forget the ``__init__.py`` in the ``tests`` package, too!\n\nunittest\n~~~~~~~~\n\nPlease note that the `zope.testing`_ test runner at the time of writing (version 4.6.2) does not (yet) support the new ``setUpClass()``, ``tearDownClass()``, ``setUpModule()`` and ``tearDownModule()`` hooks from ``unittest``.\nThis is not normally a problem, since we tend to use layers to manage complex fixtures, but it is important to be aware of nonetheless.\n\nTest modules, classes and functions\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPython tests are written with classes that derive from the base class ``TestCase``.\nEach test is written as a method that takes no arguments and has a name starting with ``test``.\nOther methods can be added and called from test methods as appropriate, e.g.\nto share some test logic.\n\nTwo special methods, ``setUp()`` and ``tearDown()``, can also be added.\nThese will be called before or after each test, respectively, and provide a useful place to construct and clean up test fixtures without writing a custom layer.\nThey are obviously not as reusable as layers, though.\n\n   *Hint:* Somewhat confusingly, the ``setUp()`` and ``tearDown()`` methods in a test case class are the equivalent of the ``testSetUp()`` and ``testTearDown()`` methods of a layer class.\n\nA layer can be specified by setting the ``layer`` class attribute to a layer instance.\nIf layers are used in conjunction with ``setUp()`` and ``tearDown()`` methods in the test class itself, the class' ``setUp()`` method will be called after the layer's ``testSetUp()`` method, and the class' ``tearDown()`` method will be called before the layer's ``testTearDown()`` method.\n\nThe ``TestCase`` base class contains a number of methods which can be used to write assertions.\nThey all take the form ``self.assertSomething()``, e.g.\n``self.assertEqual(result, expectedValue)``.\nSee the `unittest`_ documentation for details.\n\nPutting this together, let's expand on our previous example unit test:::\n\n    >>> import unittest\n\n    >>> class TestFasterThanLightTravel(unittest.TestCase):\n    ...     layer = GALAXY_CLASS_SPACE_SHIP\n    ...\n    ...     def setUp(self):\n    ...         self.warpDrive = self.layer['warpDrive']\n    ...         self.warpDrive.stop()\n    ...\n    ...     def tearDown(self):\n    ...         self.warpDrive.stop()\n    ...\n    ...     def test_warp8(self):\n    ...         self.warpDrive.start(8)\n    ...         self.assertEqual(self.warpDrive.running, True)\n    ...\n    ...     def test_max_speed(self):\n    ...         tooFast = self.warpDrive.maxSpeed + 0.1\n    ...         self.warpDrive.start(tooFast)\n    ...         self.assertEqual(self.warpDrive.running, False)\n\nA few things to note:\n\n* The class derives from ``unittest.TestCase``.\n\n* The ``layer`` class attribute is set to a layer instance (not a layer class!) defined previously.\n  This would typically be imported from a ``testing`` module.\n\n* There are two tests here: ``test_warp8()`` and ``test_max_speed()``.\n\n* We have used the ``self.assertEqual()`` assertion in both tests to check the result of executing the ``start()`` method on the warp drive.\n\n* We have used the ``setUp()`` method to fetch the ``warpDrive`` resource and ensure that it is stopped before each test is executed.\n  Assigning a variable to ``self`` is a useful way to provide some state to each test method, though be careful about data leaking between tests: in general, you cannot predict the order in which tests will run, and tests should always be independent.\n\n* We have used the ``tearDown()`` method to make sure the warp drive is really stopped after each test.\n\nTest suites\n~~~~~~~~~~~\n\nA class like the one above is all you need: any class deriving from ``TestCase`` in a module with a name starting with ``test`` will be examined for test methods.\nThose tests are then collected into a test suite and executed.\n\nSee the `unittest`_ documentation for other options.\n\nDoctests\n--------\n\nDoctests can be written in two ways: as the contents of a docstring (usually, but not always, as a means of illustrating and testing the functionality of the method or class where the docstring appears), or as a separate text file.\nIn both cases, the standard `doctest`_ module is used.\nSee its documentation for details about doctest syntax and conventions.\n\nDoctests are used in two different ways:\n\n* To test documentation.\n  That is, to ensure that code examples contained in documentation are valid and continue to work as the software is updated.\n\n* As a convenient syntax for writing tests.\n\nThese two approaches use the same testing APIs and techniques.\nThe difference is mostly about mindset.\nHowever, it is important to avoid falling into the trap that tests can substitute for good documentation or vice-a-versa.\nTests usually need to systematically go through inputs and outputs and cover off a number of corner cases.\nDocumentation should tell a compelling narrative and usually focus on the main usage scenarios.\nTrying to kill these two birds with one stone normally leaves you with an unappealing pile of stones and feathers.\n\nDocstring doctests\n~~~~~~~~~~~~~~~~~~\n\nDoctests can be added to any module, class or function docstring:::\n\n    def canOutrunKlingons(warpDrive):\n        \"\"\"Find out of the given warp drive can outrun Klingons.\n\n        Klingons travel at warp 8\n\n        >>> drive = WarpDrive(5)\n        >>> canOutrunKlingons(drive)\n        False\n\n        We have to be faster than that to outrun them.\n\n        >>> drive = WarpDrive(8.1)\n        >>> canOutrunKlingons(drive)\n        True\n\n        We can't outrun them if we're travelling exactly the same speed\n\n        >>> drive = WarpDrive(8.0)\n        >>> canOutrunKlingons(drive)\n        False\n\n        \"\"\"\n        return warpDrive.maxSpeed > 8.0\n\nTo add the doctests from a particular module to a test suite, you need to use the ``test_suite()`` function hook:::\n\n    >>> import doctest\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         unittest.makeSuite(TestFasterThanLightTravel), # our previous test\n    ...         doctest.DocTestSuite('spaceship.utils'),\n    ...     ])\n    ...     return suite\n\nHere, we have given the name of the module to check as a string dotted name.\nIt is also possible to import a module and pass it as an object.\nThe code above passes a list to ``addTests()``, making it easy to add several sets of tests to the suite: the list can be constructed from calls to ``DocTestSuite()``, ``DocFileSuite()`` (shown below) and ``makeSuite()`` (shown above).\n\n    Remember that if you add a ``test_suite()`` function to a module that also has ``TestCase``-derived python tests, those tests will no longer be automatically picked up by ``zope.testing``, so you need to add them to the test suite explicitly.\n\nThe example above illustrates a documentation-oriented doctest, where the doctest forms part of the docstring of a public module.\nThe same syntax can be used for more systematic unit tests.\nFor example, we could have a module ``spaceship.tests.test_spaceship`` with a set of methods like::\n\n    # It's often better to put the import into each method, but here we've\n    # imported the code under test at module level\n    from spaceship.utils import WarpDrive, canOutrunKlingons\n\n    def test_canOutrunKlingons_too_small():\n        \"\"\"Klingons travel at warp 8.0\n\n        >>> drive = WarpDrive(7.9)\n        >>> canOutrunKlingons(drive)\n        False\n\n        \"\"\"\n\n    def test_canOutrunKlingons_big():\n        \"\"\"Klingons travel at warp 8.0\n\n        >>> drive = WarpDrive(8.1)\n        >>> canOutrunKlingons(drive)\n        True\n\n        \"\"\"\n\n    def test_canOutrunKlingons_must_be_greater():\n        \"\"\"Klingons travel at warp 8.0\n\n        >>> drive = WarpDrive(8.0)\n        >>> canOutrunKlingons(drive)\n        False\n\n        \"\"\"\n\nHere, we have created a number of small methods that have no body.\nThey merely serve as a container for docstrings with doctests.\nSince the module has no globals, each test must import the code under test, which helps make import errors more explicit.\n\nFile doctests\n~~~~~~~~~~~~~\n\nDoctests contained in a file are similar to those contained in docstrings.\nFile doctests are better suited to narrative documentation covering the usage of an entire module or package.\n\nFor example, if we had a file called ``spaceship.txt`` with doctests, we could add it to the test suite above with:::\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         unittest.makeSuite(TestFasterThanLightTravel),\n    ...         doctest.DocTestSuite('spaceship.utils'),\n    ...         doctest.DocFileSuite('spaceship.txt'),\n    ...     ])\n    ...     return suite\n\nBy default, the file is located relative to the module where the test suite is defined.\nYou can use ``../`` (even on Windows) to reference the parent directory, which is sometimes useful if the doctest is inside a module in a ``tests`` package.\n\n.. note::\n\n    If you put the doctest ``test_suite()`` method in a module inside a ``tests`` package, that module must have a name starting with ``test``.\n    It is common to have ``tests/test_doctests.py`` that contains a single ``test_suite()`` method that returns a suite of multiple doctests.\n\nIt is possible to pass several tests to the suite, e.g.::\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         unittest.makeSuite(TestFasterThanLightTravel),\n    ...         doctest.DocTestSuite('spaceship.utils'),\n    ...         doctest.DocFileSuite('spaceship.txt', 'warpdrive.txt',),\n    ...     ])\n    ...     return suite\n\nThe test runner will report each file as a separate test, i.e.\nthe ``DocFileSuite()`` above would add two tests to the overall suite.\nConversely, a ``DocTestSuite()`` using a module with more than one docstring containing doctests will report one test for each eligible docstring.\n\nDoctest fixtures and layers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA docstring doctest will by default have access to any global symbol available in the module where the docstring is found (e.g.\nanything defined or imported in the module).\nThe global namespace can be overridden by passing a ``globs`` keyword argument to the ``DocTestSuite()`` constructor, or augmented by passing an ``extraglobs`` argument.\nBoth should be given dictionaries.\n\nA file doctest has an empty globals namespace by default.\nGlobals may be provided via the ``globs`` argument to ``DocFileSuite()``.\n\nTo manage a simple test fixture for a doctest, you can define set-up and tear-down functions and pass them as the ``setUp`` and ``tearDown`` arguments respectively.\nThese are both passed a single argument, a ``DocTest`` object.\nThe most useful attribute of this object is ``globs``, which is a mutable dictionary of globals available in the test.\n\nFor example:::\n\n    >>> def setUpKlingons(doctest):\n    ...     doctest.globs['oldStyleKlingons'] = True\n\n    >>> def tearDownKlingons(doctest):\n    ...     doctest.globs['oldStyleKlingons'] = False\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         doctest.DocTestSuite('spaceship.utils', setUp=setUpKlingons, tearDown=tearDownKlingons),\n    ...     ])\n    ...     return suite\n\nThe same arguments are available on the ``DocFileSuite()`` constructor.\nThe set up method is called before each docstring in the given module for a ``DocTestSuite``, and before each file given in a ``DocFileSuite``.\n\nOf course, we often want to use layers with doctests too.\nUnfortunately, the ``unittest`` API is not aware of layers, so you can't just pass a layer to the ``DocTestSuite()`` and ``DocFileSuite()`` constructors.\nInstead, you have to set a ``layer`` attribute on the suite after it has been constructed.\n\nFurthermore, to use layer resources in a doctest, we need access to the layer instance.\nThe easiest way to do this is to pass it as a glob, conventionally called 'layer'.\nThis makes a global name 'layer' available in the doctest itself, giving access to the test's layer instance.\n\nTo make it easier to do this, ``plone.testing`` comes with a helper function called ``layered()``.\nIts first argument is a test suite.\nThe second argument is the layer.\n\nFor example:::\n\n    >>> from plone.testing import layered\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         layered(doctest.DocTestSuite('spaceship.utils'), layer=CONSTITUTION_CLASS_SPACE_SHIP),\n    ...     ])\n    ...     return suite\n\nThis is equivalent to:::\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...\n    ...     spaceshipUtilTests = doctest.DocTestSuite('spaceship.utils', globs={'layer': CONSTITUTION_CLASS_SPACE_SHIP})\n    ...     spaceshipUtilTests.layer = CONSTITUTION_CLASS_SPACE_SHIP\n    ...     suite.addTest(spaceshipUtilTests)\n    ...\n    ...     return suite\n\n(In this example, we've opted to use ``addTest()`` to add a single suite, instead of using ``addTests()`` to add multiple suites in one go).\n\nZope testing tools\n==================\n\nEverything described so far in this document relies only on the standard `unittest`_ and `doctest`_ modules and `zope.testing`_, and you can use this package without any other dependencies.\n\nHowever, there are also some tools (and layers) available in this package, as well as in other packages, that are specifically useful for testing applications that use various Zope-related frameworks.\n\nTest cleanup\n------------\n\nIf a test uses a global registry, it may be necessary to clean that registry on set up and tear down of each test fixture.\n``zope.testing`` provides a mechanism to register cleanup handlers - methods that are called to clean up global state.\nThis can then be invoked in the ``setUp()`` and ``tearDown()`` fixture lifecycle methods of a test case.::\n\n    >>> from zope.testing import cleanup\n\nLet's say we had a global registry, implemented as a dictionary:::\n\n    >>> SOME_GLOBAL_REGISTRY = {}\n\nIf we wanted to clean this up on each test run, we could call ``clear()`` on the dict.\nSince that's a no-argument method, it is perfect as a cleanup handler.::\n\n    >>> cleanup.addCleanUp(SOME_GLOBAL_REGISTRY.clear)\n\nWe can now use the ``cleanUp()`` method to execute all registered cleanups:::\n\n    >>> cleanup.cleanUp()\n\nThis call could be placed in a ``setUp()`` and/or ``tearDown()`` method in a test class, for example.\n\nEvent testing\n-------------\n\nYou may wish to test some code that uses ``zope.event`` to fire specific events.\n`zope.component`_ provides some helpers to capture and analyse events.::\n\n    >>> from zope.component import eventtesting\n\nTo use this, you first need to set up event testing.\nSome of the layers shown below will do this for you, but you can do it yourself by calling the ``eventtesting.setUp()`` method, e.g.\nfrom your own ``setUp()`` method:::\n\n    >>> eventtesting.setUp()\n\nThis simply registers a few catch-all event handlers.\nOnce you have executed the code that is expected to fire events, you can use the ``getEvents()`` helper function to obtain a list of the event instances caught:::\n\n    >>> events = eventtesting.getEvents()\n\nYou can now examine ``events`` to see what events have been caught since the last cleanup.\n\n``getEvents()`` takes two optional arguments that can be used to filter the returned list of events.\nThe first (``event_type``) is an interface.\nIf given, only events providing this interface are returned.\nThe second (``filter``) is a callable taking one argument.\nIf given, it will be called with each captured event.\nOnly those events where the filter function returns ``True`` will be included.\n\nThe ``eventtesting`` module registers a cleanup action as outlined above.\nWhen you call ``cleanup.cleanUp()`` (or ``eventtesting.clearEvents()``, which is the handler it registers), the events list will be cleared, ready for the next test.\nHere, we'll do it manually:::\n\n    >>> eventtesting.clearEvents()\n\nMock requests\n-------------\n\nMany tests require a request object, often with particular request/form variables set.\n`zope.publisher`_ contains a useful class for this purpose.::\n\n    >>> from zope.publisher.browser import TestRequest\n\nA simple test request can be constructed with no arguments:::\n\n    >>> request = TestRequest()\n\nTo add a body input stream, pass a ``StringIO`` or file as the first parameter.\nTo set the environment (request headers), use the ``environ`` keyword argument.\nTo simulate a submitted form, use the ``form`` keyword argument:::\n\n    >>> request = TestRequest(form=dict(field1='foo', field2=1))\n\nNote that the ``form`` dict contains marshalled form fields, so modifiers like ``:int`` or ``:boolean`` should not be included in the field names, and values should be converted to the appropriate type.\n\nRegistering components\n----------------------\n\nMany test fixtures will depend on having a minimum of Zope Component Architecture (ZCA) components registered.\nIn normal operation, these would probably be registered via ZCML, but in a unit test, you should avoid loading the full ZCML configuration of your package (and its dependencies).\n\nInstead, you can use the Python API in `zope.component`_ to register global components instantly.\nThe three most commonly used functions are:::\n\n    >>> from zope.component import provideAdapter\n    >>> from zope.component import provideUtility\n    >>> from zope.component import provideHandler\n\nSee the `zope.component`_ documentation for details about how to use these.\n\nWhen registering global components like this, it is important to avoid test leakage.\nThe ``cleanup`` mechanism outlined above can be used to tear down the component registry between each test.\nSee also the ``plone.testing.zca.UNIT_TESTING`` layer, described below, which performs this cleanup automatically via the ``testSetUp()``/``testTearDown()`` mechanism.\n\nAlternatively, you can \"stack\" a new global component registry using the ``plone.testing.zca.pushGlobalRegistry()`` and ``plone.testing.zca.popGlobalRegistry()`` helpers.\nThis makes it possible to set up and tear down components that are specific to a given layer, and even allow tests to safely call the global component API (or load ZCML - see below) with proper tear-down.\nSee the layer reference below for details.\n\nLoading ZCML\n------------\n\nIntegration tests often need to load ZCML configuration.\nThis can be achieved using the ``zope.configuration`` API.::\n\n    >>> from zope.configuration import xmlconfig\n\nThe ``xmlconfig`` module contains two methods for loading ZCML.\n\n``xmlconfig.string()`` can be used to load a literal string of ZCML:::\n\n    >>> xmlconfig.string(\"\"\"\\\n    ... <configure xmlns=\"http://namespaces.zope.org/zope\" package=\"plone.testing\">\n    ...     <include package=\"zope.component\" file=\"meta.zcml\" />\n    ... </configure>\n    ... \"\"\")\n    <zope.configuration.config.ConfigurationMachine object at ...>\n\nNote that we need to set a package (used for relative imports and file locations) explicitly here, using the ``package`` attribute of the ``<configure />`` element.\n\nAlso note that unless the optional second argument (``context``) is passed, a new configuration machine will be created every time ``string()`` is called.\nIt therefore becomes necessary to explicitly ``<include />`` the files that contain the directives you want to use (the one in ``zope.component`` is a common example).\nLayers that set up ZCML configuration may expose a resource which can be passed as the ``context`` parameter, usually called ``configurationContext`` - see below.\n\nTo load the configuration for a particular package, use ``xmlconfig.file()``:::\n\n    >>> import zope.component\n    >>> context = xmlconfig.file('meta.zcml', zope.component)\n    >>> xmlconfig.file('configure.zcml', zope.component, context=context)\n    <zope.configuration.config.ConfigurationMachine object at ...>\n\nThis takes two required arguments: the file name and the module relative to which it is to be found.\nHere, we have loaded two files: ``meta.zcml`` and ``configure.zcml``.\nThe first call to ``xmlconfig.file()`` creates and returns a configuration context.\nWe reuse that for the subsequent invocation, so that the directives configured are available.\n\nInstalling a Zope product\n-------------------------\n\nSome packages (including all those in the ``Products.*`` namespace) have the special status of being Zope \"products\".\nThese are recorded in a special registry, and may have an ``initialize()`` hook in their top-level ``__init__.py`` that needs to be called for the package to be fully configured.\n\nZope 2 will find and execute any products during startup.\nFor testing, we need to explicitly list the products to install.\nProvided you are using ``plone.testing`` with Zope, you can use the following:::\n\n    from plone.testing import zope\n\n    with zope.zopeApp() as app:\n        zope.installProduct(app, 'Products.ZCatalog')\n\nThis would normally be used during layer ``setUp()``.\nNote that the basic Zope application context must have been set up before doing this.\nThe usual way to ensure this, is to use a layer that is based on ``zope.STARTUP`` - see below.\n\nTo tear down such a layer, you should do:::\n\n    from plone.testing import zope\n\n    with zope.zopeApp() as app:\n        zope.uninstallProduct(app, 'Products.ZCatalog')\n\nNote:\n\n* Unlike the similarly-named function from ``ZopeTestCase``, these helpers will work with any type of product.\n  There is no distinction between a \"product\" and a \"package\" (and no ``installPackage()``).\n  However, you must use the full name (``Products.*``) when registering a product.\n\n* Installing a product in this manner is independent of ZCML configuration.\n  However, it is almost always necessary to install the package's ZCML configuration first.\n\nFunctional testing\n------------------\n\nFor functional tests that aim to simulate the browser, you can use `zope.testbrowser`_ in a Python test or doctest:::\n\n    >>> from zope.testbrowser.browser import Browser\n    >>> browser = Browser()\n\nThis provides a simple API to simulate browser input, without actually running a web server thread or scripting a live browser (as tools such as Selenium_ do).\nThe downside is that it is not possible to test JavaScript- dependent behaviour.\n\nIf you are testing a Zope application, you need to change the import location slightly, and pass the application root to the method:::\n\n    from plone.testing.zope import Browser\n    browser = Browser(app)\n\nYou can get the application root from the ``app`` resource in any of the Zope layers in this package.\n\nBeyond that, the `zope.testbrowser`_ documentation should cover how to use the test browser.\n\n    **Hint:** The test browser will usually commit at the end of a request.\n    To avoid test fixture contamination, you should use a layer that fully isolates each test, such as the ``zope.INTEGRATION_TESTING`` layer described below.\n\nLayer reference\n===============\n\n``plone.testing`` comes with several layers that are available to use directly or extend.\nThese are outlined below.\n\nZope Component Architecture\n---------------------------\n\nThe Zope Component Architecture layers are found in the module ``plone.testing.zca``.\nIf you depend on this, you can use the ``[zca]`` extra when depending on ``plone.testing``.\n\nUnit testing\n~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zca.UNIT_TESTING``               |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zca.UnitTesting``                |\n+------------+--------------------------------------------------+\n| Bases:     | None                                             |\n+------------+--------------------------------------------------+\n| Resources: | None                                             |\n+------------+--------------------------------------------------+\n\nThis layer does not set up a fixture per se, but cleans up global state before and after each test, using ``zope.testing.cleanup`` as described above.\n\nThe net result is that each test has a clean global component registry.\nThus, it is safe to use the `zope.component`_ Python API (``provideAdapter()``, ``provideUtility()``, ``provideHandler()`` and so on) to register components.\n\nBe careful with using this layer in combination with other layers.\nBecause it tears down the component registry between each test, it will clobber any layer that sets up more permanent test fixture in the component registry.\n\nEvent testing\n~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zca.EVENT_TESTING``              |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zca.EventTesting``               |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zca.UNIT_TESTING``               |\n+------------+--------------------------------------------------+\n| Resources: | None                                             |\n+------------+--------------------------------------------------+\n\nThis layer extends the ``zca.UNIT_TESTING`` layer to enable the ``eventtesting`` support from ``zope.component``.\nUsing this layer, you can import and use ``zope.component.eventtesting.getEvent`` to inspect events fired by the code under test.\n\nSee above for details.\n\nLayer cleanup\n~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zca.LAYER_CLEANUP``              |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zca.LayerCleanup``               |\n+------------+--------------------------------------------------+\n| Bases:     | None                                             |\n+------------+--------------------------------------------------+\n| Resources: | None                                             |\n+------------+--------------------------------------------------+\n\nThis layer calls the cleanup functions from ``zope.testing.cleanup`` on setup and tear-down (but not between each test).\nIt is useful as a base layer for other layers that need an environment as pristine as possible.\n\nBasic ZCML directives\n~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zca.ZCML_DIRECTIVES``            |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zca.ZCMLDirectives``             |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |\n+------------+--------------------------------------------------+\n| Resources: | ``configurationContext``                         |\n+------------+--------------------------------------------------+\n\nThis registers a minimal set of ZCML directives, principally those found in the ``zope.component`` package, and makes available a configuration context.\nThis allows custom ZCML to be loaded as described above.\n\nThe ``configurationContext`` resource should be used when loading custom ZCML.\nTo ensure isolation, you should stack this using the ``stackConfigurationContext()`` helper.\nFor example, if you were writing a ``setUp()`` method in a layer that had ``zca.ZCML_DIRECTIVES`` as a base, you could do:::\n\n    self['configurationContext'] = context = zca.stackConfigurationContext(self.get('configurationContext'))\n    xmlconfig.string(someZCMLString, context=context)\n\nThis will create a new configuration context with the state of the base layer's context.\nOn tear-down, you should delete the layer-specific resource:::\n\n    del self['configurationContext']\n\n.. note::\n\n   If you fail to do this, you may get problems if your layer is torn down and then needs to be set up again later.\n\nSee above for more details about loading custom ZCML in a layer or test.\n\nZCML files helper class\n~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zca.ZCMLSandbox``                |\n+------------+--------------------------------------------------+\n| Resources: | ``configurationContext``                         |\n+------------+--------------------------------------------------+\n\nThe ``ZCMLSandbox`` can be instantiated with a ``filename`` and ``package`` arguments::\n\n    ZCML_SANDBOX = zca.ZCMLSandbox(filename=\"configure.zcml\",\n        package=my.package)\n\n\nThat layer ``setUp`` loads the ZCML file.\nIt avoids the need to using (and understand) ``configurationContext`` and ``globalRegistry`` until you need more flexibility or modularity for your layer and tests.\n\nSee above for more details about loading custom ZCML in a layer or test.\n\nHelper functions\n~~~~~~~~~~~~~~~~\n\nThe following helper functions are available in the ``plone.testing.zca`` module.\n\n``stackConfigurationContext(context=None)``\n\n    Create and return a copy of the passed-in ZCML configuration context, or a brand new context if it is ``None``.\n\n    The purpose of this is to ensure that if a layer loads some ZCML files (using the ``zope.configuration`` API during) during its ``setUp()``, the state of the configuration registry (which includes registered directives as well as a list of already imported files, which will not be loaded again even if explicitly included) can be torn down during ``tearDown()``.\n\n    The usual pattern is to keep the configuration context in a layer resource called ``configurationContext``.\n    In ``setUp()``, you would then use::\n\n        self['configurationContext'] = context = zca.stackConfigurationContext(self.get('configurationContext'))\n\n        # use 'context' to load some ZCML\n\n    In ``tearDown()``, you can then simply do::\n\n        del self['configurationContext']\n\n``pushGlobalRegistry(new=None)``\n\n    Create or obtain a stack of global component registries, and push a new registry to the top of the stack.\n    The net result is that ``zope.component.getGlobalSiteManager()`` and (an un-hooked) ``getSiteManager()`` will return the new registry instead of the default, module-scope one.\n    From this point onwards, calls to ``provideAdapter()``, ``provideUtility()`` and other functions that modify the global registry will use the new registry.\n\n    If ``new`` is not given, a new registry is created that has the previous global registry (site manager) as its sole base.\n    This has the effect that registrations in the previous default global registry are still available, but new registrations are confined to the new registry.\n\n    **Warning**: If you call this function, you *must* reciprocally call ``popGlobalRegistry()``.\n    That is, if you \"push\" a registry during layer ``setUp()``, you must \"pop\" it during ``tearDown()``.\n    If you \"push\" during ``testSetUp()``, you must \"pop\" during ``testTearDown()``.\n    If the calls to push and pop are not balanced, you will leave your global registry in a mess, which is not pretty.\n\n    Returns the new default global site manager.\n    Also causes the site manager hook from ``zope.component.hooks`` to be reset, clearing any local site managers as appropriate.\n\n``popGlobalRegistry()``\n\n    Pop the global site registry, restoring the previous registry to be the default.\n\n    Please heed the warning above: push and pop must be balanced.\n\n    Returns the new default global site manager.\n    Also causes the site manager hook from ``zope.component.hooks`` to be reset, clearing any local site managers as appropriate.\n\nZope Security\n-------------\n\nThe Zope Security layers build can be found in the module ``plone.testing.security``.\n\nIf you depend on this, you can use the ``[security]`` extra when depending on ``plone.testing``.\n\nSecurity checker isolation\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.security.CHECKERS``              |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.security.Checkers``              |\n+------------+--------------------------------------------------+\n| Bases:     | None                                             |\n+------------+--------------------------------------------------+\n| Resources: | None                                             |\n+------------+--------------------------------------------------+\n\nThis layer ensures that security checkers used by ``zope.security`` are isolated.\nAny checkers set up in a child layer will be removed cleanly during tear-down.\n\nHelper functions\n~~~~~~~~~~~~~~~~\n\nThe security checker isolation outlined above is managed using two helper functions found in the module ``plone.testing.security``:\n\n``pushCheckers()``\n\n    Copy the current set of security checkers for later tear-down.\n\n``popCheckers()``\n\n    Restore the set of security checkers to the state of the most recent call to ``pushCheckers()``.\n\nYou *must* keep calls to ``pushCheckers()`` and ``popCheckers()`` in balance.\nThat usually means that if you call the former during layer setup, you should call the latter during layer tear-down.\nDitto for calls during test setup/tear-down or within tests themselves.\n\nZope Publisher\n--------------\n\nThe Zope Publisher layers build on the Zope Component Architecture layers.\nThey can be found in the module ``plone.testing.publisher``.\n\nIf you depend on this, you can use the ``[publisher]`` extra when depending on ``plone.testing``.\n\nPublisher directives\n~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.publisher.PUBLISHER_DIRECTIVES`` |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.publisher.PublisherDirectives``  |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zca.ZCML_DIRECTIVES``            |\n+------------+--------------------------------------------------+\n| Resources: | None                                             |\n+------------+--------------------------------------------------+\n\nThis layer extends the ``zca.ZCML_DIRECTIVES`` layer to install additional ZCML directives in the ``browser`` namespace (from ``zope.app.publisher.browser``) as well as those from ``zope.security``.\nThis allows browser views, browser pages and other UI components to be registered, as well as the definition of new permissions.\n\nAs with ``zca.ZCML_DIRECTIVES``, you should use the ``configurationContext`` resource when loading ZCML strings or files, and the ``stackConfigurationRegistry()`` helper to create a layer-specific version of this resource resource.\nSee above.\n\nZODB\n----\n\nThe ZODB layers set up a test fixture with a persistent ZODB.\nThe ZODB instance uses ``DemoStorage``, so it will not interfere with any \"live\" data.\n\nZODB layers can be found in the module ``plone.testing.zodb``.\nIf you depend on this, you can use the ``[zodb]`` extra when depending on ``plone.testing``.\n\nEmpty ZODB sandbox\n~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zodb.EMPTY_ZODB``                |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zodb.EmptyZODB``                 |\n+------------+--------------------------------------------------+\n| Bases:     |  None                                            |\n+------------+--------------------------------------------------+\n| Resources: | ``zodbRoot``                                     |\n|            +--------------------------------------------------+\n|            | ``zodbDB`` (test set-up only)                    |\n|            +--------------------------------------------------+\n|            | ``zodbConnection`` (test set-up only)            |\n+------------+--------------------------------------------------+\n\nThis layer sets up a simple ZODB sandbox using ``DemoStorage``.\nThe ZODB root object is a simple persistent mapping, available as the resource ``zodbRoot``.\nThe ZODB database object is available as the resource ``zodbDB``.\nThe connection used in the test is available as ``zodbConnection``.\n\nNote that the ``zodbConnection`` and ``zodbRoot`` resources are created and destroyed for each test.\nYou can use ``zodbDB`` (and the ``open()`` method) if you are writing a layer based on this one and need to set up a fixture during layer set up.\nDon't forget to close the connection before concluding the test setup!\n\nA new transaction is begun for each test, and rolled back (aborted) on test tear-down.\nThis means that so long as you don't use ``transaction.commit()`` explicitly in your code, it should be safe to add or modify items in the ZODB root.\n\nIf you want to create a test fixture with persistent data in your own layer based on ``EMPTY_ZODB``, you can use the following pattern::\n\n    from plone.layer import Layer\n    from plone.layer import zodb\n\n    class MyLayer(Layer):\n        defaultBases = (zodb.EMPTY_ZODB,)\n\n        def setUp(self):\n\n            import transaction\n            self['zodbDB'] = db = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')\n\n            conn = db.open()\n            root = conn.root()\n\n            # modify the root object here\n\n            transaction.commit()\n            conn.close()\n\n        def tearDown(self):\n\n            self['zodbDB'].close()\n            del self['zodbDB']\n\nThis shadows the ``zodbDB`` resource with a new database that uses a new ``DemoStorage`` stacked on top of the underlying database storage.\nThe fixture is added to this storage and committed during layer setup.\n(The base layer test set-up/tear-down will still begin and abort a new transaction for each *test*).\nOn layer tear-down, the database is closed and the resource popped, leaving the original ``zodbDB`` database with the original, pristine storage.\n\nHelper functions\n~~~~~~~~~~~~~~~~\n\nOne helper function is available in the ``plone.testing.zodb`` module.\n\n``stackDemoStorage(db=None, name=None)``\n\nCreate a new ``DemoStorage`` using the storage from the passed-in database as a base.\nIf ``db`` is None, a brand new storage is created.\n\nA ``name`` can be given to uniquely identify the storage.\nIt is optional, but it is often useful for debugging purposes to pass the name of the layer.\n\nThe usual pattern is::\n\n    def setUp(self):\n        self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')\n\n    def tearDown(self):\n        self['zodbDB'].close()\n        del self['zodbDB']\n\nThis will shadow the ``zodbDB`` resource with an isolated ``DemoStorage``, creating a new one if that resource does not already exist.\nAll existing data continues to be available, but new changes are written to the stacked storage.\nOn tear-down, the stacked database is closed and the resource removed, leaving the original data.\n\nZope\n----\n\nThe Zope layers provide test fixtures suitable for testing Zope applications.\nThey set up a Zope application root, install core Zope products, and manage security.\n\nZope layers can be found in the module ``plone.testing.zope``.\nIf you depend on this, you can use the ``[zope]`` extra when depending on ``plone.testing``.\n\nStartup\n~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zope.STARTUP``                   |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zope.Startup``                   |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |\n+------------+--------------------------------------------------+\n| Resources: | ``zodbDB``                                       |\n|            +--------------------------------------------------+\n|            | ``configurationContext``                         |\n|            +--------------------------------------------------+\n|            | ``host``                                         |\n|            +--------------------------------------------------+\n|            | ``port``                                         |\n+------------+--------------------------------------------------+\n\nThis layer sets up a Zope environment, and is a required base for all other Zope layers.\nYou cannot run two instances of this layer in parallel, since Zope depends on some module-global state to run, which is managed by this layer.\n\nOn set-up, the layer will configure a Zope environment with:\n\n.. note::\n\n    The ``STARTUP`` layer is a useful base layer for your own fixtures, but should not be used directly, since it provides no test lifecycle or transaction management.\n    See the \"Integration test\" and \"Functional\" test sections below for examples of how to create your own layers.\n\n* Debug mode enabled.\n\n* ZEO client cache disabled.\n\n* Some patches installed, which speed up Zope startup by disabling some superfluous aspects of Zope.\n\n* One thread (this only really affects the ``WSGI_SERVER``, ``ZSERVER`` and ``FTP_SERVER`` layers).\n\n* A pristine database using ``DemoStorage``, exposed as the resource ``zodbDB``.\n  Zope is configured to use this database in a way that will also work if the ``zodbDB`` resource is shadowed using the pattern shown above in the description of the ``zodb.EMPTY_ZODB`` layer.\n\n* A fake hostname and port, exposed as the ``host`` and ``port`` resource, respectively.\n\n* A minimal set of products installed (``Products.OFSP`` and ``Products.PluginIndexes``, both required for Zope to start up).\n\n* A stacked ZCML configuration context, exposed as the resource ``configurationContext``.\n  As illustrated above, you should use the ``zca.stackConfigurationContext()`` helper to stack your own configuration context if you use this.\n\n* A minimal set of global Zope components configured.\n\nNote that unlike a \"real\" Zope site, products in the ``Products.*`` namespace are not automatically loaded, nor is any ZCML.\n\nIntegration test\n~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zope.INTEGRATION_TESTING``       |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zope.IntegrationTesting``        |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zope.STARTUP``                   |\n+------------+--------------------------------------------------+\n| Resources: | ``app``                                          |\n|            +--------------------------------------------------+\n|            | ``request``                                      |\n+------------+--------------------------------------------------+\n\nThis layer is intended for integration testing against the simple ``STARTUP`` fixture.\nIf you want to create your own layer with a more advanced, shared fixture, see \"Integration and functional testing with custom fixtures\" below.\n\nFor each test, it exposes the Zope application root as the resource ``app``.\nThis is wrapped in the request container, so you can do ``app.REQUEST`` to acquire a fake request, but the request is also available as the resource ``request``.\n\nA new transaction is begun for each test and rolled back on test tear-down, meaning that so long as the code under test does not explicitly commit any changes, the test may modify the ZODB.\n\n    *Hint:* If you want to set up a persistent test fixture in a layer based on this one (or ``zope.FUNCTIONAL_TESTING``), you can stack a new ``DemoStorage`` in a shadowing ``zodbDB`` resource, using the pattern described above for the ``zodb.EMPTY_ZODB`` layer.\n\n    Once you've shadowed the ``zodbDB`` resource, you can do (e.g. in your layer's ``setUp()`` method)::\n\n        ...\n        with zope.zopeApp() as app:\n            # modify the Zope application root\n\n    The ``zopeApp()`` context manager will open a new connection to the Zope application root, accessible here as ``app``.\n    Provided the code within the ``with`` block does not raise an exception, the transaction will be committed and the database closed properly upon exiting the block.\n\nFunctional testing\n~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zope.FUNCTIONAL_TESTING``        |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zope.FunctionalTesting``         |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zope.STARTUP``                   |\n+------------+--------------------------------------------------+\n| Resources: | ``app``                                          |\n|            +--------------------------------------------------+\n|            | ``request``                                      |\n+------------+--------------------------------------------------+\n\nThis layer is intended for functional testing against the simple ``STARTUP`` fixture.\nIf you want to create your own layer with a more advanced, shared fixture, see \"Integration and functional testing with custom fixtures\" below.\n\nAs its name implies, this layer is intended mainly for functional end-to-end testing using tools like `zope.testbrowser`_.\nSee also the ``Browser`` object as described under \"Helper functions\" below.\n\nThis layer is very similar to ``INTEGRATION_TESTING``, but is not based on it.\nIt sets up the same fixture and exposes the same resources.\nHowever, instead of using a simple transaction abort to isolate the ZODB between tests, it uses a stacked ``DemoStorage`` for each test.\nThis is slower, but allows test code to perform and explicit commit, as will usually happen in a functional test.\n\nIntegration and functional testing with custom fixtures\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf you want to extend the ``STARTUP`` fixture for use with integration or functional testing, you should use the following pattern:\n\n* Create a layer class and a \"fixture\" base layer instance that has ``zope.STARTUP`` (or some intermediary layer, such as ``zope.WSGI_SERVER_FIXTURE``, shown below) as a base.\n\n* Create \"end user\" layers by instantiating the ``zope.IntegrationTesting`` and/or ``FunctionalTesting`` classes with this new \"fixture\" layer as a base.\n\nThis allows the same fixture to be used regardless of the \"style\" of testing, minimising the amount of set-up and tear-down.\nThe \"fixture\" layers manage the fixture as part of the *layer* lifecycle.\nThe layer class (``IntegrationTesting`` or ``FunctionalTesting``), manages the *test* lifecycle, and the test lifecycle only.\n\nFor example::\n\n    from plone.testing import Layer, zope, zodb\n\n    class MyLayer(Layer):\n        defaultBases = (zope.STARTUP,)\n\n        def setUp(self):\n            # Set up the fixture here\n            ...\n\n        def tearDown(self):\n            # Tear down the fixture here\n            ...\n\n    MY_FIXTURE = MyLayer()\n\n    MY_INTEGRATION_TESTING = zope.IntegrationTesting(bases=(MY_FIXTURE,), name=\"MyFixture:Integration\")\n    MY_FUNCTIONAL_TESTING = zope.FunctionalTesting(bases=(MY_FIXTURE,), name=\"MyFixture:Functional\")\n\n(Note that we need to give an explicit, unique name to the two layers that reuse the ``IntegrationTesting`` and ``FunctionalTesting`` classes.)\n\nIn this example, other layers could extend the \"MyLayer\" fixture by using ``MY_FIXTURE`` as a base.\nTests would use either ``MY_INTEGRATION_TESTING`` or ``MY_FUNCTIONAL_TESTING`` as appropriate.\nHowever, even if both these two layers were used, the fixture in ``MY_FIXTURE`` would only be set up once.\n\n.. note::\n\n    If you implement the ``testSetUp()`` and ``testTearDown()`` test lifecycle methods in your \"fixture\" layer (e.g. in the the ``MyLayer`` class above), they will execute before the corresponding methods from ``IntegrationTesting`` and ``FunctionalTesting``.\n    Hence, they cannot use those layers' resources (``app`` and ``request``).\n\nIt may be preferable, therefore, to have your own \"test lifecycle\" layer classes that subclass ``IntegrationTesting`` and/or ``FunctionalTesting`` and call base class methods as appropriate.\n``plone.app.testing`` takes this approach, for example.\n\nHTTP WSGI server thread (fixture only)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zope.WSGI_SERVER_FIXTURE``       |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zope.WSGIServer``                |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zope.STARTUP``                   |\n+------------+--------------------------------------------------+\n| Resources: | ``host``                                         |\n|            +--------------------------------------------------+\n|            | ``port``                                         |\n+------------+--------------------------------------------------+\n\nThis layer extends the ``zope.STARTUP`` layer to start the Zope HTTP WSGI server in a separate thread.\nThis means the test site can be accessed through a web browser, and can thus be used with tools like `Selenium`_.\n\n.. note::\n\n    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.\n    Use the ``WSGI_SERVER`` layer if you want to execute functional tests against this fixture.\n\nThe WSGI server's hostname (normally ``localhost``) is available through the resource ``host``, whilst the port it is running on is available through the resource ``port``.\n\n  *Hint:* Whilst the layer is set up, you can actually access the test Zope site through a web browser.\n  The default URL will be ``http://localhost:55001``.\n\nHTTP WSGI server functional testing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zope.WSGI_SERVER``               |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zope.FunctionalTesting``         |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zope.WSGI_SERVER_FIXTURE``       |\n+------------+--------------------------------------------------+\n| Resources: |                                                  |\n+------------+--------------------------------------------------+\n\nThis layer provides the functional testing lifecycle against the fixture set up by the ``zope.WSGI_SERVER_FIXTURE`` layer.\n\nYou can use this to run \"live\" functional tests against a basic Zope site.\nYou should **not** use it as a base.\nInstead, create your own \"fixture\" layer that extends ``zope.WSGI_SERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.\n\nHelper functions\n~~~~~~~~~~~~~~~~\n\nSeveral helper functions are available in the ``plone.testing.zope`` module.\n\n``zopeApp(db=None, conn=Non, environ=None)``\n\n    This function can be used as a context manager for any code that requires access to the Zope application root.\n    By using it in a ``with`` block, the database will be opened, and the application root will be obtained and request-wrapped.\n    When exiting the ``with`` block, the transaction will be committed and the database properly closed, unless an exception was raised::\n\n        with zope.zopeApp() as app:\n            # do something with app\n\n    If you want to use a specific database or database connection, pass either the ``db`` or ``conn`` arguments.\n    If the context manager opened a new connection, it will close it, but it will not close a connection passed with ``conn``.\n\n    To set keys in the (fake) request environment, pass a dictionary of environment values as ``environ``.\n\n    Note that ``zopeApp()`` should *not* normally be used in tests or test set-up/tear-down, because the ``INTEGRATOIN_TEST`` and ``FUNCTIONAL_TESTING`` layers both manage the application root (as the ``app`` resource) and close it for you.\n    It is very useful in layer setup, however.\n\n``installProduct(app, product, quiet=False)``\n\n    Install a Zope 2 style product, ensuring that its ``initialize()`` function is called.\n    The product name must be the full dotted name, e.g. ``plone.app.portlets`` or ``Products.CMFCore``.\n    If ``quiet`` is true, duplicate registrations will be ignored silently, otherwise a message is logged.\n\n    To get hold of the application root, passed as the ``app`` argument, you would normally use the ``zopeApp()`` context manager outlined above.\n\n``uninstallProduct(app, product, quiet=False)``\n\n    This is the reciprocal of ``installProduct()``, normally used during layer tear-down.\n    Again, you should use ``zopeApp()`` to obtain the application root.\n\n``login(userFolder, userName)``\n\n    Create a new security manager that simulates being logged in as the given user.\n    ``userFolder`` is an ``acl_users`` object, e.g. ``app['acl_users']`` for the root user folder.\n\n``logout()``\n\n    Simulate being the anonymous user by unsetting the security manager.\n\n``setRoles(userFolder, userName, roles)``\n\n    Set the roles of the given user in the given user folder to the given list of roles.\n\n``makeTestRequest()``\n\n    Create a fake Zope request.\n\n``addRequestContainer(app, environ=None)``\n\n    Create a fake request and wrap the given object (normally an application root) in a ``RequestContainer`` with this request.\n    This makes acquisition of ``app.REQUEST`` possible.\n    To initialise the request environment with non-default values, pass a dictionary as ``environ``.\n\n    .. note::\n\n       This method is rarely used, because both the ``zopeApp()``\n       context manager and the layer set-up/tear-down for\n       ``zope.INTEGRATION_TESTING`` and ``zope.FUNCTIONAL_TESTING`` will wrap the\n       ``app`` object before exposing it.\n\n``Browser(app)``\n\n    Obtain a test browser client, for use with `zope.testbrowser`_.\n    You should use this in conjunction with the ``zope.FUNCTIONAL_TESTING`` layer or a derivative.\n    You must pass the app root, usually obtained from the ``app`` resource of the layer, e.g.::\n\n        app = self.layer['app']\n        browser = zope.Browser(app)\n\n    You can then use ``browser`` as described in the `zope.testbrowser`_ documentation.\n\n    Bear in mind that the test browser runs separately from the test fixture.\n    In particular, calls to helpers such as ``login()`` or ``logout()`` do not affect the state that the test browser sees.\n    If you want to set up a persistent fixture (e.g. test content), you can do so before creating the test browser, but you will need to explicitly commit your changes, with::\n\n        import transaction\n        transaction.commit()\n\n\nZServer\n-------\n\nThe ZServer layers provide test fixtures suitable for testing Zope applications while using ZServer instead of a WSGI server.\nThey set up a Zope application root, install core Zope products, and manage security.\n\nZServer layers can be found in the module ``plone.testing.zserver``.\nIf you depend on this, you can use the ``[zope,zserver]`` extra when depending on ``plone.testing``.\n\nStartup\n~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.STARTUP``                |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.Startup``                |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zca.LAYER_CLEANUP``              |\n+------------+--------------------------------------------------+\n| Resources: | ``zodbDB``                                       |\n|            +--------------------------------------------------+\n|            | ``configurationContext``                         |\n|            +--------------------------------------------------+\n|            | ``host``                                         |\n|            +--------------------------------------------------+\n|            | ``port``                                         |\n+------------+--------------------------------------------------+\n\nThis layer sets up a Zope environment for ZServer, and is a required base for all other ZServer layers.\nYou cannot run two instances of this layer in parallel, since Zope depends on some module-global state to run, which is managed by this layer.\n\nOn set-up, the layer will configure a Zope environment with the same options as ``zope.Startup``, see there.\n\nIntegration test\n~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.INTEGRATION_TESTING``    |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.IntegrationTesting``     |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.STARTUP``                |\n+------------+--------------------------------------------------+\n| Resources: | ``app``                                          |\n|            +--------------------------------------------------+\n|            | ``request``                                      |\n+------------+--------------------------------------------------+\n\nThis layer is intended for integration testing against the simple ``STARTUP`` fixture.\nIf you want to create your own layer with a more advanced, shared fixture, see \"Integration and functional testing with custom fixtures\" below.\n\nFor each test, it exposes the Zope application root as the resource ``app``.\nThis is wrapped in the request container, so you can do ``app.REQUEST`` to acquire a fake request, but the request is also available as the resource ``request``.\n\nA new transaction is begun for each test and rolled back on test tear-down, meaning that so long as the code under test does not explicitly commit any changes, the test may modify the ZODB.\n\n    *Hint:* If you want to set up a persistent test fixture in a layer based on this one (or ``zserver.FUNCTIONAL_TESTING``), you can stack a new ``DemoStorage`` in a shadowing ``zodbDB`` resource, using the pattern described above for the ``zodb.EMPTY_ZODB`` layer.\n\n    Once you've shadowed the ``zodbDB`` resource, you can do (e.g. in your layer's ``setUp()`` method)::\n\n        ...\n        with zserver.zopeApp() as app:\n            # modify the Zope application root\n\n    The ``zserver.zopeApp()`` context manager will open a new connection to the Zope application root, accessible here as ``app``.\n    Provided the code within the ``with`` block does not raise an exception, the transaction will be committed and the database closed properly upon exiting the block.\n\nFunctional testing\n~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.FUNCTIONAL_TESTING``     |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.FunctionalTesting``      |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.STARTUP``                |\n+------------+--------------------------------------------------+\n| Resources: | ``app``                                          |\n|            +--------------------------------------------------+\n|            | ``request``                                      |\n+------------+--------------------------------------------------+\n\nIt behaves the same as ``zope.FunctionalTesting``, see there.\n\n\nIntegration and functional testing with custom fixtures\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf you want to extend the ``STARTUP`` fixture for use with integration or functional testing, you should use the following pattern:\n\n* Create a layer class and a \"fixture\" base layer instance that has ``zserver.STARTUP`` (or some intermediary layer, such as ``zserver.ZSERVER_FIXTURE`` or ``zserver.FTP_SERVER_FIXTURE``, shown below) as a base.\n\n* Create \"end user\" layers by instantiating the ``zserver.IntegrationTesting`` and/or ``FunctionalTesting`` classes with this new \"fixture\" layer as a base.\n\nThis allows the same fixture to be used regardless of the \"style\" of testing, minimising the amount of set-up and tear-down.\nThe \"fixture\" layers manage the fixture as part of the *layer* lifecycle.\nThe layer class (``IntegrationTesting`` or ``FunctionalTesting``), manages the *test* lifecycle, and the test lifecycle only.\n\nFor example::\n\n    from plone.testing import Layer, zserver, zodb\n\n    class MyLayer(Layer):\n        defaultBases = (zserver.STARTUP,)\n\n        def setUp(self):\n            # Set up the fixture here\n            ...\n\n        def tearDown(self):\n            # Tear down the fixture here\n            ...\n\n    MY_FIXTURE = MyLayer()\n\n    MY_INTEGRATION_TESTING = zserver.IntegrationTesting(bases=(MY_FIXTURE,), name=\"MyFixture:Integration\")\n    MY_FUNCTIONAL_TESTING = zserver.FunctionalTesting(bases=(MY_FIXTURE,), name=\"MyFixture:Functional\")\n\n(Note that we need to give an explicit, unique name to the two layers that reuse the ``IntegrationTesting`` and ``FunctionalTesting`` classes.)\n\nIn this example, other layers could extend the \"MyLayer\" fixture by using ``MY_FIXTURE`` as a base.\nTests would use either ``MY_INTEGRATION_TESTING`` or ``MY_FUNCTIONAL_TESTING`` as appropriate.\nHowever, even if both these two layers were used, the fixture in ``MY_FIXTURE`` would only be set up once.\n\n.. note::\n\n    If you implement the ``testSetUp()`` and ``testTearDown()`` test lifecycle methods in your \"fixture\" layer (e.g. in the the ``MyLayer`` class above), they will execute before the corresponding methods from ``IntegrationTesting`` and ``FunctionalTesting``.\n    Hence, they cannot use those layers' resources (``app`` and ``request``).\n\nIt may be preferable, therefore, to have your own \"test lifecycle\" layer classes that subclass ``IntegrationTesting`` and/or ``FunctionalTesting`` and call base class methods as appropriate.\n``plone.app.testing`` takes this approach, for example.\n\n\nHTTP ZServer thread (fixture only)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.ZSERVER_FIXTURE``        |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.ZServer``                |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.STARTUP``                |\n+------------+--------------------------------------------------+\n| Resources: | ``host``                                         |\n|            +--------------------------------------------------+\n|            | ``port``                                         |\n+------------+--------------------------------------------------+\n\nThis layer extends the ``zserver.STARTUP`` layer to start the Zope HTTP server (ZServer) in a separate thread.\nThis means the test site can be accessed through a web browser, and can thus be used with tools like `Selenium`_.\n\n.. note::\n\n    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.\n    Use the ``ZSERVER`` layer if you want to execute functional tests against this fixture.\n\nThe ZServer's hostname (normally ``localhost``) is available through the resource ``host``, whilst the port it is running on is available through the resource ``port``.\n\n  *Hint:* Whilst the layer is set up, you can actually access the test Zope site through a web browser.\n  The default URL will be ``http://localhost:55001``.\n\nHTTP ZServer functional testing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.ZSERVER``                |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.FunctionalTesting``      |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.ZSERVER_FIXTURE``        |\n+------------+--------------------------------------------------+\n| Resources: |                                                  |\n+------------+--------------------------------------------------+\n\nThis layer provides the functional testing lifecycle against the fixture set up by the ``zserver.ZSERVER_FIXTURE`` layer.\n\nYou can use this to run \"live\" functional tests against a basic Zope site.\nYou should **not** use it as a base.\nInstead, create your own \"fixture\" layer that extends ``zserver.ZSERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.\n\n\nFTP server thread (fixture only)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.FTP_SERVER_FIXTURE``     |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.FTPServer``              |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.STARTUP``                |\n+------------+--------------------------------------------------+\n| Resources: | ``host``                                         |\n|            +--------------------------------------------------+\n|            | ``port``                                         |\n+------------+--------------------------------------------------+\n\nThis layer is the FTP server equivalent of the ``zserver.ZSERVER_FIXTURE`` layer.\nIt can be used to functionally test Zope FTP servers.\n\n.. note::\n\n    This layer is useful as a fixture base layer only, because it does not manage the test lifecycle.\n    Use the ``FTP_SERVER`` layer if you want to execute functional tests against this fixture.\n\n    *Hint:* Whilst the layer is set up, you can actually access the test Zope site through an FTP client.\n    The default URL will be ``ftp://localhost:55002``.\n\n.. warning::\n\n    Do not run the ``FTP_SERVER`` and ``ZSERVER`` layers concurrently in the same process.\n\nIf you need both ZServer and FTPServer running together, you can subclass the ``ZServer`` layer class (like the ``FTPServer`` layer class does) and implement the ``setUpServer()`` and ``tearDownServer()`` methods to set up and close down two servers on different ports.\nThey will then share a main loop.\n\nFTP server functional testing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------+--------------------------------------------------+\n| Layer:     | ``plone.testing.zserver.FTP_SERVER``             |\n+------------+--------------------------------------------------+\n| Class:     | ``plone.testing.zserver.FunctionalTesting``      |\n+------------+--------------------------------------------------+\n| Bases:     | ``plone.testing.zserver.FTP_SERVER_FIXTURE``     |\n+------------+--------------------------------------------------+\n| Resources: |                                                  |\n+------------+--------------------------------------------------+\n\nThis layer provides the functional testing lifecycle against the fixture set up by the ``zserver.FTP_SERVER_FIXTURE`` layer.\n\nYou can use this to run \"live\" functional tests against a basic Zope site.\nYou should **not** use it as a base.\nInstead, create your own \"fixture\" layer that extends ``zserver.FTP_SERVER_FIXTURE``, and then instantiate the ``FunctionalTesting`` class with this extended fixture layer as a base, as outlined above.\n\nHelper functions\n~~~~~~~~~~~~~~~~\n\nSeveral helper functions are available in the ``plone.testing.zserver`` module.\n\n``zopeApp(db=None, conn=Non, environ=None)``\n\n    This function can be used as a context manager for any code that requires access to the Zope application root.\n    By using it in a ``with`` block, the database will be opened, and the application root will be obtained and request-wrapped.\n    When exiting the ``with`` block, the transaction will be committed and the database properly closed, unless an exception was raised::\n\n        with zserver.zopeApp() as app:\n            # do something with app\n\n    If you want to use a specific database or database connection, pass either the ``db`` or ``conn`` arguments.\n    If the context manager opened a new connection, it will close it, but it will not close a connection passed with ``conn``.\n\n    To set keys in the (fake) request environment, pass a dictionary of environment values as ``environ``.\n\n    Note that ``zopeApp()`` should *not* normally be used in tests or test set-up/tear-down, because the ``INTEGRATOIN_TEST`` and ``FUNCTIONAL_TESTING`` layers both manage the application root (as the ``app`` resource) and close it for you.\n    It is very useful in layer setup, however.\n\nThe other helper functions defined in ``plone.testing.zope`` can also be used in a ZServer context but together with the ZServer layers.\n\n.. _zope.testing: https://pypi.org/project/zope.testing/\n.. _zope.testbrowser: https://pypi.org/project/zope.testbrowser\n.. _zope.component: https://pypi.org/project/zope.component\n.. _zope.publisher: https://pypi.org/project/zope.publisher\n.. _plone.app.testing: https://pypi.org/project/plone.app.testing\n.. _zc.recipe.testrunner: https://pypi.org/project/zc.recipe.testrunner\n.. _coverage: https://pypi.org/project/coverage\n.. _Cobertura: https://wiki.jenkins.io/display/JENKINS/Cobertura+Plugin\n.. _Jenkins: https://jenkins.io\n.. _unittest: http://doc.python.org/library/unittest.html\n.. _doctest: http://docs.python.org/dev/library/doctest.html\n.. _Selenium: http://seleniumhq.org/\n\n\nChangelog\n=========\n\n.. You should *NOT* be adding new change log entries to this file.\n   You should create a file in the news directory instead.\n   For helpful instructions, please see:\n   https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst\n\n.. towncrier release notes start\n\n9.0.1 (2023-11-30)\n------------------\n\nBug fixes:\n\n\n- Remove incorrect hard dependency on five.localsitemanager. @davisagli (#86)\n\n\n9.0.0 (2023-10-25)\n------------------\n\nBreaking changes:\n\n\n- Drop python 2.7 support.\n  [gforcada] (#1)\n- Drop ZServer support.\n  [gforcada] (#2)\n\n\nInternal:\n\n\n- Update configuration files.\n  [plone devs] (5cc689e5)\n\n\n8.0.4 (2023-09-21)\n------------------\n\nBug fixes:\n\n\n- Fix tests when run with ZODB 5.8.1+.\n  [maurits] (#581)\n\n\n8.0.3 (2021-06-14)\n------------------\n\nBug fixes:\n\n\n- fix waitress deprecation warning (#77)\n- Catch OSError in test teardown when removing a temporary directory.\n  Fixes `issue 79 <https://github.com/plone/plone.testing/issues/79>`_.\n  [maurits] (#79)\n\n\n8.0.2 (2020-10-12)\n------------------\n\nBug fixes:\n\n\n- update `isort` configuration for version 5 of `isort` (#75)\n\n\n8.0.1 (2020-06-16)\n------------------\n\nBug fixes:\n\n\n- fix broken Flake8 job (#74)\n\n\n8.0.0 (2020-04-21)\n------------------\n\nBreaking changes:\n\n\n- Drop support for Python 3.4 and 3.5.\n  Remove \"z2\" extra.\n  [jensens] (#72)\n\n\nNew features:\n\n\n- Update links for further information about `testing`.\n  [jugmac00] (#71)\n\n\nBug fixes:\n\n\n- Fix tests when using zope.testrunner internals since its version 5.1.\n  [jensens] (#72)\n\n\n7.0.3 (2019-12-10)\n------------------\n\nBug fixes:\n\n\n- Fix issue with test-setup when using ZServer 4.0.2.\n  [pbauer] (#69)\n\n\n7.0.2 (2019-07-06)\n------------------\n\nBug fixes:\n\n\n- Remove the ``ZOPETESTCASEALERT`` as it imports from ZopeTestCase and has side effects.\n  Fixes #64.\n  [thet] (#67)\n\n\n7.0.1 (2019-03-03)\n------------------\n\nBug fixes:\n\n\n- Fixed test for 'Connection refused' which could be 'Connection reset'.\n  [maurits] (#59)\n\n\n7.0.0 (2018-10-17)\n------------------\n\nBreaking changes:\n\n- ``plone.testing.z2`` is now a BBB shim for ``plone.testing.zope``,\n  thus it switches the tests to use WSGI.\n  If you absolutely want to keep using ZServer please import from ``plone.testing.zserver``.\n\n- ``plone.testing.z2`` now only contains a no-op FTPServer layer because FTP is not supported by WSGI.\n  If you really need it, import it from ``plone.testing.zserver`` but this will not work on Python 3.\n  \n- Default to picking a dynamical port for ZServer layers instead of a static\n  default port.\n  [Rotonen]\n\nNew features:\n\n- Make ``ZServer`` an optional dependency.\n\n- Add support for Python 3.6.\n  [rudaporto, icemac]\n\nBug fixes:\n\n- Explicitly depend on ZServer on the z2 extra.\n  [Rotonen]\n\n\n6.1.0 (2018-10-05)\n------------------\n\nBreaking changes:\n\n- Default to picking a dynamical port for ZServer layers instead of a static\n  default port.\n  [Rotonen]\n\nBug fixes:\n\n- Pinned ZODB to < 5.4.0 for testing to avoid flaky doctest layer teardowns.\n  [Rotonen]\n\n- Loosened doctest assertions to keep up with Zope-side changes.\n  [Rotonen]\n\n- Fix most of the code smells Jenkins complains about.\n\n- Fix the Zope exception hook when using the ZServer layer.\n\n- Fix teardown of the ``plone.testing.security.Checkers`` layer.\n  It was not properly restoring zope.security's ``_checkers`` dict.\n\n\n6.0.0 (2018-02-05)\n------------------\n\n- Breaking changes:\n\n  + Only support ``Zope >= 4``, no longer support ``Zope2``.\n  + Drop support for Python 2.6.\n\n- No longer use deprecated import for getSite/setSite.\n  [jensens]\n\n- Update code to follow Plone styleguide.\n  [gforcada]\n\n\n5.1.1 (2017-04-19)\n------------------\n\n- Do not break on import of ``plone.testing.z2`` when using `zope.testbrowser` >= 5.0 which no longer depends on `mechanize`.\n\n\n5.1 (2017-04-13)\n----------------\n\n- Fix for ZODB 5: Abort transaction before DB close.\n  [jensens, jimfulton]\n\n- Remove BBB code and imports for Zope < 2.13.\n  [thet]\n\n- Fix issue, which prevented using layered-helper on Python 3.\n  [datakurre]\n\n- Fix ``.z2.Startup.setUpZCML()`` to be compatible with Zope >= 4.0a2.\n  [icemac]\n\n- Fix version pins on the package itself to be able to run the tests.\n  [gforcada]\n\n5.0.0 (2016-02-19)\n------------------\n\nRerelease of 4.2.0 as 5.0.0.\n\nThe version 4.2.0 had changed error handling in the public api, causing exceptions where before everything continued to work.\n\n\n4.2.0 (2016-02-18)\n------------------\n\nNew:\n\n- Refuse to work if user breaks test isolation.\n  [do3cc]\n- Check that tests don't run together with ZopeTestCase\n  [do3cc]\n\nFixes:\n\n- Fix tests for Zope 4, where the app root Control_Panel is not available anymore.\n  [thet]\n\n\n4.1.0 (2016-01-08)\n------------------\n\nFixes:\n\n- Rename all txt doctest files to rst. Reformat doctests.\n  [thet]\n\n- PEP 8.\n  [thet]\n\n- Depend on zope.testrunner, which was moved out from zope.testing.testrunner.\n  [thet]\n\n- Add support for Zope 4.\n  [thet]\n\n\n4.0.15 (2015-08-14)\n-------------------\n\n- Prevent exception masking in finally clause of zopeApp context.\n  [do3cc]\n\n\n4.0.14 (2015-07-29)\n-------------------\n\n- Rerelease for clarity due to double release of 4.0.13.\n  [maurits]\n\n- Added ``multiinit``-parameter to z2.installProduct to allow multiple initialize methods for a package\n  [tomgross]\n\n\n4.0.13 (2015-03-13)\n-------------------\n\n- Really fix not to depend on unittest2.\n  [icemac]\n\n- Add tox.ini\n  [icemac]\n\n\n4.0.12 (2014-09-07)\n-------------------\n\n- Fixed AttributeError when importing ``plone.testing.z2`` if ``zope.testbrowser`` 4.x is used but not ``zope.app.testing``.\n  [icemac]\n\n- Broke dependency on `unittest2` for Python 2.7+ as all features of `unittest2` are integrated in `unittest` there.\n  [icemac]\n\n\n4.0.11 (2014-02-22)\n-------------------\n\n- Fix z2.txt doctest for FTP_SERVER.\n  [timo]\n\n\n4.0.10 (2014-02-11)\n-------------------\n\n- Read 'FTPSERVER_HOST' and 'FTPSERVER_PORT' from the environment variables if possible.\n  This allows us to run tests in parallel on CI servers.\n  [timo]\n\n\n4.0.9 (2014-01-28)\n------------------\n\n- Replace deprecated Zope2VocabularyRegistry import.\n  [timo]\n\n\n4.0.8 (2013-03-05)\n------------------\n\n- Factor test request creation out of addRequestContainer into makeTestRequest.\n  [davisagli]\n\n\n4.0.7 (2012-12-09)\n------------------\n\n- Fix quoting of urls by the testbrowser.\n  [do3cc]\n\n\n4.0.6 (2012-10-15)\n------------------\n\n- Update manifest.in to include content in src directory.\n  [esteele]\n\n\n4.0.5 (2012-10-15)\n------------------\n\n- Fixed an issue where a query string would be unquoted twice;\n  once while setting up the HTTP request and once in the handler (the publisher).\n  [malthe]\n\n\n4.0.4 (2012-08-04)\n------------------\n\n- Fixed the cache reset code.\n  In some situations the function does not have any defaults,\n  so we shouldn't try to clear out the app reference.\n  [malthe]\n\n\n4.0.3 (2011-11-24)\n------------------\n\n- Fixed class names in documentation to match code.\n  [icemac]\n\n\n4.0.2 (2011-08-31)\n------------------\n\n- The defaults of the ``ZPublisher.Publish.get_module_info`` function cache\n  a reference to the app, so make sure that gets reset when tearing down the\n  app. This fixes a problem where the testbrowser in the second functional\n  layer to be set up accessed the database from the first functional layer.\n  [davisagli]\n\n\n4.0.1 - 2011-05-20\n------------------\n\n- Moved readme file containing tests into the package, so tests can be run from\n  released source distributions. Closes http://dev.plone.org/plone/ticket/11821.\n  [hannosch]\n\n- Relicense under BSD license.\n  See http://plone.org/foundation/materials/foundation-resolutions/plone-framework-components-relicensing-policy\n  [davisagli]\n\n\n4.0 - 2011-05-13\n----------------\n\n- Release 4.0 Final.\n  [esteele]\n\n- Add MANIFEST.in.\n  [WouterVH]\n\n\n4.0a6 - 2011-04-06\n------------------\n\n- Fixed Browser cookies retrieval with Zope 2.13.\n  [vincentfretin]\n\n- Add ``ZCMLSandbox`` layer to load a ZCML file; replaces ``setUpZcmlFiles`` and\n  ``tearDownZcmlFiles`` helper functions.\n  [gotcha]\n\n\n4.0a5 - 2011-03-02\n------------------\n\n- Handle test failures due to userFolderAddUser returning the user object in\n  newer versions of Zope.\n  [esteele]\n\n- Add ``setUpZcmlFiles`` and ``tearDownZcmlFiles`` helpers to enable loading\n  of ZCML files without too much boilerplate.\n  [gotcha]\n\n- Add some logging.\n  [gotcha]\n\n- Add the ``[security]`` extra, to provide tear-down of security checkers.\n  [optilude]\n\n- Let the ``IntegrationTesting`` and ``FunctionalTesting`` lifecycle layers\n  set up request ``PARENTS`` and, if present, wire up\n  ``zope.globalrequest``.\n  [optilude]\n\n- Make the test browser support IStreamIterators\n  [optilude]\n\n\n4.0a4 - 2011-01-11\n------------------\n\n- Make sure ZCML doesn't load during App startup in Zope 2.13.\n  [davisagli]\n\n\n4.0a3 - 2010-12-14\n------------------\n\n- Ignore the `testinghome` configuration setting if present.\n  [stefan]\n\n- Use the new API for getting the packages_to_initialize list in Zope 2.13.\n  [davisagli]\n\n- De-duplicate _register_monkies and _meta_type_regs in the correct module on\n  teardown of the Startup layer in Zope 2.13.\n  [davisagli]\n\n- Allow doctest suites from `zope.testing` to work with `plone.testing.layer.layered`.\n  Previously, only doctest suites from the stdlib would see the `layer` global.\n  [nouri]\n\n- Changed documentation to advertise the `coverage` library for running\n  coverage tests instead of the built-in `zope.testing` support. This also\n  avoids using `z3c.coverage`. The coverage tests now run at the same speed\n  as a normal test run, making it more likely to get executed frequently.\n  [hannosch]\n\n- Correct license to GPL version 2 only.\n  [hannosch]\n\n- Fix some user id vs name confusion.\n  [rossp]\n\n- Add the option to specify ZServer host and port through environment\n  variables - ZSERVER_HOST and ZSERVER_PORT).\n  [esteele]\n\n\n1.0a2 - 2010-09-05\n------------------\n\n- Fix a problem that would cause ``<meta:redefinePermission />`` to break.\n  In particular fixes the use of the ``zope2.Public`` permission.\n  [optilude]\n\n- Set the security implementation to \"Python\" for easier debugging during\n  the z2.STARTUP layer.\n  [optilude]\n\n- Initialize Five in the z2.Startup layer, pushing a Zope2VocabularyRegistry on\n  layer set-up and restoring the previous one upon tear-down.\n  [dukebody]\n\n\n1.0a1 - 2010-08-01\n------------------\n\n- Initial release\n\n\nDetailed documentation\n======================\n\nLayer base class\n----------------\n\nThis package provides a layer base class which can be used by the test runner.\nIt is available as a convenience import from the package root.::\n\n    >>> from plone.testing import Layer\n\nA layer may be instantiated directly, though in this case the ``name`` argument is required (see below).::\n\n    >>> NULL_LAYER = Layer(name=\"Null layer\")\n\nThis is not very useful on its own.\nIt has an empty list of bases, and each of the layer lifecycle methods does nothing.::\n\n    >>> NULL_LAYER.__bases__\n    ()\n    >>> NULL_LAYER.__name__\n    'Null layer'\n    >>> NULL_LAYER.__module__\n    'plone.testing.layer'\n\n    >>> NULL_LAYER.setUp()\n    >>> NULL_LAYER.testSetUp()\n    >>> NULL_LAYER.tearDown()\n    >>> NULL_LAYER.testTearDown()\n\nJust about the only reason to use this directly (i.e. not as a base class) is to group together other layers.::\n\n    >>> SIMPLE_LAYER = Layer(bases=(NULL_LAYER,), name=\"Simple layer\", module='plone.testing.tests')\n\nHere, we've also set the module name directly.\nThe default for all layers is to take the module name from the stack frame where the layer was instantiated.\nIn doctests, that doesn't work, though, so we fall back on the module name of the layer class.\nThe two are often the same, of course.\n\nThis layer now has the bases, name and module we set:::\n\n    >>> SIMPLE_LAYER.__bases__\n    (<Layer 'plone.testing.layer.Null layer'>,)\n\n    >>> SIMPLE_LAYER.__name__\n    'Simple layer'\n\n    >>> SIMPLE_LAYER.__module__\n    'plone.testing.tests'\n\nThe ``name`` argument is required when using ``Layer`` directly (but not when using a subclass):::\n\n    >>> Layer((SIMPLE_LAYER,))\n    Traceback (most recent call last):\n    ...\n    ValueError: The `name` argument is required when instantiating `Layer` directly\n\n    >>> class NullLayer(Layer):\n    ...     pass\n    >>> NullLayer()\n    <Layer 'builtins.NullLayer'>\n\nUsing ``Layer`` as a base class\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe usual pattern is to use ``Layer`` as a base class for a custom layer.\nThis can then override the lifecycle methods as appropriate, as well as set a default list of bases.::\n\n    >>> class BaseLayer(Layer):\n    ...\n    ...     def setUp(self):\n    ...         print(\"Setting up base layer\")\n    ...\n    ...     def tearDown(self):\n    ...         print(\"Tearing down base layer\")\n\n    >>> BASE_LAYER = BaseLayer()\n\nThe layer name and module are taken from the class.::\n\n    >>> BASE_LAYER.__bases__\n    ()\n    >>> BASE_LAYER.__name__\n    'BaseLayer'\n    >>> BASE_LAYER.__module__\n    'builtins'\n\nWe can now create a new layer that has this one as a base.\nWe can do this in the instance constructor, as shown above, but the most common pattern is to set the default bases in the class body, using the variable ``defaultBases``.\n\nWe'll also set the default name explicitly here by passing a name to the the super-constructor.\nThis is mostly cosmetic, but may be desirable if the class name would be misleading in the test runner output.::\n\n    >>> class ChildLayer(Layer):\n    ...     defaultBases = (BASE_LAYER,)\n    ...\n    ...     def __init__(self, bases=None, name='Child layer', module=None):\n    ...         super(ChildLayer, self).__init__(bases, name, module)\n    ...\n    ...     def setUp(self):\n    ...         print(\"Setting up child layer\")\n    ...\n    ...     def tearDown(self):\n    ...         print(\"Tearing down child layer\")\n\n    >>> CHILD_LAYER = ChildLayer()\n\nNotice how the bases have now been set using the value in ``defaultBases``.::\n\n    >>> CHILD_LAYER.__bases__\n    (<Layer 'builtins.BaseLayer'>,)\n    >>> CHILD_LAYER.__name__\n    'Child layer'\n    >>> CHILD_LAYER.__module__\n    'builtins'\n\nOverriding the default list of bases\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWe can override the list of bases on a per-instance basis.\nThis may be dangerous, i.e.\nthe layer is likely to expect that its bases are set up.\nSometimes, it may be useful to inject a new base, however, especially when re-using layers from other packages.\n\nThe new list of bases is passed to the constructor.\nWhen creating a second instance of a layer (most layers are global singletons created only once), it's useful to give the new instance a unique name, too.::\n\n    >>> NEW_CHILD_LAYER = ChildLayer(bases=(SIMPLE_LAYER, BASE_LAYER,), name='New child')\n\n    >>> NEW_CHILD_LAYER.__bases__\n    (<Layer 'plone.testing.tests.Simple layer'>, <Layer 'builtins.BaseLayer'>)\n    >>> NEW_CHILD_LAYER.__name__\n    'New child'\n    >>> NEW_CHILD_LAYER.__module__\n    'builtins'\n\nInconsistent bases\n~~~~~~~~~~~~~~~~~~\n\nLayer bases are maintained in an order that is semantically equivalent to the \"method resolution order\" Python maintains for base classes.\nWe can get this from the ``baseResolutionOrder`` attribute:::\n\n    >>> CHILD_LAYER.baseResolutionOrder\n    (<Layer 'builtins.Child layer'>, <Layer 'builtins.BaseLayer'>)\n\n    >>> NEW_CHILD_LAYER.baseResolutionOrder\n    (<Layer 'builtins.New child'>, <Layer 'plone.testing.tests.Simple layer'>,\n     <Layer 'plone.testing.layer.Null layer'>,\n     <Layer 'builtins.BaseLayer'>)\n\nAs with Python classes, it is possible to construct an invalid set of bases.\nIn this case, layer instantiation will fail.::\n\n    >>> INCONSISTENT_BASE1 = Layer(name=\"Inconsistent 1\")\n    >>> INCONSISTENT_BASE2 = Layer((INCONSISTENT_BASE1,), name=\"Inconsistent 1\")\n    >>> INCONSISTENT_BASE3 = Layer((INCONSISTENT_BASE1, INCONSISTENT_BASE2,), name=\"Inconsistent 1\")\n    Traceback (most recent call last):\n    ...\n    TypeError: Inconsistent layer hierarchy!\n\nUsing the resource manager\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLayers are also resource managers.\nResources can be set, retrieved and deleted using dictionary syntax.\nResources in base layers are available in child layers.\nWhen an item is set on a child layer, it shadows any items with the same key in any base layer (until it is deleted), but the original item still exists.\n\nLet's create a somewhat complex hierarchy of layers that all set resources under a key ``'foo'`` in their ``setUp()`` methods.::\n\n    >>> class Layer1(Layer):\n    ...     def setUp(self):\n    ...         self['foo'] = 1\n    ...     def tearDown(self):\n    ...         del self['foo']\n    >>> LAYER1 = Layer1()\n\n    >>> class Layer2(Layer):\n    ...     defaultBases = (LAYER1,)\n    ...     def setUp(self):\n    ...         self['foo'] = 2\n    ...     def tearDown(self):\n    ...         del self['foo']\n    >>> LAYER2 = Layer2()\n\n    >>> class Layer3(Layer):\n    ...     def setUp(self):\n    ...         self['foo'] = 3\n    ...     def tearDown(self):\n    ...         del self['foo']\n    >>> LAYER3 = Layer3()\n\n    >>> class Layer4(Layer):\n    ...     defaultBases = (LAYER2, LAYER3,)\n    ...     def setUp(self):\n    ...         self['foo'] = 4\n    ...     def tearDown(self):\n    ...         del self['foo']\n    >>> LAYER4 = Layer4()\n\n    **Important:** Resources that are created in ``setUp()`` must be deleted in ``tearDown()``.\n    Similarly, resources created in ``testSetUp()`` must be deleted in ``testTearDown()``.\n    This ensures resources are properly stacked and do not leak between layers.\n\nIf a test was using ``LAYER4``, the test runner would call each setup step in turn, starting with the \"deepest\" layer.\nWe'll simulate that here, so that each of the resources is created.::\n\n    >>> LAYER1.setUp()\n    >>> LAYER2.setUp()\n    >>> LAYER3.setUp()\n    >>> LAYER4.setUp()\n\nThe layers are ordered in a known \"resource resolution order\", which is used to determine in which order the layers shadow one another.\nThis is based on the same algorithm as Python's method resolution order.::\n\n    >>> LAYER4.baseResolutionOrder\n    (<Layer 'builtins.Layer4'>,\n     <Layer 'builtins.Layer2'>,\n     <Layer 'builtins.Layer1'>,\n     <Layer 'builtins.Layer3'>)\n\nWhen fetching and item from a layer, it will be obtained according to the resource resolution order.::\n\n    >>> LAYER4['foo']\n    4\n\nThis is not terribly interesting, since ``LAYER4`` has the resource ``'foo'`` set directly.\nLet's tear down the layer (which deletes the resource) and see what happens.::\n\n    >>> LAYER4.tearDown()\n    >>> LAYER4['foo']\n    2\n\nWe can continue up the chain:::\n\n    >>> LAYER2.tearDown()\n    >>> LAYER4['foo']\n    1\n\n    >>> LAYER1.tearDown()\n    >>> LAYER4['foo']\n    3\n\nOnce we've deleted the last key, we'll get a ``KeyError``:::\n\n    >>> LAYER3.tearDown()\n    >>> LAYER4['foo']\n    Traceback (most recent call last):\n    ...\n    KeyError: 'foo'\n\nTo guard against this, we can use the ``get()`` method.::\n\n    >>> LAYER4.get('foo', -1)\n    -1\n\nWe can also test with 'in':::\n\n    >>> 'foo' in LAYER4\n    False\n\nTo illustrate that this indeed works, let's set the resource back on one of the bases.::\n\n    >>> LAYER3['foo'] = 10\n    >>> LAYER4.get('foo', -1)\n    10\n\nLet's now consider a special case: a base layer sets up a resource in layer setup, and uses it in test setup.\nA child layer then shadows this resource in its own layer setup method.\nIn this case, we want the base layer's ``testSetUp()`` to use the shadowed version that the child provided.\n\n(This is similar to how instance variables work: a base class may set an attribute on ``self`` and use it in a method.\nIf a subclass then sets the same attribute to a different value and the base class method is called on an instance of the subclass, the base class attribute is used).\n\n    *Hint:* If you definitely need to access the \"original\" resource in your ``testSetUp()``/``testTearDown()`` methods, you can store a reference to the resource as a layer instance variable::\n\n        self.someResource = self['someResource'] = SomeResource()\n\n    ``self.someResource`` will now be the exact resource created here, whereas ``self['someResource']`` will retain the layer shadowing semantics.\n    In most cases, you probably *don't* want to do this, allowing child layers to supply overridden versions of resources as appropriate.\n\nFirst, we'll create some base layers.\nWe want to demonstrate having two \"branches\" of bases that both happen to define the same resource.::\n\n    >>> class ResourceBaseLayer1(Layer):\n    ...     def setUp(self):\n    ...         self['resource'] = \"Base 1\"\n    ...     def testSetUp(self):\n    ...         print(self['resource'])\n    ...     def tearDown(self):\n    ...         del self['resource']\n\n    >>> RESOURCE_BASE_LAYER1 = ResourceBaseLayer1()\n\n    >>> class ResourceBaseLayer2(Layer):\n    ...     defaultBases = (RESOURCE_BASE_LAYER1,)\n    ...     def testSetUp(self):\n    ...         print(self['resource'])\n\n    >>> RESOURCE_BASE_LAYER2 = ResourceBaseLayer2()\n\n    >>> class ResourceBaseLayer3(Layer):\n    ...     def setUp(self):\n    ...         self['resource'] = \"Base 3\"\n    ...     def testSetUp(self):\n    ...         print(self['resource'])\n    ...     def tearDown(self):\n    ...         del self['resource']\n\n    >>> RESOURCE_BASE_LAYER3 = ResourceBaseLayer3()\n\nWe'll then create the child layer that overrides this resource.::\n\n    >>> class ResourceChildLayer(Layer):\n    ...     defaultBases = (RESOURCE_BASE_LAYER2, RESOURCE_BASE_LAYER3)\n    ...     def setUp(self):\n    ...         self['resource'] = \"Child\"\n    ...     def testSetUp(self):\n    ...         print(self['resource'])\n    ...     def tearDown(self):\n    ...         del self['resource']\n\n    >>> RESOURCE_CHILD_LAYER = ResourceChildLayer()\n\nWe'll first set up the base layers on their own and simulate two tests.\n\nA test with RESOURCE_BASE_LAYER1 only would look like this:::\n\n    >>> RESOURCE_BASE_LAYER1.setUp()\n\n    >>> RESOURCE_BASE_LAYER1.testSetUp()\n    Base 1\n    >>> RESOURCE_BASE_LAYER1.testTearDown()\n\n    >>> RESOURCE_BASE_LAYER1.tearDown()\n\nA test with RESOURCE_BASE_LAYER2 would look like this:::\n\n    >>> RESOURCE_BASE_LAYER1.setUp()\n    >>> RESOURCE_BASE_LAYER2.setUp()\n\n    >>> RESOURCE_BASE_LAYER1.testSetUp()\n    Base 1\n    >>> RESOURCE_BASE_LAYER2.testSetUp()\n    Base 1\n    >>> RESOURCE_BASE_LAYER2.testTearDown()\n    >>> RESOURCE_BASE_LAYER1.testTearDown()\n\n    >>> RESOURCE_BASE_LAYER2.tearDown()\n    >>> RESOURCE_BASE_LAYER1.tearDown()\n\nA test with RESOURCE_BASE_LAYER3 only would look like this:::\n\n    >>> RESOURCE_BASE_LAYER3.setUp()\n\n    >>> RESOURCE_BASE_LAYER3.testSetUp()\n    Base 3\n    >>> RESOURCE_BASE_LAYER3.testTearDown()\n\n    >>> RESOURCE_BASE_LAYER3.tearDown()\n\nNow let's set up the child layer and simulate another test.\nWe should now be using the shadowed resource.::\n\n    >>> RESOURCE_BASE_LAYER1.setUp()\n    >>> RESOURCE_BASE_LAYER2.setUp()\n    >>> RESOURCE_BASE_LAYER3.setUp()\n    >>> RESOURCE_CHILD_LAYER.setUp()\n\n    >>> RESOURCE_BASE_LAYER1.testSetUp()\n    Child\n    >>> RESOURCE_BASE_LAYER2.testSetUp()\n    Child\n    >>> RESOURCE_BASE_LAYER3.testSetUp()\n    Child\n    >>> RESOURCE_CHILD_LAYER.testSetUp()\n    Child\n\n    >>> RESOURCE_CHILD_LAYER.testTearDown()\n    >>> RESOURCE_BASE_LAYER3.testTearDown()\n    >>> RESOURCE_BASE_LAYER2.testTearDown()\n    >>> RESOURCE_BASE_LAYER1.testTearDown()\n\nFinally, we'll tear down the child layer again and simulate another test.\nwe should have the original resources back.\nNote that the first and third layers no longer share a resource, since they don't have a common ancestor.::\n\n    >>> RESOURCE_CHILD_LAYER.tearDown()\n\n    >>> RESOURCE_BASE_LAYER1.testSetUp()\n    Base 1\n    >>> RESOURCE_BASE_LAYER2.testSetUp()\n    Base 1\n    >>> RESOURCE_BASE_LAYER2.testTearDown()\n    >>> RESOURCE_BASE_LAYER1.testTearDown()\n\n    >>> RESOURCE_BASE_LAYER3.testSetUp()\n    Base 3\n    >>> RESOURCE_BASE_LAYER3.testTearDown()\n\nFinally, we'll tear down the remaining layers..::\n\n    >>> RESOURCE_BASE_LAYER3.tearDown()\n    >>> RESOURCE_BASE_LAYER2.tearDown()\n    >>> RESOURCE_BASE_LAYER1.tearDown()\n\nAsymmetric deletion\n+++++++++++++++++++\n\nIt is an error to create or shadow a resource in a set-up lifecycle method and not delete it again in the tear-down.\nIt is also an error to delete a resource that was not explicitly created.\nThese two layers break those roles:::\n\n    >>> class BadLayer1(Layer):\n    ...     def setUp(self):\n    ...         pass\n    ...     def tearDown(self):\n    ...         del self['foo']\n    >>> BAD_LAYER1 = BadLayer1()\n\n    >>> class BadLayer2(Layer):\n    ...     defaultBases = (BAD_LAYER1,)\n    ...     def setUp(self):\n    ...         self['foo'] = 1\n    ...         self['bar'] = 2\n    >>> BAD_LAYER2 = BadLayer2()\n\nLet's simulate a test that uses ``BAD_LAYER2``:::\n\n    >>> BAD_LAYER1.setUp()\n    >>> BAD_LAYER2.setUp()\n\n    >>> BAD_LAYER1.testSetUp()\n    >>> BAD_LAYER2.testSetUp()\n\n    >>> BAD_LAYER2.testTearDown()\n    >>> BAD_LAYER1.testTearDown()\n\n    >>> BAD_LAYER2.tearDown()\n    >>> BAD_LAYER1.tearDown()\n    Traceback (most recent call last):\n    ...\n    KeyError: 'foo'\n\nHere, we've got an error in the base layer.\nThis is because the resource is actually associated with the layer that first created it, in this case ``BASE_LAYER2``.\nThis one remains intact and orphaned:::\n\n    >>> 'foo' in BAD_LAYER2._resources\n    True\n    >>> 'bar' in BAD_LAYER2._resources\n    True\n\nDoctest layer helper\n~~~~~~~~~~~~~~~~~~~~\n\nThe ``doctest`` module is not aware of ``zope.testing``'s layers concept.\nTherefore, the syntax for creating a doctest with a layer and adding it to a test suite is somewhat contrived: the test suite has to be created first, and then the layer attribute set on it:::\n\n    >>> class DoctestLayer(Layer):\n    ...     pass\n    >>> DOCTEST_LAYER = DoctestLayer()\n\n    >>> import unittest\n    >>> import doctest\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     layerDoctest = doctest.DocFileSuite('layer.rst', package='plone.testing')\n    ...     layerDoctest.layer = DOCTEST_LAYER\n    ...     suite.addTest(layerDoctest)\n    ...     return suite\n\n    >>> suite = test_suite()\n    >>> tests = list(suite)\n    >>> len(tests)\n    1\n    >>> tests[0].layer is DOCTEST_LAYER\n    True\n\n\nTo make this a little easier - especially when setting up multiple tests - a helper function called ``layered`` is provided:::\n\n    >>> from plone.testing import layered\n\n    >>> def test_suite():\n    ...     suite = unittest.TestSuite()\n    ...     suite.addTests([\n    ...         layered(doctest.DocFileSuite('layer.rst', package='plone.testing'), layer=DOCTEST_LAYER),\n    ...         # repeat with more suites if necessary\n    ...     ])\n    ...     return suite\n\nThis does the same as the sample above.::\n\n    >>> suite = test_suite()\n    >>> tests = list(suite)\n    >>> len(tests)\n    1\n    >>> tests[0].layer is DOCTEST_LAYER\n    True\n\nIn addition, a 'layer' glob is added to each test in the suite.\nThis allows the test to access layer resources.::\n\n    >>> len(list(tests[0]))\n    1\n    >>> list(tests[0])[0]._dt_test.globs['layer'] is DOCTEST_LAYER\n    True\n\n\nZope Component Architecture layers\n----------------------------------\n\nThe ZCA layers are found in the module ``plone.testing.zca``:::\n\n    >>> from plone.testing import zca\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nUnit testing\n~~~~~~~~~~~~\n\nThe ``UNIT_TESTING`` layer is used to set up a clean component registry between each test.\nIt uses ``zope.testing.cleanup`` to clean up all global state.\n\nIt has no bases:::\n\n    >>> \"%s.%s\" % (zca.UNIT_TESTING.__module__, zca.UNIT_TESTING.__name__,)\n    'plone.testing.zca.UnitTesting'\n\n    >>> zca.UNIT_TESTING.__bases__\n    ()\n\nThe component registry is cleaned up between each test.::\n\n    >>> from zope.interface import Interface\n    >>> from zope.component import provideUtility\n\n    >>> class DummyUtility(object):\n    ...     def __init__(self, name):\n    ...         self.name = name\n    ...     def __repr__(self):\n    ...         return \"<%s>\" % self.name\n\n    >>> provideUtility(DummyUtility(\"Dummy\"), provides=Interface, name=\"test-dummy\")\n\n    >>> from zope.component import queryUtility\n    >>> queryUtility(Interface, name=\"test-dummy\")\n    <Dummy>\n\nLayer setup does nothing.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zca.UNIT_TESTING, setupLayers)\n    Set up plone.testing.zca.UnitTesting in ... seconds.\n\nLet's now simulate a test.\nBefore any test setup has happened, our previously registered utility is still there.::\n\n    >>> queryUtility(Interface, name=\"test-dummy\")\n    <Dummy>\n\nOn test setup, it disappears.::\n\n    >>> zca.UNIT_TESTING.testSetUp()\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n\nThe test would now execute. It may register some components.::\n\n    >>> provideUtility(DummyUtility(\"Dummy2\"), provides=Interface, name=\"test-dummy\")\n    >>> queryUtility(Interface, name=\"test-dummy\")\n    <Dummy2>\n\nOn test tear-down, this disappears.::\n\n    >>> zca.UNIT_TESTING.testTearDown()\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n\nLayer tear-down does nothing.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zca.UnitTesting in ... seconds.\n\nEvent testing\n~~~~~~~~~~~~~\n\nThe ``EVENT_TESTING`` layer extends the ``UNIT_TESTING`` layer to add the necessary registrations for ``zope.component.eventtesting`` to work.::\n\n    >>> \"%s.%s\" % (zca.EVENT_TESTING.__module__, zca.EVENT_TESTING.__name__,)\n    'plone.testing.zca.EventTesting'\n\n    >>> zca.EVENT_TESTING.__bases__\n    (<Layer 'plone.testing.zca.UnitTesting'>,)\n\nBefore the test, the component registry is empty and ``getEvents()`` returns nothing, even if an event is fired.::\n\n    >>> from zope.component.eventtesting import getEvents\n\n    >>> class DummyEvent(object):\n    ...     def __repr__(self):\n    ...         return \"<Dummy event>\"\n\n    >>> from zope.event import notify\n    >>> notify(DummyEvent())\n\n    >>> getEvents()\n    []\n\nLayer setup does nothing.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zca.EVENT_TESTING, setupLayers)\n    Set up plone.testing.zca.UnitTesting in ... seconds.\n    Set up plone.testing.zca.EventTesting in ... seconds.\n\nLet's now simulate a test. On test setup, the event testing list is emptied.::\n\n    >>> zca.UNIT_TESTING.testSetUp()\n    >>> zca.EVENT_TESTING.testSetUp()\n\n    >>> getEvents()\n    []\n\nThe test would now execute.\nIt may fire some events, which would show up in the event testing list.::\n\n    >>> notify(DummyEvent())\n    >>> getEvents()\n    [<Dummy event>]\n\nOn test tear-down, the list is emptied again:::\n\n    >>> zca.EVENT_TESTING.testTearDown()\n    >>> zca.UNIT_TESTING.testTearDown()\n\n    >>> getEvents()\n    []\n\nLayer tear-down does nothing.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zca.EventTesting in ... seconds.\n    Tear down plone.testing.zca.UnitTesting in ... seconds.\n\nLayer cleanup\n~~~~~~~~~~~~~\n\nThe ``LAYER_CLEANUP`` layer is used to set up a clean component registry at the set-up and tear-down of a layer.\nIt uses ``zope.testing.cleanup`` to clean up all global state.\n\nIt has no bases:::\n\n    >>> \"%s.%s\" % (zca.LAYER_CLEANUP.__module__, zca.LAYER_CLEANUP.__name__,)\n    'plone.testing.zca.LayerCleanup'\n\n    >>> zca.LAYER_CLEANUP.__bases__\n    ()\n\nThe component registry is cleaned up on layer set-up and tear-down (but not between tests).::\n\n    >>> from zope.interface import Interface\n    >>> from zope.component import provideUtility\n\n    >>> class DummyUtility(object):\n    ...     def __init__(self, name):\n    ...         self.name = name\n    ...     def __repr__(self):\n    ...         return \"<%s>\" % self.name\n\n    >>> provideUtility(DummyUtility(\"Dummy\"), provides=Interface, name=\"test-dummy\")\n\n    >>> from zope.component import queryUtility\n    >>> queryUtility(Interface, name=\"test-dummy\")\n    <Dummy>\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zca.LAYER_CLEANUP, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n\nA sub-layer may register additional components:::\n\n    >>> provideUtility(DummyUtility(\"Dummy2\"), provides=Interface, name=\"test-dummy2\")\n\nLet's now simulate a test. Test setup and tear-down does nothing.::\n\n    >>> zca.LAYER_CLEANUP.testSetUp()\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n    >>> queryUtility(Interface, name=\"test-dummy2\")\n    <Dummy2>\n\n    >>> zca.LAYER_CLEANUP.testTearDown()\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n    >>> queryUtility(Interface, name=\"test-dummy2\")\n    <Dummy2>\n\nOn tear-down, the registry is cleaned again.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\n    >>> queryUtility(Interface, name=\"test-dummy\") is None\n    True\n    >>> queryUtility(Interface, name=\"test-dummy2\") is None\n    True\n\nBasic ZCML directives\n~~~~~~~~~~~~~~~~~~~~~\n\nThe ``ZCML_DIRECTIVES`` layer creates a ZCML configuration context with the basic ``zope.component`` directives available.\nIt extends the ``LAYER_CLEANUP`` layer.::\n\n    >>> \"%s.%s\" % (zca.ZCML_DIRECTIVES.__module__, zca.ZCML_DIRECTIVES.__name__,)\n    'plone.testing.zca.ZCMLDirectives'\n\n    >>> zca.ZCML_DIRECTIVES.__bases__\n    (<Layer 'plone.testing.zca.LayerCleanup'>,)\n\nBefore the test, we cannot use e.g. a ``<utility />`` directive without loading the necessary ``meta.zcml`` files.::\n\n    >>> from zope.configuration import xmlconfig\n    >>> from zope.configuration.exceptions import ConfigurationError\n    >>> try:\n    ...     xmlconfig.string(\"\"\"\\\n    ...     <configure package=\"plone.testing\" xmlns=\"http://namespaces.zope.org/zope\">\n    ...         <utility factory=\".tests.DummyUtility\" provides=\"zope.interface.Interface\" name=\"test-dummy\" />\n    ...     </configure>\"\"\")\n    ... except ConfigurationError as e:\n    ...     True\n    True\n\nLayer setup creates a configuration context we can use to load further configuration.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zca.ZCML_DIRECTIVES, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zca.ZCMLDirectives in ... seconds.\n\nLet's now simulate a test that uses this configuration context to load the same ZCML string.::\n\n    >>> zca.ZCML_DIRECTIVES.testSetUp()\n\n    >>> context = zca.ZCML_DIRECTIVES['configurationContext'] # would normally be self.layer['configurationContext']\n    >>> xmlconfig.string(\"\"\"\\\n    ... <configure package=\"plone.testing\" xmlns=\"http://namespaces.zope.org/zope\">\n    ...     <utility factory=\".tests.DummyUtility\" provides=\"zope.interface.Interface\" name=\"test-dummy\" />\n    ... </configure>\"\"\", context=context) is context\n    True\n\nThe utility is now registered:::\n\n    >>> queryUtility(Interface, name=\"test-dummy\")\n    <Dummy utility>\n\n    >>> zca.UNIT_TESTING.testTearDown()\n\nNote that normally, we'd combine this with the ``UNIT_TESTING`` layer to tear down the component architecture as well.\n\nLayer tear-down deletes the configuration context.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zca.ZCMLDirectives in ... seconds.\n\n    >>> zca.ZCML_DIRECTIVES.get('configurationContext', None) is None\n    True\n\nConfiguration registry sandboxing\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor simple unit tests, the full cleanup performed between each test using the ``UNIT_TESTING`` layer is undoubtedly the safest and most convenient way to ensure proper isolation of tests using the global component architecture.\nHowever, if you are writing a complex layer that sets up a lot of components, you may wish to keep some components registered at the layer level, whilst still allowing tests and sub-layers to register their own components in isolation.\n\nThis is a tricky problem, because the default ZCML directives and APIs (``provideAdapter()``, ``provideUtility()`` and so on) explicitly work on a single global adapter registry object.\nTo get around this, you can use two helper methods in the ``zca`` module to push a new global component registry before registering components, and pop the registry after.\nRegistries are stacked, so the components registered in a \"lower\" registry are automatically available in a \"higher\" registry.\n\nLet's illustrate this with a layer that stacks two new global registries.\nThe first registry is specific to the layer, and is used to house the components registered at the layer level.\nThe second registry is set up and torn down for each test, allowing tests to register their own components freely.\n\nFirst, we'll create a simple dummy utility to illustrate registrations.::\n\n    >>> from zope.interface import Interface, implementer\n\n    >>> class IDummyUtility(Interface):\n    ...     pass\n    >>> @implementer(IDummyUtility)\n    ... class DummyUtility(object):\n    ...     def __init__(self, name):\n    ...         self.name = name\n    ...     def __repr__(self):\n    ...         return \"<DummyUtility %s>\" % self.name\n\nThe two key methods are:\n\n* ``zca.pushGlobalRegistry()``, which creates a new global registry.\n* ``zca.popGlobalRegistry()``, which restores the previous global registry.\n\n  **Warning:** You *must* balance your calls to these methods.\n  If you call ``pushGlobalRegistry()`` in ``setUp()``, call ``popGlobalRegistry()`` in ``tearDown()``.\n  Ditto for ``testSetUp()`` and ``testTearDown()``.\n\nLet's now create our layer.::\n\n    >>> from zope.component import provideUtility\n    >>> from plone.testing import Layer\n    >>> from plone.testing import zca\n\n    >>> class ComponentSandbox(Layer):\n    ...     def setUp(self):\n    ...         zca.pushGlobalRegistry()\n    ...         provideUtility(DummyUtility(\"layer\"), name=\"layer\")\n    ...     def tearDown(self):\n    ...         zca.popGlobalRegistry()\n    ...     def testSetUp(self):\n    ...         zca.pushGlobalRegistry()\n    ...     def testTearDown(self):\n    ...         zca.popGlobalRegistry()\n    >>> COMPONENT_SANDBOX = ComponentSandbox()\n\nLet's now simulate a test using this layer.\n\nTo begin with, we have the default registry.::\n\n    >>> from zope.component import getGlobalSiteManager, getSiteManager\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n\n    >>> defaultGlobalSiteManager = getGlobalSiteManager()\n\n    >>> from zope.component import queryUtility\n    >>> queryUtility(IDummyUtility, name=\"layer\") is None\n    True\n\nWe'll now simulate layer setup. This will push a new registry onto the stack:::\n\n    >>> COMPONENT_SANDBOX.setUp()\n\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n    >>> getGlobalSiteManager() is defaultGlobalSiteManager\n    False\n    >>> layerGlobalSiteManager = getGlobalSiteManager()\n\n    >>> queryUtility(IDummyUtility, name=\"layer\")\n    <DummyUtility layer>\n\nWe'll then simulate a test that registers a global component:::\n\n    >>> COMPONENT_SANDBOX.testSetUp()\n\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n    >>> getGlobalSiteManager() is defaultGlobalSiteManager\n    False\n    >>> getGlobalSiteManager() is layerGlobalSiteManager\n    False\n\nOur previously registered component is still here.::\n\n    >>> queryUtility(IDummyUtility, name=\"layer\")\n    <DummyUtility layer>\n\nWe can also register a new one.::\n\n    >>> provideUtility(DummyUtility(\"test\"), name=\"test\")\n    >>> queryUtility(IDummyUtility, name=\"layer\")\n    <DummyUtility layer>\n    >>> queryUtility(IDummyUtility, name=\"test\")\n    <DummyUtility test>\n\nOn test tear-down, only the second utility disappears:::\n\n    >>> COMPONENT_SANDBOX.testTearDown()\n\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n    >>> getGlobalSiteManager() is defaultGlobalSiteManager\n    False\n    >>> getGlobalSiteManager() is layerGlobalSiteManager\n    True\n\n    >>> queryUtility(IDummyUtility, name=\"layer\")\n    <DummyUtility layer>\n    >>> queryUtility(IDummyUtility, name=\"test\") is None\n    True\n\nIf we tear down the layer too, we're back where we started:::\n\n    >>> COMPONENT_SANDBOX.tearDown()\n\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n    >>> getGlobalSiteManager() is defaultGlobalSiteManager\n    True\n\n    >>> queryUtility(IDummyUtility, name=\"layer\") is None\n    True\n    >>> queryUtility(IDummyUtility, name=\"test\") is None\n    True\n\nZCML files helper class\n~~~~~~~~~~~~~~~~~~~~~~~\n\nOne of the frequent use cases is a layer that loads a ZCML file and sandbox the resulting registry.\n\nThe ``ZCMLSandbox`` can be instantiated with a `filename`` and ``package`` arguments.::\n\n    >>> import plone.testing\n    >>> ZCML_SANDBOX = zca.ZCMLSandbox(filename=\"testing_zca.zcml\",\n    ...     package=plone.testing)\n\nBefore layer setup, the utility is not registered.::\n\n    >>> queryUtility(Interface, name=\"layer\") is None\n    True\n\nWe'll now simulate layer setup.\nThis pushes a new registry onto the stack:::\n\n    >>> ZCML_SANDBOX.setUp()\n\n    >>> getSiteManager() is getGlobalSiteManager()\n    True\n    >>> getGlobalSiteManager() is defaultGlobalSiteManager\n    False\n    >>> queryUtility(Interface, name=\"layer\")\n    <Dummy utility>\n\nThe ``ZCMLSandbox`` class can also be used as ancestor for your own classes when you need to load more than a single ZCML file.\n\nYour class then needs to override the ``setUpZCMLFiles()`` method.\nIt is in charge of calling ``loadZCMLFile()``, once for each ZCML file that the class needs to load.::\n\n    >>> class OtherZCML(zca.ZCMLSandbox):\n    ...     def setUpZCMLFiles(self):\n    ...         self.loadZCMLFile(\"testing_zca.zcml\", package=plone.testing)\n    ...         self.loadZCMLFile(\"testing_zca_more_specific.zcml\",\n    ...             package=plone.testing)\n    >>> OTHER_ZCML_SANDBOX = OtherZCML()\n\nBefore layer setup, a second utility is not registered.::\n\n    >>> queryUtility(Interface, name=\"more_specific_layer\") is None\n    True\n\nWe'll now simulate the setup of the more specific layer.::\n\n    >>> OTHER_ZCML_SANDBOX.setUp()\n\nAfter setUp, the second utility is registered:::\n\n    >>> queryUtility(Interface, name=\"more_specific_layer\")\n    <Dummy utility>\n\nAfter layer teardown, the second utility is not registered anymore.::\n\n    >>> OTHER_ZCML_SANDBOX.tearDown()\n    >>> queryUtility(Interface, name=\"more_specific_layer\") is None\n    True\n\nAfter teardown of the first layer, the first utility is not registered anymore.::\n\n    >>> ZCML_SANDBOX.tearDown()\n    >>> queryUtility(Interface, name=\"layer\") is None\n    True\n\n\nSecurity\n--------\n\nThe Zope Security layers are found in the module ``plone.testing.security``:::\n\n    >>> from plone.testing import security\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nLayers\n~~~~~~\n\nThe ``security.CHECKERS`` layer makes sure that ``zope.security`` checkers are correctly set up and torn down.::\n\n    >>> \"%s.%s\" % (security.CHECKERS.__module__, security.CHECKERS.__name__,)\n    'plone.testing.security.Checkers'\n\n    >>> security.CHECKERS.__bases__\n    ()\n\nBefore the test, our custom checker is not in the registry.::\n\n    >>> class DummyObject(object):\n    ...     pass\n\n    >>> from zope.security.interfaces import IChecker\n    >>> from zope.interface import implementer\n    >>> @implementer(IChecker)\n    ... class FauxChecker(object):\n    ...     # we should really implement the interface here, but oh well\n    ...     pass\n\n    >>> from zope.security.checker import getCheckerForInstancesOf\n    >>> getCheckerForInstancesOf(DummyObject) is None\n    True\n\nLayer setup stacks the current checkers.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, security.CHECKERS, setupLayers)\n    Set up plone.testing.security.Checkers in ... seconds.\n\nWe can now set up a checker.\nIn real life, this may happen during ZCML configuration, but here will just call the API directlyMost likely, we'd do this in a child layer:::\n\n    >>> from zope.security.checker import defineChecker\n    >>> fauxChecker = FauxChecker()\n    >>> defineChecker(DummyObject, fauxChecker)\n\n    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker\n    True\n\nLet's now simulate a test that may use the checker.::\n\n    >>> security.CHECKERS.testSetUp()\n    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker\n    True\n    >>> security.CHECKERS.testTearDown()\n\nWe still have the checker after test tear-down:::\n\n    >>> getCheckerForInstancesOf(DummyObject) is fauxChecker\n    True\n\nHowever, when we tear down the layer, the checker is gone:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.security.Checkers in ... seconds.\n\n    >>> getCheckerForInstancesOf(DummyObject) is None\n    True\n\n\nZope Publisher layers\n---------------------\n\nThe Zope Publisher layers are found in the module ``plone.testing.publisher``::\n\n    >>> from plone.testing import publisher\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nZCML directives\n~~~~~~~~~~~~~~~\n\nThe ``publisher.PUBLISHER_DIRECTIVES`` layer extends the ``zca.ZCML_DIRECTIVES`` layer to extend its ZCML configuration context with the ``zope.app.publisher`` and ``zope.security`` directives available.\nIt also extends ``security.CHECKERS``.::\n\n    >>> from plone.testing import zca, security\n\n    >>> \"%s.%s\" % (publisher.PUBLISHER_DIRECTIVES.__module__, publisher.PUBLISHER_DIRECTIVES.__name__,)\n    'plone.testing.publisher.PublisherDirectives'\n\n    >>> publisher.PUBLISHER_DIRECTIVES.__bases__\n    (<Layer 'plone.testing.zca.ZCMLDirectives'>, <Layer 'plone.testing.security.Checkers'>)\n\nBefore the test, we cannot use e.g.\nthe ``<permission />`` or ``<browser:view />`` directives without loading the necessary ``meta.zcml`` files.::\n\n    >>> from zope.configuration import xmlconfig\n    >>> from zope.configuration.exceptions import ConfigurationError\n    >>> try:\n    ...     xmlconfig.string(\"\"\"\\\n    ...     <configure package=\"plone.testing\"\n    ...         xmlns=\"http://namespaces.zope.org/zope\"\n    ...         xmlns:browser=\"http://namespaces.zope.org/browser\"\n    ...         i18n_domain=\"plone.testing.tests\">\n    ...         <permission id=\"plone.testing.Test\" title=\"plone.testing: Test\" />\n    ...         <browser:view\n    ...             for=\"*\"\n    ...             name=\"plone.testing-test\"\n    ...             class=\"plone.testing.tests.DummyView\"\n    ...             permission=\"zope.Public\"\n    ...             />\n    ...     </configure>\"\"\")\n    ... except ConfigurationError as e:\n    ...     True\n    True\n\nLayer setup creates a configuration context we can use to load further configuration.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, publisher.PUBLISHER_DIRECTIVES, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zca.ZCMLDirectives in ... seconds.\n    Set up plone.testing.security.Checkers in ... seconds.\n    Set up plone.testing.publisher.PublisherDirectives in ... seconds.\n\n\nLet's now simulate a test that uses this configuration context to load the same ZCML string.::\n\n    >>> zca.ZCML_DIRECTIVES.testSetUp()\n    >>> security.CHECKERS.testSetUp()\n    >>> publisher.PUBLISHER_DIRECTIVES.testSetUp()\n\n    >>> context = zca.ZCML_DIRECTIVES['configurationContext'] # would normally be self.layer['configurationContext']\n    >>> xmlconfig.string(\"\"\"\\\n    ... <configure package=\"plone.testing\"\n    ...     xmlns=\"http://namespaces.zope.org/zope\"\n    ...     xmlns:browser=\"http://namespaces.zope.org/browser\"\n    ...     i18n_domain=\"plone.testing.tests\">\n    ...     <permission id=\"plone.testing.Test\" title=\"plone.testing: Test\" />\n    ...     <browser:view\n    ...         for=\"*\"\n    ...         name=\"plone.testing-test\"\n    ...         class=\"plone.testing.tests.DummyView\"\n    ...         permission=\"zope.Public\"\n    ...         />\n    ... </configure>\"\"\", context=context) is context\n    True\n\nThe permission and view are now registered:::\n\n    >>> from zope.component import queryUtility\n    >>> from zope.security.interfaces import IPermission\n\n    >>> queryUtility(IPermission, name=u\"plone.testing.Test\")\n    <zope.security.permission.Permission object at ...>\n\n    >>> from zope.interface import Interface\n    >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer\n    >>> from zope.component import getSiteManager\n    >>> siteManager = getSiteManager()\n\n    >>> [x.factory for x in siteManager.registeredAdapters()\n    ...  if x.provided==Interface and x.required==(Interface, IDefaultBrowserLayer)\n    ...   and x.name==u\"plone.testing-test\"]\n    [<class '....plone.testing-test'>]\n\nWe can then simulate test tear-down:::\n\n    >>> publisher.PUBLISHER_DIRECTIVES.testTearDown()\n    >>> security.CHECKERS.testTearDown()\n    >>> zca.ZCML_DIRECTIVES.testTearDown()\n\nNote that you'd normally combine this layer with the ``zca.UNIT_TESTING`` or a similar layer to automatically tear down the component architecture between each test.\nHere, we need to do it manually.::\n\n    >>> from zope.component.testing import tearDown\n    >>> tearDown()\n\nLayer tear-down does nothing.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.publisher.PublisherDirectives in ... seconds.\n    Tear down plone.testing.zca.ZCMLDirectives in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n    Tear down plone.testing.security.Checkers in ... seconds.\n\n    >>> zca.ZCML_DIRECTIVES.get('configurationContext', None) is None\n    True\n\n\nZope Object Database layers\n---------------------------\n\nThe ZODB layers are found in the module ``plone.testing.zodb``:::\n\n    >>> from plone.testing import zodb\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nEmpty ZODB layer\n~~~~~~~~~~~~~~~~\n\nThe ``EMPTY_ZODB`` layer is used to set up an empty ZODB using ``DemoStorage``.\n\nThe storage and database are set up as layer fixtures.\nThe database is exposed as the resource ``zodbDB``.\n\nA connection is opened for each test and exposed as ``zodbConnection``.\nThe ZODB root is also exposed, as ``zodbRoot``.\nA new transaction is begun for each test.\nOn test tear-down, the transaction is aborted, the connection is closed, and the two test-specific resources are deleted.\n\nThe layer has no bases.::\n\n    >>> \"%s.%s\" % (zodb.EMPTY_ZODB.__module__, zodb.EMPTY_ZODB.__name__,)\n    'plone.testing.zodb.EmptyZODB'\n\n    >>> zodb.EMPTY_ZODB.__bases__\n    ()\n\nLayer setup creates the database, but not a connection.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zodb.EMPTY_ZODB, setupLayers)\n    Set up plone.testing.zodb.EmptyZODB in ... seconds.\n\n    >>> db = zodb.EMPTY_ZODB['zodbDB']\n    >>> db.storage\n    EmptyZODB\n\n    >>> zodb.EMPTY_ZODB.get('zodbConnection', None) is None\n    True\n    >>> zodb.EMPTY_ZODB.get('zodbRoot', None) is None\n    True\n\nLet's now simulate a test.::\n\n    >>> zodb.EMPTY_ZODB.testSetUp()\n\nThe test would then execute. It may use the ZODB root.::\n\n    >>> zodb.EMPTY_ZODB['zodbConnection']\n    <...Connection...at ...>\n\n    >>> zodb.EMPTY_ZODB['zodbRoot']\n    {}\n\n    >>> zodb.EMPTY_ZODB['zodbRoot']['foo'] = 'bar'\n\nOn test tear-down, the transaction is aborted and the connection is closed.::\n\n    >>> zodb.EMPTY_ZODB.testTearDown()\n\n    >>> zodb.EMPTY_ZODB.get('zodbConnection', None) is None\n    True\n\n    >>> zodb.EMPTY_ZODB.get('zodbRoot', None) is None\n    True\n\nThe transaction has been rolled back.::\n\n    >>> conn = zodb.EMPTY_ZODB['zodbDB'].open()\n    >>> conn.root()\n    {}\n    >>> conn.close()\n\nLayer tear-down closes and deletes the database.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zodb.EmptyZODB in ... seconds.\n\n    >>> zodb.EMPTY_ZODB.get('zodbDB', None) is None\n    True\n\nExtending the ZODB layer\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen creating a test fixture, it is often desirable to add some initial data to the database.\nIf you want to do that once on layer setup, you can create your own layer class based on ``EmptyZODB`` and override its ``createStorage()`` and/or ``createDatabase()`` methods to return a pre-populated database.::\n\n    >>> import transaction\n    >>> from ZODB.DemoStorage import DemoStorage\n    >>> from ZODB.DB import DB\n\n    >>> class PopulatedZODB(zodb.EmptyZODB):\n    ...\n    ...     def createStorage(self):\n    ...         return DemoStorage(\"My storage\")\n    ...\n    ...     def createDatabase(self, storage):\n    ...         db = DB(storage)\n    ...         conn = db.open()\n    ...\n    ...         conn.root()['someData'] = 'a string'\n    ...\n    ...         transaction.commit()\n    ...         conn.close()\n    ...\n    ...         return db\n\n    >>> POPULATED_ZODB = PopulatedZODB()\n\nWe'll use this new layer in a similar manner to the test above, showing that the data is there for each test, but that other changes are rolled back.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, POPULATED_ZODB, setupLayers)\n    Set up ...PopulatedZODB in ... seconds.\n\n    >>> db = POPULATED_ZODB['zodbDB']\n    >>> db.storage\n    My storage\n\n    >>> POPULATED_ZODB.get('zodbConnection', None) is None\n    True\n    >>> POPULATED_ZODB.get('zodbRoot', None) is None\n    True\n\nLet's now simulate a test.::\n\n    >>> POPULATED_ZODB.testSetUp()\n\nThe test would then execute. It may use the ZODB root.::\n\n    >>> POPULATED_ZODB['zodbConnection']\n    <...Connection...at ...>\n\n    >>> POPULATED_ZODB['zodbRoot']\n    {'someData': 'a string'}\n\n    >>> POPULATED_ZODB['zodbRoot']['foo'] = 'bar'\n\nOn test tear-down, the transaction is aborted and the connection is closed.::\n\n    >>> POPULATED_ZODB.testTearDown()\n\n    >>> POPULATED_ZODB.get('zodbConnection', None) is None\n    True\n\n    >>> POPULATED_ZODB.get('zodbRoot', None) is None\n    True\n\nThe transaction has been rolled back.::\n\n    >>> conn = POPULATED_ZODB['zodbDB'].open()\n    >>> conn.root()\n    {'someData': 'a string'}\n    >>> conn.close()\n\nLayer tear-down closes and deletes the database.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down ...PopulatedZODB in ... seconds.\n\n    >>> POPULATED_ZODB.get('zodbDB', None) is None\n    True\n\nStacking ``DemoStorage`` storages\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe example above shows how to create a simple test fixture with a custom database.\nIt is sometimes useful to be able to stack these fixtures, so that a base layer sets up some data for one set of tests, and a child layer extends this, temporarily, with more data.\n\nThis can be achieved using layer bases and resource shadowing, combined with ZODB's stackable DemoStorage.\nThere is even a helper function available:::\n\n    >>> from plone.testing import Layer\n    >>> from plone.testing import zodb\n    >>> import transaction\n\n    >>> class ExpandedZODB(Layer):\n    ...     defaultBases = (POPULATED_ZODB,)\n    ...\n    ...     def setUp(self):\n    ...         # Get the database from the base layer\n    ...\n    ...         self['zodbDB'] = db = zodb.stackDemoStorage(self.get('zodbDB'), name='ExpandedZODB')\n    ...\n    ...         conn = db.open()\n    ...         conn.root()['additionalData'] = \"Some new data\"\n    ...         transaction.commit()\n    ...         conn.close()\n    ...\n    ...     def tearDown(self):\n    ...         # Close the database and delete the shadowed copy\n    ...\n    ...         self['zodbDB'].close()\n    ...         del self['zodbDB']\n\n    >>> EXPANDED_ZODB = ExpandedZODB()\n\nNotice that we are using plain ``Layer`` as a base class here.\nWe obtain the underlying database from our bases using the resource manager, and then create a shadow copy using a stacked storage.\nStacked storages contain the data of the original storage, but save changes in a separate (and, in this case, temporary) storage.\n\nLet's simulate a test run again to show how this would work.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, EXPANDED_ZODB, setupLayers)\n    Set up ...PopulatedZODB in ... seconds.\n    Set up ...ExpandedZODB in ... seconds.\n\n    >>> db = EXPANDED_ZODB['zodbDB']\n    >>> db.storage\n    ExpandedZODB\n\n    >>> EXPANDED_ZODB.get('zodbConnection', None) is None\n    True\n    >>> EXPANDED_ZODB.get('zodbRoot', None) is None\n    True\n\nLet's now simulate a test.::\n\n    >>> POPULATED_ZODB.testSetUp()\n    >>> EXPANDED_ZODB.testSetUp()\n\nThe test would then execute. It may use the ZODB root.::\n\n    >>> EXPANDED_ZODB['zodbConnection']\n    <...Connection...at ...>\n\n    >>> EXPANDED_ZODB['zodbRoot'] == dict(someData='a string', additionalData='Some new data')\n    True\n\n    >>> POPULATED_ZODB['zodbRoot']['foo'] = 'bar'\n\nOn test tear-down, the transaction is aborted and the connection is closed.::\n\n    >>> EXPANDED_ZODB.testTearDown()\n    >>> POPULATED_ZODB.testTearDown()\n\n    >>> EXPANDED_ZODB.get('zodbConnection', None) is None\n    True\n\n    >>> EXPANDED_ZODB.get('zodbRoot', None) is None\n    True\n\nThe transaction has been rolled back.::\n\n    >>> conn = EXPANDED_ZODB['zodbDB'].open()\n    >>> conn.root() == dict(someData='a string', additionalData='Some new data')\n    True\n    >>> conn.close()\n\nWe'll now tear down the expanded layer and inspect the database again.::\n\n    >>> runner.tear_down_unneeded(options, [POPULATED_ZODB], setupLayers, [])\n    Tear down ...ExpandedZODB in ... seconds.\n\n    >>> conn = EXPANDED_ZODB['zodbDB'].open()\n    >>> conn.root()\n    {'someData': 'a string'}\n\n    >>> conn.close()\n\nFinally, we'll tear down the rest of the layers.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down ...PopulatedZODB in ... seconds.\n\n    >>> EXPANDED_ZODB.get('zodbDB', None) is None\n    True\n    >>> POPULATED_ZODB.get('zodbDB', None) is None\n    True\n\n\nZope WSGI layers\n----------------\n\nThe Zope WSGI layers are found in the module ``plone.testing.zope``:::\n\n    >>> from plone.testing import zope\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nStartup\n~~~~~~~\n\n``STARTUP`` is the base layer for all Zope WSGI testing.\nIt sets up a Zope WSGI sandbox environment that is suitable for testing.\nIt extends the ``zca.LAYER_CLEANUP`` layer to maximise the chances of having and leaving a pristine environment.\n\n**Note**: You should probably use at least ``INTEGRATION_TESTING`` for any real test, although ``STARTUP`` is a useful base layer if you are setting up your own fixture.\nSee the description of ``INTEGRATION_TESTING`` below.::\n\n    >>> \"%s.%s\" % (zope.STARTUP.__module__, zope.STARTUP.__name__,)\n    'plone.testing.zope.Startup'\n\n    >>> zope.STARTUP.__bases__\n    (<Layer 'plone.testing.zca.LayerCleanup'>,)\n\nOn layer setup, Zope is initialised in a lightweight manner.\nThis involves certain patches to global modules that Zope manages, to reduce setup time, a database based on ``DemoStorage``, and a minimal set of products that must be installed for Zope 2 to work.\nA minimal set of ZCML is loaded, but packages in the ``Products`` namespace are not automatically configured.\n\nLet's just verify that we have an empty component registry before the test:::\n\n    >>> from zope.component import getSiteManager\n    >>> list(getSiteManager().registeredAdapters())\n    []\n\nFive sets a special vocabulary registry upon the layer setup, but there's a default one set before:::\n\n    >>> from zope.schema.vocabulary import getVocabularyRegistry\n    >>> getVocabularyRegistry()\n    <zope.schema.vocabulary.VocabularyRegistry object ...>\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zope.STARTUP, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zope.Startup in ... seconds.\n\nAfter layer setup, the ``zodbDB`` resource is available, pointing to the default ZODB.::\n\n    >>> zope.STARTUP['zodbDB']\n    <ZODB.DB.DB object at ...>\n\n    >>> zope.STARTUP['zodbDB'].storage\n    Startup\n\nIn addition, the resources ``host`` and ``port`` are set to the default hostname and port that are used for URLs generated from Zope.\nThese are hardcoded, but shadowed by layers that provide actual running Zope instances.::\n\n    >>> zope.STARTUP['host']\n    'nohost'\n    >>> zope.STARTUP['port']\n    80\n\nAt this point, it is also possible to get hold of a Zope application root.\nIf you are setting up a layer fixture, you can obtain an application root with the correct database that is properly closed by using the ``zopeApp()`` context manager.::\n\n    >>> with zope.zopeApp() as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\nIf you want to use a specific database, you can pass that to ``zopeApp()`` as the ``db`` parameter.\nA new connection will be opened and closed.::\n\n    >>> with zope.zopeApp(db=zope.STARTUP['zodbDB']) as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\nIf you want to reuse an existing connection, you can pass one to ``zopeApp()`` as the ``connection`` argument.\nIn this case, you will need to close the connection yourself.::\n\n    >>> conn = zope.STARTUP['zodbDB'].open()\n    >>> with zope.zopeApp(connection=conn) as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\n    >>> conn.opened is not None\n    True\n\n    >>> conn.close()\n\nIf an exception is raised within the ``with`` block, the transaction is aborted, but the connection is still closed (if it was opened by the context manager):::\n\n    >>> with zope.zopeApp() as app:\n    ...     raise Exception(\"Test error\")\n    Traceback (most recent call last):\n    ...\n    Exception: Test error\n\nIt is common to combine the ``zopeApp()`` context manager with a stacked ``DemoStorage`` to set up a layer-specific fixture.\nAs a sketch:::\n\n    from plone.testing import Layer, zope, zodb\n\n    class MyLayer(Layer):\n        defaultBases = (zope.STARTUP,)\n\n        def setUp(self):\n            self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')\n            with zope.zopeApp() as app:\n\n                # Set up a fixture, e.g.:\n                app.manage_addFolder('folder1')\n                folder = app['folder1']\n                folder._addRole('role1')\n                folder.manage_addUserFolder()\n\n                userFolder = folder['acl_users']\n                ignore = userFolder.userFolderAddUser('user1', 'secret', ['role1'], [])\n                folder.manage_role('role1', ('Access contents information',))\n\n        def tearDown(self):\n            self['zodbDB'].close()\n            del self['zodbDB']\n\nNote that you would normally *not* use the ``zope.zopeApp()`` in a test or in a ``testSetUp()`` or ``testTearDown()`` method.\nThe ``IntegrationTesting`` and ``FunctionalTesting`` layer classes manage the application object for you, exposing them as the resource ``app`` (see below).\n\nAfter layer setup, the global component registry contains a number of components needed by Zope.::\n\n    >>> len(list(getSiteManager().registeredAdapters())) > 1 # in fact, > a lot\n    True\n\nAnd Five has set a ``Zope2VocabularyRegistry`` vocabulary registry:::\n\n    >>> getVocabularyRegistry()\n    <....Zope2VocabularyRegistry object at ...>\n\nTo load additional ZCML, you can use the ``configurationContext`` resource:::\n\n    >>> zope.STARTUP['configurationContext']\n    <zope.configuration.config.ConfigurationMachine object ...>\n\nSee ``zca.rst`` for details about how to use ``zope.configuration`` for this purpose.\n\nThe ``STARTUP`` layer does not perform any specific test setup or tear-down.\nThat is left up to the ``INTEGRATION_TESTING`` and ``FUNCTIONAL_TESTING`` layers, or other layers using their layer classes - ``IntegrationTesting`` and ``FunctionalTesting``.::\n\n    >>> zope.STARTUP.testSetUp()\n    >>> zope.STARTUP.testTearDown()\n\nLayer tear-down resets the environment.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zope.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\n    >>> import Zope2\n    >>> Zope2._began_startup\n    0\n    >>> Zope2.DB is None\n    True\n    >>> Zope2.bobo_application is None\n    True\n\n    >>> list(getSiteManager().registeredAdapters())\n    []\n\n    >>> getVocabularyRegistry()\n    <zope.schema.vocabulary.VocabularyRegistry object at ...>\n\nIntegration test\n~~~~~~~~~~~~~~~~\n\n``INTEGRATION_TESTING`` is intended for simple Zope WSGI integration testing.\nIt extends ``STARTUP`` to ensure that a transaction is begun before and rolled back after each test.\nTwo resources, ``app`` and ``request``, are available during testing as well.\nIt does not manage any layer state - it implements the test lifecycle methods only.\n\n**Note:** You would normally *not* use ``INTEGRATION_TESTING`` as a base layer.\nInstead, you'd use the ``IntegrationTesting`` class to create your own layer with the testing lifecycle semantics of ``INTEGRATION_TESTING``.\nSee the ``plone.testing`` ``README`` file for an example.\n\n``app`` is the application root.\nIn a test, you should use this instead of the ``zopeApp`` context manager (which remains the weapon of choice for setting up persistent fixtures), because the ``app`` resource is part of the transaction managed by the layer.\n\n``request`` is a test request. It is the same as ``app.REQUEST``.::\n\n    >>> \"%s.%s\" % (zope.INTEGRATION_TESTING.__module__, zope.INTEGRATION_TESTING.__name__,)\n    'plone.testing.zope.IntegrationTesting'\n\n    >>> zope.INTEGRATION_TESTING.__bases__\n    (<Layer 'plone.testing.zope.Startup'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zope.INTEGRATION_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zope.Startup in ... seconds.\n    Set up plone.testing.zope.IntegrationTesting in ... seconds.\n\nLet's now simulate a test.\nOn test setup, the ``app`` resource is made available.\nIn a test, you should always use this to access the application root.::\n\n    >>> zope.STARTUP.testSetUp()\n    >>> zope.INTEGRATION_TESTING.testSetUp()\n\nThe test may now inspect and modify the environment.::\n\n    >>> app = zope.INTEGRATION_TESTING['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()\n    True\n\nThe request is also available:::\n\n    >>> zope.INTEGRATION_TESTING['request'] # would normally be self.layer['request']\n    <HTTPRequest, URL=http://nohost>\n\nWe can create a user and simulate logging in as that user, using the ``zope.login()`` helper:::\n\n    >>> app._addRole('role1')\n    >>> ignore = app['acl_users'].userFolderAddUser('user1', 'secret', ['role1'], [])\n    >>> zope.login(app['acl_users'], 'user1')\n\nThe first argument to ``zope.login()`` is the user folder that contains the relevant user.\nThe second argument is the user's name.\nThere is no need to give the password.::\n\n    >>> from AccessControl import getSecurityManager\n    >>> getSecurityManager().getUser()\n    <User 'user1'>\n\nYou can change the roles of a user using the ``zope.setRoles()`` helper:::\n\n    >>> sorted(getSecurityManager().getUser().getRolesInContext(app))\n    ['Authenticated', 'role1']\n\n    >>> zope.setRoles(app['acl_users'], 'user1', [])\n    >>> getSecurityManager().getUser().getRolesInContext(app)\n    ['Authenticated']\n\nTo become the anonymous user again, use ``zope.logout()``:::\n\n    >>> zope.logout()\n    >>> getSecurityManager().getUser()\n    <SpecialUser 'Anonymous User'>\n\nOn tear-down, the transaction is rolled back:::\n\n    >>> zope.INTEGRATION_TESTING.testTearDown()\n    >>> zope.STARTUP.testTearDown()\n\n    >>> 'app' in zope.INTEGRATION_TESTING\n    False\n\n    >>> 'request' in zope.INTEGRATION_TESTING\n    False\n\n    >>> with zope.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\n\nLet's tear down the layers:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zope.IntegrationTesting in ... seconds.\n    Tear down plone.testing.zope.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nFunctional testing\n~~~~~~~~~~~~~~~~~~\n\nThe ``FUNCTIONAL_TESTING`` layer is very similar to ``INTEGRATION_TESTING``, and exposes the same fixture and resources.\nHowever, it has different transaction semantics.\n``INTEGRATION_TESTING`` creates a single database storage, and rolls back the transaction after each test.\n``FUNCTIONAL_TESTING`` creates a whole new database storage (stacked on top of the basic fixture) for each test.\nThis allows testing of code that performs an explicit commit, which is usually required for end-to-end testing.\nThe downside is that the set-up and tear-down of each test takes longer.\n\n**Note:** Again, you would normally *not* use ``FUNCTIONAL_TESTING`` as a base layer.\nInstead, you'd use the ``FunctionalTesting`` class to create your own layer with the testing lifecycle semantics of ``FUNCTIONAL_TESTING``.\nSee the ``plone.testing`` ``README`` file for an example.\n\nLike ``INTEGRATION_TESTING``, ``FUNCTIONAL_TESTING`` is based on ``STARTUP``.::\n\n    >>> \"%s.%s\" % (zope.FUNCTIONAL_TESTING.__module__, zope.FUNCTIONAL_TESTING.__name__,)\n    'plone.testing.zope.FunctionalTesting'\n\n    >>> zope.FUNCTIONAL_TESTING.__bases__\n    (<Layer 'plone.testing.zope.Startup'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zope.FUNCTIONAL_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zope.Startup in ... seconds.\n    Set up plone.testing.zope.FunctionalTesting in ... seconds.\n\nLet's now simulate a test.\nOn test setup, the ``app`` resource is made available.\nIn a test, you should always use this to access the application root.\nThe ``request`` resource can be used to access the test request.::\n\n    >>> zope.STARTUP.testSetUp()\n    >>> zope.FUNCTIONAL_TESTING.testSetUp()\n\nThe test may now inspect and modify the environment.\nIt may also commit things.::\n\n    >>> app = zope.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()\n    True\n\n    >>> import transaction\n    >>> transaction.commit()\n\nOn tear-down, the database is torn down.::\n\n    >>> zope.FUNCTIONAL_TESTING.testTearDown()\n    >>> zope.STARTUP.testTearDown()\n\n    >>> 'app' in zope.FUNCTIONAL_TESTING\n    False\n\n    >>> 'request' in zope.FUNCTIONAL_TESTING\n    False\n\n    >>> with zope.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\nLet's tear down the layer:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zope.FunctionalTesting in ... seconds.\n    Tear down plone.testing.zope.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nThe test browser\n~~~~~~~~~~~~~~~~\n\nThe ``FUNCTIONAL_TESTING`` layer and ``FunctionalTesting`` layer class are the basis for functional testing using ``zope.testbrowser``.\nThis simulates a web browser, allowing an application to be tested \"end-to-end\" via its user-facing interface.\n\nTo use the test browser with a ``FunctionalTesting`` layer (such as the default ``FUNCTIONAL_TESTING`` layer instance), we need to use a custom browser client, which ensures that the test browser uses the correct ZODB and is appropriately isolated from the test code.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zope.FUNCTIONAL_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zope.Startup in ... seconds.\n    Set up plone.testing.zope.FunctionalTesting in ... seconds.\n\nLet's simulate a test:::\n\n    >>> zope.STARTUP.testSetUp()\n    >>> zope.FUNCTIONAL_TESTING.testSetUp()\n\nIn the test, we can create a test browser client like so:::\n\n    >>> app = zope.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']\n    >>> browser = zope.Browser(app)\n\nIt is usually best to let Zope errors be shown with full tracebacks:::\n\n    >>> browser.handleErrors = False\n\nWe can add to the test fixture in the test.\nFor those changes to be visible to the test browser, however, we need to commit the transaction.::\n\n    >>> _ = app.manage_addDTMLDocument('dtml-doc-1')\n    >>> import transaction; transaction.commit()\n\nWe can now view this via the test browser:::\n\n    >>> browser.open(app.absolute_url() + '/dtml-doc-1')\n    >>> 'This is the dtml-doc-1 Document.' in browser.contents\n    True\n\nThe test browser integration converts the URL into a request and passes control to Zope's publisher.\nLet's check that query strings are available for input processing:::\n\n    >>> from urllib.parse import urlencode\n    >>> _ = app.manage_addDTMLDocument('dtml-doc-2', file='<dtml-var foo>')\n    >>> import transaction; transaction.commit()\n    >>> qs = urlencode({'foo': 'boo, bar & baz'})  # sic: the ampersand.\n    >>> browser.open(app.absolute_url() + '/dtml-doc-2?' + qs)\n    >>> browser.contents\n    'boo, bar & baz'\n\nThe test browser also works with iterators.\nLet's test that with a simple file implementation that uses an iterator.::\n\n    >>> from plone.testing.tests import DummyFile\n    >>> app._setObject('file1', DummyFile('file1'))\n    'file1'\n\n    >>> import transaction; transaction.commit()\n\n    >>> browser.open(app.absolute_url() + '/file1')\n    >>> 'The test browser also works with iterators' in browser.contents\n    True\n\nSee the ``zope.testbrowser`` documentation for more information about how to use the browser client.\n\nOn tear-down, the database is torn down.::\n\n    >>> zope.FUNCTIONAL_TESTING.testTearDown()\n    >>> zope.STARTUP.testTearDown()\n\n    >>> 'app' in zope.FUNCTIONAL_TESTING\n    False\n\n    >>> 'request' in zope.FUNCTIONAL_TESTING\n    False\n\n    >>> with zope.zopeApp() as app:\n    ...     'acl_users' in app.objectIds()\\\n    ...         and 'folder1' not in app.objectIds()\\\n    ...         and 'file1' not in app.objectIds()\n    True\n\nLet's tear down the layer:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zope.FunctionalTesting in ... seconds.\n    Tear down plone.testing.zope.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nHTTP server\n~~~~~~~~~~~\n\nThe ``WSGI_SERVER_FIXTURE`` layer extends ``STARTUP`` to start a single-threaded Zope server in a separate thread.\nThis makes it possible to connect to the test instance using a web browser or a testing tool like Selenium or Windmill.\n\nThe ``WSGI_SERVER`` layer provides a ``FunctionalTesting`` layer that has ``WSGI_SERVER_FIXTURE`` as its base.::\n\n    >>> \"%s.%s\" % (zope.WSGI_SERVER_FIXTURE.__module__, zope.WSGI_SERVER_FIXTURE.__name__,)\n    'plone.testing.zope.WSGIServer'\n\n    >>> zope.WSGI_SERVER_FIXTURE.__bases__\n    (<Layer 'plone.testing.zope.Startup'>,)\n\n\n    >>> \"%s.%s\" % (zope.WSGI_SERVER.__module__, zope.WSGI_SERVER.__name__,)\n    'plone.testing.zope.WSGIServer:Functional'\n\n    >>> zope.WSGI_SERVER.__bases__\n    (<Layer 'plone.testing.zope.WSGIServer'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zope.WSGI_SERVER, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zope.Startup in ... seconds.\n    Set up plone.testing.zope.WSGIServer in ... seconds.\n    Set up plone.testing.zope.WSGIServer:Functional in ... seconds.\n\nAfter layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::\n\n    >>> host = zope.WSGI_SERVER['host']\n    >>> host\n    'localhost'\n\n    >>> port = zope.WSGI_SERVER['port']\n\nLet's now simulate a test.\nTest setup does nothing beyond what the base layers do.::\n\n    >>> zope.STARTUP.testSetUp()\n    >>> zope.FUNCTIONAL_TESTING.testSetUp()\n    >>> zope.WSGI_SERVER.testSetUp()\n\nIt is common in a test to use the Python API to change the state of the server (e.g.\ncreate some content or change a setting) and then use the HTTP protocol to look at the results.\nBear in mind that the server is running in a separate thread, with a separate security manager, so calls to ``zope.login()`` and ``zope.logout()``, for instance, do not affect the server thread.::\n\n    >>> app = zope.WSGI_SERVER['app'] # would normally be self.layer['app']\n    >>> _ = app.manage_addDTMLDocument('dtml-doc-3')\n\nNote that we need to commit the transaction before it will show up in the other thread.::\n\n    >>> import transaction; transaction.commit()\n\nWe can now look for this new object through the server.::\n\n    >>> app_url = app.absolute_url()\n    >>> app_url.split(':')[:-1]\n    ['http', '//localhost']\n\n    >>> from urllib.request import urlopen\n    >>> conn = urlopen(app_url + '/dtml-doc-3', timeout=5)\n    >>> b'This is the dtml-doc-3 Document.' in conn.read()\n    True\n    >>> conn.close()\n\nTest tear-down does nothing beyond what the base layers do.::\n\n    >>> zope.WSGI_SERVER.testTearDown()\n    >>> zope.FUNCTIONAL_TESTING.testTearDown()\n    >>> zope.STARTUP.testTearDown()\n\n    >>> 'app' in zope.WSGI_SERVER\n    False\n\n    >>> 'request' in zope.WSGI_SERVER\n    False\n\n    >>> with zope.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\nWhen the server is torn down, the WSGIServer thread is stopped.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zope.WSGIServer:Functional in ... seconds.\n    Tear down plone.testing.zope.WSGIServer in ... seconds.\n    Tear down plone.testing.zope.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nWe can expect one of these exceptions:\n- URLError: <urlopen error [Errno ...] Connection refused>\n- error: [Errno 104] Connection reset by peer\n\n    >>> try:\n    ...     conn = urlopen(app_url + '/folder1', timeout=5)\n    ... except Exception as exc:\n    ...     if 'Connection refused' not in str(exc) and 'Connection reset' not in str(exc):\n    ...         raise exc\n    ... else:\n    ...     print('urlopen should have raised exception')\n\n\nZope 2 layers\n-------------\n\nThe Zope 2 layers are found in the module ``plone.testing.zserver``:::\n\n    >>> from plone.testing import zserver\n\nFor testing, we need a testrunner:::\n\n    >>> from zope.testrunner import runner\n\nStartup\n~~~~~~~\n\n``STARTUP`` is the base layer for all Zope 2 testing.\nIt sets up a Zope 2 sandbox environment that is suitable for testing.\nIt extends the ``zca.LAYER_CLEANUP`` layer to maximise the chances of having and leaving a pristine environment.\n\n**Note**: You should probably use at least ``INTEGRATION_TESTING`` for any real test, although ``STARTUP`` is a useful base layer if you are setting up your own fixture.\nSee the description of ``INTEGRATION_TESTING`` below.::\n\n    >>> \"%s.%s\" % (zserver.STARTUP.__module__, zserver.STARTUP.__name__,)\n    'plone.testing.zserver.Startup'\n\n    >>> zserver.STARTUP.__bases__\n    (<Layer 'plone.testing.zca.LayerCleanup'>,)\n\nOn layer setup, Zope is initialised in a lightweight manner.\nThis involves certain patches to global modules that Zope manages, to reduce setup time, a database based on ``DemoStorage``, and a minimal set of products that must be installed for Zope 2 to work.\nA minimal set of ZCML is loaded, but packages in the ``Products`` namespace are not automatically configured.\n\nLet's just verify that we have an empty component registry before the test:::\n\n    >>> from zope.component import getSiteManager\n    >>> list(getSiteManager().registeredAdapters())\n    []\n\nFive sets a special vocabulary registry upon the layer setup, but there's a default one set before:::\n\n    >>> from zope.schema.vocabulary import getVocabularyRegistry\n    >>> getVocabularyRegistry()\n    <zope.schema.vocabulary.VocabularyRegistry object ...>\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.STARTUP, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n\nAfter layer setup, the ``zodbDB`` resource is available, pointing to the default ZODB.::\n\n    >>> zserver.STARTUP['zodbDB']\n    <ZODB.DB.DB object at ...>\n\n    >>> zserver.STARTUP['zodbDB'].storage\n    Startup\n\nIn addition, the resources ``host`` and ``port`` are set to the default hostname and port that are used for URLs generated from Zope.\nThese are hardcoded, but shadowed by layers that provide actual running Zope instances.::\n\n    >>> zserver.STARTUP['host']\n    'nohost'\n    >>> zserver.STARTUP['port']\n    80\n\nAt this point, it is also possible to get hold of a Zope application root.\nIf you are setting up a layer fixture, you can obtain an application root with the correct database that is properly closed by using the ``zopeApp()`` context manager.::\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\nIf you want to use a specific database, you can pass that to ``zopeApp()`` as the ``db`` parameter.\nA new connection will be opened and closed.::\n\n    >>> with zserver.zopeApp(db=zserver.STARTUP['zodbDB']) as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\nIf you want to reuse an existing connection, you can pass one to ``zopeApp()`` as the ``connection`` argument.\nIn this case, you will need to close the connection yourself.::\n\n    >>> conn = zserver.STARTUP['zodbDB'].open()\n    >>> with zserver.zopeApp(connection=conn) as app:\n    ...     'acl_users' in app.objectIds()\n    True\n\n    >>> conn.opened is not None\n    True\n\n    >>> conn.close()\n\nIf an exception is raised within the ``with`` block, the transaction is aborted, but the connection is still closed (if it was opened by the context manager):::\n\n    >>> with zserver.zopeApp() as app:\n    ...     raise Exception(\"Test error\")\n    Traceback (most recent call last):\n    ...\n    Exception: Test error\n\nIt is common to combine the ``zopeApp()`` context manager with a stacked ``DemoStorage`` to set up a layer-specific fixture.\nAs a sketch:::\n\n    from plone.testing import Layer, zserver, zodb\n\n    class MyLayer(Layer):\n        defaultBases = (zserver.STARTUP,)\n\n        def setUp(self):\n            self['zodbDB'] = zodb.stackDemoStorage(self.get('zodbDB'), name='MyLayer')\n            with zserver.zopeApp() as app:\n\n                # Set up a fixture, e.g.:\n                app.manage_addFolder('folder1')\n                folder = app['folder1']\n                folder._addRole('role1')\n                folder.manage_addUserFolder()\n\n                userFolder = folder['acl_users']\n                ignore = userFolder.userFolderAddUser('user1', 'secret', ['role1'], [])\n                folder.manage_role('role1', ('Access contents information',))\n\n        def tearDown(self):\n            self['zodbDB'].close()\n            del self['zodbDB']\n\nNote that you would normally *not* use the ``zserver.zopeApp()`` in a test or in a ``testSetUp()`` or ``testTearDown()`` method.\nThe ``IntegrationTesting`` and ``FunctionalTesting`` layer classes manage the application object for you, exposing them as the resource ``app`` (see below).\n\nAfter layer setup, the global component registry contains a number of components needed by Zope.::\n\n    >>> len(list(getSiteManager().registeredAdapters())) > 1 # in fact, > a lot\n    True\n\nAnd Five has set a ``Zope2VocabularyRegistry`` vocabulary registry:::\n\n    >>> getVocabularyRegistry()\n    <....Zope2VocabularyRegistry object at ...>\n\nTo load additional ZCML, you can use the ``configurationContext`` resource:::\n\n    >>> zserver.STARTUP['configurationContext']\n    <zope.configuration.config.ConfigurationMachine object ...>\n\nSee ``zca.rst`` for details about how to use ``zope.configuration`` for this purpose.\n\nThe ``STARTUP`` layer does not perform any specific test setup or tear-down.\nThat is left up to the ``INTEGRATION_TESTING`` and ``FUNCTIONAL_TESTING`` layers, or other layers using their layer classes - ``IntegrationTesting`` and ``FunctionalTesting``.::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.STARTUP.testTearDown()\n\nLayer tear-down resets the environment.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\n    >>> import ZServer.Zope2\n    >>> ZServer.Zope2._began_startup\n    0\n    >>> import Zope2\n    >>> Zope2.DB is None\n    True\n    >>> Zope2.bobo_application is None\n    True\n\n    >>> list(getSiteManager().registeredAdapters())\n    []\n\n    >>> getVocabularyRegistry()\n    <zope.schema.vocabulary.VocabularyRegistry object at ...>\n\nIntegration test\n~~~~~~~~~~~~~~~~\n\n``INTEGRATION_TESTING`` is intended for simple Zope 2 integration testing.\nIt extends ``STARTUP`` to ensure that a transaction is begun before and rolled back after each test.\nTwo resources, ``app`` and ``request``, are available during testing as well.\nIt does not manage any layer state - it implements the test lifecycle methods only.\n\n**Note:** You would normally *not* use ``INTEGRATION_TESTING`` as a base layer.\nInstead, you'd use the ``IntegrationTesting`` class to create your own layer with the testing lifecycle semantics of ``INTEGRATION_TESTING``.\nSee the ``plone.testing`` ``README`` file for an example.\n\n``app`` is the application root.\nIn a test, you should use this instead of the ``zopeApp`` context manager (which remains the weapon of choice for setting up persistent fixtures), because the ``app`` resource is part of the transaction managed by the layer.\n\n``request`` is a test request. It is the same as ``app.REQUEST``.::\n\n    >>> \"%s.%s\" % (zserver.INTEGRATION_TESTING.__module__, zserver.INTEGRATION_TESTING.__name__,)\n    'plone.testing.zserver.IntegrationTesting'\n\n    >>> zserver.INTEGRATION_TESTING.__bases__\n    (<Layer 'plone.testing.zserver.Startup'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.INTEGRATION_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n    Set up plone.testing.zserver.IntegrationTesting in ... seconds.\n\nLet's now simulate a test.\nOn test setup, the ``app`` resource is made available.\nIn a test, you should always use this to access the application root.::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.INTEGRATION_TESTING.testSetUp()\n\nThe test may now inspect and modify the environment.::\n\n    >>> app = zserver.INTEGRATION_TESTING['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()\n    True\n\nThe request is also available:::\n\n    >>> zserver.INTEGRATION_TESTING['request'] # would normally be self.layer['request']\n    <HTTPRequest, URL=http://nohost>\n\nWe can create a user and simulate logging in as that user, using the ``zserver.login()`` helper:::\n\n    >>> app._addRole('role1')\n    >>> ignore = app['acl_users'].userFolderAddUser('user1', 'secret', ['role1'], [])\n    >>> zserver.login(app['acl_users'], 'user1')\n\nThe first argument to ``zserver.login()`` is the user folder that contains the relevant user.\nThe second argument is the user's name.\nThere is no need to give the password.::\n\n    >>> from AccessControl import getSecurityManager\n    >>> getSecurityManager().getUser()\n    <User 'user1'>\n\nYou can change the roles of a user using the ``zserver.setRoles()`` helper:::\n\n    >>> sorted(getSecurityManager().getUser().getRolesInContext(app))\n    ['Authenticated', 'role1']\n\n    >>> zserver.setRoles(app['acl_users'], 'user1', [])\n    >>> getSecurityManager().getUser().getRolesInContext(app)\n    ['Authenticated']\n\nTo become the anonymous user again, use ``zserver.logout()``:::\n\n    >>> zserver.logout()\n    >>> getSecurityManager().getUser()\n    <SpecialUser 'Anonymous User'>\n\nOn tear-down, the transaction is rolled back:::\n\n    >>> zserver.INTEGRATION_TESTING.testTearDown()\n    >>> zserver.STARTUP.testTearDown()\n\n    >>> 'app' in zserver.INTEGRATION_TESTING\n    False\n\n    >>> 'request' in zserver.INTEGRATION_TESTING\n    False\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\n\nLet's tear down the layers:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.IntegrationTesting in ... seconds.\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nFunctional testing\n~~~~~~~~~~~~~~~~~~\n\nThe ``FUNCTIONAL_TESTING`` layer is very similar to ``INTEGRATION_TESTING``, and exposes the same fixture and resources.\nHowever, it has different transaction semantics.\n``INTEGRATION_TESTING`` creates a single database storage, and rolls back the transaction after each test.\n``FUNCTIONAL_TESTING`` creates a whole new database storage (stacked on top of the basic fixture) for each test.\nThis allows testing of code that performs an explicit commit, which is usually required for end-to-end testing.\nThe downside is that the set-up and tear-down of each test takes longer.\n\n**Note:** Again, you would normally *not* use ``FUNCTIONAL_TESTING`` as a base layer.\nInstead, you'd use the ``FunctionalTesting`` class to create your own layer with the testing lifecycle semantics of ``FUNCTIONAL_TESTING``.\nSee the ``plone.testing`` ``README`` file for an example.\n\nLike ``INTEGRATION_TESTING``, ``FUNCTIONAL_TESTING`` is based on ``STARTUP``.::\n\n    >>> \"%s.%s\" % (zserver.FUNCTIONAL_TESTING.__module__, zserver.FUNCTIONAL_TESTING.__name__,)\n    'plone.testing.zserver.FunctionalTesting'\n\n    >>> zserver.FUNCTIONAL_TESTING.__bases__\n    (<Layer 'plone.testing.zserver.Startup'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.FUNCTIONAL_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n    Set up plone.testing.zserver.FunctionalTesting in ... seconds.\n\nLet's now simulate a test.\nOn test setup, the ``app`` resource is made available.\nIn a test, you should always use this to access the application root.\nThe ``request`` resource can be used to access the test request.::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.FUNCTIONAL_TESTING.testSetUp()\n\nThe test may now inspect and modify the environment.\nIt may also commit things.::\n\n    >>> app = zserver.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n    >>> 'acl_users' in app.objectIds() and 'folder1' in app.objectIds()\n    True\n\n    >>> import transaction\n    >>> transaction.commit()\n\nOn tear-down, the database is torn down.::\n\n    >>> zserver.FUNCTIONAL_TESTING.testTearDown()\n    >>> zserver.STARTUP.testTearDown()\n\n    >>> 'app' in zserver.FUNCTIONAL_TESTING\n    False\n\n    >>> 'request' in zserver.FUNCTIONAL_TESTING\n    False\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\nLet's tear down the layer:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.FunctionalTesting in ... seconds.\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nThe test browser\n~~~~~~~~~~~~~~~~\n\nThe ``FUNCTIONAL_TESTING`` layer and ``FunctionalTesting`` layer class are the basis for functional testing using ``zope.testbrowser``.\nThis simulates a web browser, allowing an application to be tested \"end-to-end\" via its user-facing interface.\n\nTo use the test browser with a ``FunctionalTesting`` layer (such as the default ``FUNCTIONAL_TESTING`` layer instance), we need to use a custom browser client, which ensures that the test browser uses the correct ZODB and is appropriately isolated from the test code.::\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.FUNCTIONAL_TESTING, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n    Set up plone.testing.zserver.FunctionalTesting in ... seconds.\n\nLet's simulate a test:::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.FUNCTIONAL_TESTING.testSetUp()\n\nIn the test, we can create a test browser client like so:::\n\n    >>> app = zserver.FUNCTIONAL_TESTING['app'] # would normally be self.layer['app']\n    >>> browser = zserver.Browser(app)\n\nIt is usually best to let Zope errors be shown with full tracebacks:::\n\n    >>> browser.handleErrors = False\n\nWe can add to the test fixture in the test.\nFor those changes to be visible to the test browser, however, we need to commit the transaction.::\n\n    >>> app.manage_addFolder('folder1')\n    >>> import transaction; transaction.commit()\n\nWe can now view this via the test browser:::\n\n    >>> browser.open(app.absolute_url() + '/folder1')\n\n    >>> browser.contents.replace('\"', '').replace(\"'\", \"\")\n    '<Folder ...'\n\nThe __repr__ of Zope objects is not stable anymore.\n\nThe test browser integration converts the URL into a request and passes control to Zope's publisher.\nLet's check that query strings are available for input processing:::\n\n    >>> import urllib\n    >>> qs = urllib.urlencode({'foo': 'boo, bar & baz'})  # sic: the ampersand.\n    >>> _ = app['folder1'].addDTMLMethod('index_html', file='<dtml-var foo>')\n    >>> import transaction; transaction.commit()\n    >>> browser.open(app.absolute_url() + '/folder1?' + qs)\n    >>> browser.contents\n    'boo, bar & baz'\n\nThe test browser also works with iterators.\nLet's test that with a simple file implementation that uses an iterator.::\n\n    >>> from plone.testing.tests import DummyFile\n    >>> app._setObject('file1', DummyFile('file1'))\n    'file1'\n\n    >>> import transaction; transaction.commit()\n\n    >>> browser.open(app.absolute_url() + '/file1')\n    >>> 'The test browser also works with iterators' in browser.contents\n    True\n\nSee the ``zope.testbrowser`` documentation for more information about how to use the browser client.\n\nOn tear-down, the database is torn down.::\n\n    >>> zserver.FUNCTIONAL_TESTING.testTearDown()\n    >>> zserver.STARTUP.testTearDown()\n\n    >>> 'app' in zserver.FUNCTIONAL_TESTING\n    False\n\n    >>> 'request' in zserver.FUNCTIONAL_TESTING\n    False\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds()\\\n    ...         and 'folder1' not in app.objectIds()\\\n    ...         and 'file1' not in app.objectIds()\n    True\n\nLet's tear down the layer:::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.FunctionalTesting in ... seconds.\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nHTTP server\n~~~~~~~~~~~\n\nThe ``ZSERVER_FIXTURE`` layer extends ``STARTUP`` to start a single-threaded Zope server in a separate thread.\nThis makes it possible to connect to the test instance using a web browser or a testing tool like Selenium or Windmill.\n\nThe ``ZSERVER`` layer provides a ``FunctionalTesting`` layer that has ``ZSERVER_FIXTURE`` as its base.::\n\n    >>> \"%s.%s\" % (zserver.ZSERVER_FIXTURE.__module__, zserver.ZSERVER_FIXTURE.__name__,)\n    'plone.testing.zserver.ZServer'\n\n    >>> zserver.ZSERVER_FIXTURE.__bases__\n    (<Layer 'plone.testing.zserver.Startup'>,)\n\n\n    >>> \"%s.%s\" % (zserver.ZSERVER.__module__, zserver.ZSERVER.__name__,)\n    'plone.testing.zserver.ZServer:Functional'\n\n    >>> zserver.ZSERVER.__bases__\n    (<Layer 'plone.testing.zserver.ZServer'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.ZSERVER, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n    Set up plone.testing.zserver.ZServer in ... seconds.\n    Set up plone.testing.zserver.ZServer:Functional in ... seconds.\n\nAfter layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::\n\n    >>> host = zserver.ZSERVER['host']\n    >>> port = zserver.ZSERVER['port']\n\nLet's now simulate a test.\nTest setup does nothing beyond what the base layers do.::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.FUNCTIONAL_TESTING.testSetUp()\n    >>> zserver.ZSERVER.testSetUp()\n\nIt is common in a test to use the Python API to change the state of the server (e.g.\ncreate some content or change a setting) and then use the HTTP protocol to look at the results.\nBear in mind that the server is running in a separate thread, with a separate security manager, so calls to ``zserver.login()`` and ``zserver.logout()``, for instance, do not affect the server thread.::\n\n    >>> app = zserver.ZSERVER['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n\nNote that we need to commit the transaction before it will show up in the other thread.::\n\n    >>> import transaction; transaction.commit()\n\nWe can now look for this new object through the server.::\n\n    >>> app_url = app.absolute_url()\n    >>> app_url.split(':')[:-1]\n    ['http', '//localhost']\n\n    >>> import urllib2\n    >>> conn = urllib2.urlopen(app_url + '/folder1', timeout=5)\n    >>> conn.read().replace('\"', '').replace(\"'\", \"\")\n    '<Folder ...'\n    >>> conn.close()\n\nThe __repr__ of Zope objects is not stable anymore.\n\nTest tear-down does nothing beyond what the base layers do.::\n\n    >>> zserver.ZSERVER.testTearDown()\n    >>> zserver.FUNCTIONAL_TESTING.testTearDown()\n    >>> zserver.STARTUP.testTearDown()\n\n    >>> 'app' in zserver.ZSERVER\n    False\n\n    >>> 'request' in zserver.ZSERVER\n    False\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\nWhen the server is torn down, the ZServer thread is stopped.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.ZServer:Functional in ... seconds.\n    Tear down plone.testing.zserver.ZServer in ... seconds.\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\nWe can expect one of these exceptions:\n- URLError: <urlopen error [Errno ...] Connection refused>\n- error: [Errno 104] Connection reset by peer\n\n    >>> try:\n    ...     conn = urllib2.urlopen(app_url + '/folder1', timeout=5)\n    ... except Exception as exc:\n    ...     if 'Connection refused' not in str(exc) and 'Connection reset' not in str(exc):\n    ...         raise exc\n    ... else:\n    ...     print('urllib2.urlopen should have raised exception')\n\n\nFTP server\n~~~~~~~~~~\n\nThe ``FTP_SERVER`` layer is identical similar to ``ZSERVER``, except that it starts an FTP server instead of an HTTP server.\nThe fixture is contained in the ``FTP_SERVER_FIXTURE`` layer.\n\n    **Warning:** It is generally not safe to run the ``ZSERVER`` and ``FTP_SERVER`` layers concurrently, because they both start up the same ``asyncore`` loop.\n    If you need concurrent HTTP and FTP servers in a test, you can create your own layer by subclassing the ``ZServer`` layer class, and overriding the ``setUpServer()`` and ``tearDownServer()`` hooks to set up and close both servers.\n    See the code for an example.\n\nThe ``FTP_SERVER_FIXTURE`` layer is based on the ``STARTUP`` layer.::\n\n    >>> \"%s.%s\" % (zserver.FTP_SERVER_FIXTURE.__module__, zserver.FTP_SERVER_FIXTURE.__name__,)\n    'plone.testing.zserver.FTPServer'\n\n    >>> zserver.FTP_SERVER_FIXTURE.__bases__\n    (<Layer 'plone.testing.zserver.Startup'>,)\n\nThe ``FTP_SERVER`` layer is based on ``FTP_SERVER_FIXTURE``, using the ``FunctionalTesting`` layer class.::\n\n    >>> \"%s.%s\" % (zserver.FTP_SERVER.__module__, zserver.FTP_SERVER.__name__,)\n    'plone.testing.zserver.FTPServer:Functional'\n\n    >>> zserver.FTP_SERVER.__bases__\n    (<Layer 'plone.testing.zserver.FTPServer'>,)\n\n    >>> options = runner.get_options([], [])\n    >>> setupLayers = {}\n    >>> runner.setup_layer(options, zserver.FTP_SERVER, setupLayers)\n    Set up plone.testing.zca.LayerCleanup in ... seconds.\n    Set up plone.testing.zserver.Startup in ... seconds.\n    Set up plone.testing.zserver.FTPServer in ... seconds.\n    Set up plone.testing.zserver.FTPServer:Functional in ... seconds.\n\nAfter layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.::\n\n    >>> host = zserver.FTP_SERVER['host']\n    >>> port = zserver.FTP_SERVER['port']\n\nLet's now simulate a test.\nTest setup does nothing beyond what the base layers do.::\n\n    >>> zserver.STARTUP.testSetUp()\n    >>> zserver.FUNCTIONAL_TESTING.testSetUp()\n    >>> zserver.FTP_SERVER.testSetUp()\n\nAs with ``ZSERVER``, we will set up some content for the test and then access it over the FTP port.::\n\n    >>> app = zserver.FTP_SERVER['app'] # would normally be self.layer['app']\n    >>> app.manage_addFolder('folder1')\n\nWe'll also create a user in the root user folder to make FTP access easier.::\n\n    >>> ignore = app['acl_users'].userFolderAddUser('admin', 'secret', ['Manager'], ())\n\nNote that we need to commit the transaction before it will show up in the other thread.::\n\n    >>> import transaction; transaction.commit()\n\nWe can now look for this new object through the server.::\n\n    >>> app_path = app.absolute_url_path()\n\n    >>> import ftplib\n    >>> ftpClient = ftplib.FTP()\n    >>> ftpClient.connect(host, port, timeout=5)\n    '220 ... FTP server (...) ready.'\n\n    >>> ftpClient.login('admin', 'secret')\n    '230 Login successful.'\n\n    >>> ftpClient.cwd(app_path)\n    '250 CWD command successful.'\n\n    >>> ftpClient.retrlines('LIST')\n    drwxrwx---   1 Zope     Zope            0 ... .\n    ...--w--w----   1 Zope     Zope            0 ... acl_users\n    drwxrwx---   1 Zope     Zope            0 ... folder1\n    '226 Transfer complete'\n\n    >>> ftpClient.quit()\n    '221 Goodbye.'\n\nTest tear-down does nothing beyond what the base layers do.::\n\n    >>> zserver.FTP_SERVER.testTearDown()\n    >>> zserver.FUNCTIONAL_TESTING.testTearDown()\n    >>> zserver.STARTUP.testTearDown()\n\n    >>> 'app' in zserver.ZSERVER\n    False\n\n    >>> 'request' in zserver.ZSERVER\n    False\n\n    >>> with zserver.zopeApp() as app:\n    ...     'acl_users' in app.objectIds() and 'folder1' not in app.objectIds()\n    True\n\nWhen the server is torn down, the FTP thread is stopped.::\n\n    >>> runner.tear_down_unneeded(options, [], setupLayers, [])\n    Tear down plone.testing.zserver.FTPServer:Functional in ... seconds.\n    Tear down plone.testing.zserver.FTPServer in ... seconds.\n    Tear down plone.testing.zserver.Startup in ... seconds.\n    Tear down plone.testing.zca.LayerCleanup in ... seconds.\n\n    >>> ftpClient.connect(host, port, timeout=5)\n    Traceback (most recent call last):\n    ...\n    error: [Errno ...] Connection refused\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "Testing infrastructure for Zope and Plone projects.",
    "version": "9.0.1",
    "project_urls": {
        "Homepage": "https://github.com/plone/plone.testing"
    },
    "split_keywords": [
        "plone",
        "zope",
        "testing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "48cf2108c8a3b809f5aa0d726fcd2e2a77e900c26b4f9a03e6722e90b7c7f8db",
                "md5": "41245e6454ad0f3f0008ba08354bb911",
                "sha256": "ad47672541376889716aef5f8a882d9eb22c1cffa5994bf73f860b85b0351e7c"
            },
            "downloads": -1,
            "filename": "plone.testing-9.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "41245e6454ad0f3f0008ba08354bb911",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 120857,
            "upload_time": "2023-11-30T19:31:14",
            "upload_time_iso_8601": "2023-11-30T19:31:14.941171Z",
            "url": "https://files.pythonhosted.org/packages/48/cf/2108c8a3b809f5aa0d726fcd2e2a77e900c26b4f9a03e6722e90b7c7f8db/plone.testing-9.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8f1b9e7a5a00f8098e0632d8bc32fbf1abbc67d4abdb5e8c0e4b56ddd9ee2eae",
                "md5": "8e837d5e487955304b666dbeca4ace05",
                "sha256": "c5dce6e0b1bf5b9ce26176976c239f41b65866f6945228779568642f35aa7947"
            },
            "downloads": -1,
            "filename": "plone.testing-9.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "8e837d5e487955304b666dbeca4ace05",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 161752,
            "upload_time": "2023-11-30T19:31:19",
            "upload_time_iso_8601": "2023-11-30T19:31:19.007855Z",
            "url": "https://files.pythonhosted.org/packages/8f/1b/9e7a5a00f8098e0632d8bc32fbf1abbc67d4abdb5e8c0e4b56ddd9ee2eae/plone.testing-9.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-30 19:31:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "plone",
    "github_project": "plone.testing",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "plone.testing"
}
        
Elapsed time: 0.16693s