Source code for zope.pytest.setup
import os
from zope.configuration import xmlconfig, config
from zope.component.hooks import setHooks
from zope.testing.cleanup import cleanUp
from zope import component
from zope.event import notify
from zope.app.publication.zopepublication import ZopePublication
from zope.app.publication.httpfactory import HTTPPublicationRequestFactory
import zope.processlifetime
from zope.app import wsgi
from ZODB.DB import DB
from ZODB.DemoStorage import DemoStorage
import ZODB.interfaces
import transaction
[docs]def create_app(request, site_root):
"""Get a WSGI publisher application.
Returns a :class:`zope.app.wsgi.WSGIPublisherApplication` with
`site_root` stored in the root folder under the name ``test``.
This function is meant to be used as setup/teardown handler
deploying a `pytest_funcarg__`_ function.
It sets up a ZODB_ connection to a ZODB_ DemoStorage and adds
finalizers (`tear_down`-functionality for people from other
testing frameworks) to shutdown the whole setup after the test
session.
The `request` parameter is expected to be a py.test
:class:`FuncargRequest` (not an HTTP request or similar) which is
generated by py.test while running tests.
The :attr:`handle_errors` attribute of the returned application is
set to ``False`` so that errors are handled by the server.
To make use of this setup, you have to configure the environment
properly before. Most notably you have to register basic
components that subscribe to IDatabaseOpenedEvents, etc. This can
normally be done using :func:`configure` or :func:`setup_config`.
.. seealso:: `pytest_funcarg__`_ docs on pytest.org.
.. _pytest_funcarg__: http://pytest.org/funcargs.html
"""
db = setup_db()
connection = setup_connection(db)
root = setup_root(connection)
root['test'] = site_root
wsgi_app = wsgi.WSGIPublisherApplication(
db,
HTTPPublicationRequestFactory,
True)
transaction.commit()
def finalize():
teardown_root(root)
teardown_connection(connection)
teardown_db(db)
request.addfinalizer(finalize)
# turn this off to let the errors be handled by the server
# this is useful for testing the server's error handling
wsgi_app.handleErrors = False
return wsgi_app
[docs]def setup_config(package, zcml_file):
"""Setup a configuration.
Execute the configuration specified by `package` and `zcml_file`.
`package`
is a Python package in which the `zcml_file` is looked up.
`zcml_file`
is a string giving the name of a ZCML_ file to parse.
This is a helper function used by :func:`configure`. You normally
use :func:`configure` to setup tests.
The function registers the most common directives and then tries
to parse the and execute the configuration as given in the ZCML_
file.
Returns the resulting ZCML_ configuration.
"""
zcml_file = os.path.join(os.path.dirname(package.__file__),
zcml_file)
setHooks()
context = config.ConfigurationMachine()
xmlconfig.registerCommonDirectives(context)
return xmlconfig.file(zcml_file,
package=package,
context=context, execute=True)
[docs]def teardown_config(config):
"""Clean up a ZCML configuration.
Unregisters components registered.
"""
cleanUp()
[docs]def setup_db():
"""Create a ZODB_ DB with a demo storage.
Creates a ZODB :class:`DemoStorage`, turns it into a ZODB_ DB
named ``main`` and sends a :class:`DatebaseOpened` event to inform
other components.
You normally have to configure the Zope Component Architechture
using :func:`setup_config` or (preferably) :func:`configure`
before you call this function.
Returns a ZODB DB.
"""
name = 'main'
storage = DemoStorage(name)
db = DB(storage, database_name=name)
db.setActivityMonitor(ZODB.ActivityMonitor.ActivityMonitor())
# DB are registered as utilities
component.provideUtility(db, ZODB.interfaces.IDatabase, name)
# And we send a event that our DB is available
notify(zope.processlifetime.DatabaseOpened(db))
return db
[docs]def teardown_db(db):
"""Unregister ZODB_ DB.
Unregisters the ``main`` database with the global site manager and
closes the DB.
"""
# Need to unregister DB
base = component.getGlobalSiteManager()
base.unregisterUtility(
db, ZODB.interfaces.IDatabase, 'main')
db.close()
[docs]def setup_connection(db):
"""Open a connection to `db`.
`db`
is a ZODB_ DB as returned from :func:`setup_db`.
Returns a connection to the database.
"""
return db.open()
[docs]def teardown_connection(connection):
"""Shutdown ZODB_ DB connection.
`connection`
is a (normally open) ZODB_ DB connection as returned by
:func:`setup_connection`.
Aborts any running transaction and closes the connection.
"""
transaction.abort()
connection.close()
[docs]def setup_root(connection):
"""Get the application root.
Returns the Zope application root from a ZODB DB connected to by
`connection`.
`connection`
is an (already opened) connection to a ZODB_ DB.
Return the application root, i.e. the object that contains the
global site manager and other fundamental ZCA-related stuff.
"""
return connection.root()[ZopePublication.root_name]
[docs]def teardown_root(root):
"""Shutdown the application root.
`root`
is a ZODB_ DB application root.
This function does actually nothing.
"""
pass