Package: gocept.httpserverlayer
gocept.httpserverlayerThis package provides an HTTP server for testing your application with normal
HTTP clients (e.g. a real browser). This is done usingtest layers, which
are a feature ofzope.testrunner.gocept.httpserverlayer usesplone.testingfor the test layer implementation,
and exposes the following resources (accessible in your test case asself.layer[RESOURCE_NAME]):http_host:The hostname of the HTTP server (Default: localhost)http_port:The port of the HTTP server (Default: 0, which means chosen
automatically by the operating system)http_address:hostname:port, convenient to use in URLs
(e.g.'http://user:password@%s/path'%self.layer['http_address'])This package is compatible with Python version 3.6, 3.7, 3.8, and 3.9.Contentsgocept.httpserverlayerWSGIStatic filesCustom request handlerFramework integrationZope 3 / ZTK / Grok (zope.app.wsgi)Zope via WSGIZope / Plone viaplone.testing.zopeDeveloping gocept.httpserverlayerChange log for gocept.httpserverlayer4.0 (2021-04-07)3.2 (2019-04-03)3.1 (2019-01-15)3.0 (2018-06-29)2.2 (2016-12-02)2.1 (2016-12-01)2.0 (2016-04-12)1.5.3 (2015-01-09)1.5.2 (2014-05-22)1.5.1 (2014-02-10)1.5.0 (2013-11-07)1.4.1 (2013-10-01)1.4.0 (2013-10-01)1.3.0 (2013-07-18)1.2.1 (2013-02-07)1.2 (2013-02-06)1.1 (2013-02-03)1.0.1 (2012-12-21)1.0 (2012-12-19)WSGIThis test layer takes a WSGI callable and runs it in a temporary HTTP server:import gocept.httpserverlayer.wsgi
from mypackage import App
import unittest

HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer()
HTTP_LAYER.wsgi_app = App()

class WSGIExample(unittest.TestCase):

    layer = HTTP_LAYER

    def test_something(self):
        r = urllib.urlopen('http://{0.layer[http_address]}/'.format(self))
        self.assertIn('Hello world', r.read())You can also have a base layer provide the WSGI callable (in thewsgi_appresource):import gocept.httpserverlayer.wsgi
from mypackage import App
import plone.testing

class WSGILayer(plone.testing.Layer):

    def setUp(self):
        self['wsgi_app'] = App()

WSGI_LAYER = WSGILayer()

HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer(
    name='HTTPLayer', bases=(WSGI_LAYER,))Static filesThis test layer serves up the contents of a directory:import gocept.httpserverlayer.static
import pkg_resources
import unittest

HTTP_LAYER = gocept.httpserverlayer.static.Layer(
    pkg_resources.resource_filename('my.package.tests', 'fixtures'))

class DirecoryExample(unittest.TestCase):

    layer = HTTP_LAYER

    def test_something(self):
        r = urllib.urlopen('http://{0.layer[http_address]}/'.format(self))
        self.assertIn('Hello world', r.read())If you don’t pass in a directory, a temporary directory will be created/removed
automatically. The directory is provided in thedocumentrootresource.
For convenience, a layer instance is already provided asSTATIC_FILES:import gocept.httpserverlayer.static
import os.path
import unittest

HTTP_LAYER = gocept.httpserverlayer.static.STATIC_FILES

class TemporaryExample(unittest.TestCase):

    layer = HTTP_LAYER

    def test_something(self):
        path = os.path.join(self.testlayer['documentroot'], 'index')
        with open(path, 'w') as f:
            f.write('Hello World!')
        r = urllib.urlopen(
            'http://{0.layer[http_address]}/index'.format(self))
        self.assertIn('Hello world', r.read())Custom request handlerThis test layer allows you to provide your own HTTP request handler for very
fine-grained control:import gocept.httpserverlayer.custom
import unittest

class RequestHandler(gocept.httpserverlayer.custom.RequestHandler):

    response_code = 200
    response_body = ''
    posts_received = []

    def do_POST(self):
        length = int(self.headers['content-length'])
        self.posts_received.append(dict(
            path=self.path,
            data=self.rfile.read(length),
            headers=self.headers,
        ))
        self.send_response(self.response_code)
        self.end_headers()
        self.wfile.write(self.response_body)

HTTP_LAYER = gocept.httpserverlayer.custom.Layer(RequestHandler)

class POSTExample(unittest.TestCase):

    layer = HTTP_LAYER

    def test_something(self):
        urllib.urlopen('http://{0.layer[http_address]}/'.format(self),
                       urllib.urlencode({'foo': 'bar'}))
        self.assertEqual(
            'foo=bar',
            self.layer['request_handler'].posts_received[0]['data'])Framework integrationgocept.httpserverlayer also provides integration with some web frameworks.
Different frameworks require different dependencies; this is handled via
setuptools extras of gocept.httpserverlayer (e.g. for Grok integration you need
to requiregocept.httpserverlayer[zopeappwsgi]).Zope 3 / ZTK / Grok (zope.app.wsgi)Requiresgocept.httpserverlayer[zopeappwsgi]If your ZTK application useszope.app.wsgi.testlayer(which is the
recommended test setup for Grok, for example), you can usegocept.httpserverlayer.zopeappwsgi.Layerto create a WSGI app that
integrates ZODB isolation, andgocept.httpserverlayer.wsgi.Layerto provide
the actual HTTP server. No special TestCase is required,unittest.TestCaseis enough.Thezopeappwsgi.Layerexpects to find the current ZODB in the plone.testing
resourcezodbDB(which is used byplone.testing.zodb.EMPTY_ZODB), or
you can inherit and overrideget_current_zodb. Here’s an example setup for
Grok (which useszope.app.appsetup.testlayer.ZODBLayer):import gocept.httpserverlayer.wsgi
import gocept.httpserverlayer.zopeappwsgi
import unittest
import zope.app.appsetup.testlayer

ZODB_LAYER = zope.app.appsetup.testlayer.ZODBLayer(
    gocept.httpserverlayer.zopeappwsgi, 'testing.zcml')

class WSGILayer(gocept.httpserverlayer.zopeappwsgi.Layer):

    defaultBases = (ZODB_LAYER,)

    def get_current_zodb(self):
        return ZODB_LAYER.db

WSGI_LAYER = WSGILayer()

HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer(
    name='HTTPLayer', bases=(WSGI_LAYER,))

class GrokExample(unittest.TestCase):

    layer = HTTP_LAYER

    def test(self):
        r = urllib.urlopen('http://%s/' % self.layer['http_address'])
        self.assertIn('Hello world', r.read())Zope via WSGIIf your Zope setup supports WSGI, you can use the WSGI integration instead of a
specialised Zope integration to run your tests.You might see an exception complaining about theConnectionheader.
To fix this issue you can use an additional middleware around your WSGI
application:gocept.httpserverlayer.wsgi.FixupMiddleware.Zope / Plone viaplone.testing.zopeRequiresgocept.httpserverlayer[plonetestingzope].gocept.httpserverlayer provides aplone.testing.Layeratgocept.httpserverlayer.plonetestingzope.HTTP_SERVERthat you can mix and match
with your base layers. No special TestCase is required,unittest.TestCaseis enough.Caution!This setup also uses the WSGI flavour instead of ZServer which
was supported ingocept.httpserverlayer < 3.For a plain Zope application this might look like this (usesplone.testing[zope]):import gocept.httpserverlayer.plonetestingzope
import plone.testing
import plone.testing.zope

class Layer(plone.testing.Layer):

    defaultBases = (plone.testing.zope.STARTUP,)

    def setUp(self):
        zope.configuration.xmlconfig.file(
            'testing.zcml', package=mypackage,
            context=self['configurationContext'])

ZOPE_LAYER = Layer()

HTTP_LAYER = plone.testing.Layer(
    name='HTTPLayer',
    bases=(ZOPE_LAYER,
           gocept.httpserverlayer.plonetestingzope.HTTP_SERVER))Developing gocept.httpserverlayerAuthor:gocept<mail@gocept.com>PyPI page:https://pypi.org/project/gocept.httpserverlayer/Issue tracker:https://github.com/gocept/gocept.httpserverlayer/issuesSource code:https://github.com/gocept/gocept.httpserverlayerCurrent change log:https://raw.githubusercontent.com/gocept/gocept.httpserverlayer/master/CHANGES.rstRun tests:Use tox, for info see:https://pypi.org/project/tox/Change log for gocept.httpserverlayer4.0 (2021-04-07)Drop support for Python 2.Add support for Python 3.8 and 3.9.Migrate to GitHub and GitHub Actions.3.2 (2019-04-03)Fix usage of pending deprecatedThread.isAlive().3.1 (2019-01-15)Create a wheel of the package.Add support for Python 3.7.3.0 (2018-06-29)Add support for Python 3.6.Drop support for Zope 2.xRename the setup.py extraplonetestingz2intoplonetestingzope.Rename the module.plonetestingz2into.plonetestingzope.2.2 (2016-12-02)Ensure compatibility withsetuptools >= 30.0.2.1 (2016-12-01)Support the upcoming Zope 4 through extras_require [plonetestingz4].Pintransaction < 2.0andZODB < 5.0untilZope2is compatible with
these releases. (Seehttps://github.com/zopefoundation/Zope/issues/79)2.0 (2016-04-12)Drop support for:zope.app.testing(extras_require: [zopeapptesting])Testing.ZopeTestCase(extras_require: [zope2testcase])plone.app.testing(extras_require: [test_plonetestingz2])Products.PloneTestCase(extras_require: [plonetestcase])Drop support for Python 2.6.Usetoxas testrunner.Removezc.buildoutinfrastructure.1.5.3 (2015-01-09)Don’t overwriteself.portwhen it was 0.1.5.2 (2014-05-22)Silence “error 32: Broken pipe” errors incustom.Layer, too.1.5.1 (2014-02-10)Silence “error 32: Broken pipe” errors inwsgi.Layer, they just
mean the client closed the connection prematurely, which is as
harmless as it is normal.1.5.0 (2013-11-07)Make it possible to dictate the hostname for the httpserver via environment
variableGOCEPT_HTTP_APP_HOST. You will need this if you run your tests
in a selenium grid on different machines.1.4.1 (2013-10-01)1.4.0 was a brown-bag, let’s try again.1.4.0 (2013-10-01)Make HTTP server and thread objects used by layers available as a resource.1.3.0 (2013-07-18)Replace dependency ondistributewithsetuptools, since the projects have merged.1.2.1 (2013-02-07)Fix custom layer test tear down.1.2 (2013-02-06)Fixed tests run on MacOS.Use theserver_addressinstead ofserver_nameofHTTPServerto be
compatible with MacOS.Dropped compatability with Zope < 2.12.Removed customizedHTTPServer, theBaseHTTPServer.HTTPServerdoes
everything we need.1.1 (2013-02-03)Addcustom.Layerthat uses a BaseHTTPServer with a custom RequestHandler,
andstatic.Layerthat server the contents of a directory.Dropped compatability with Python < 2.6.1.0.1 (2012-12-21)Avoid the property.setter spelling in the wsgi layer’s code for Python 2.5
compatibility.Conditionally require wsgiref to make the wsgi layer work with Python 2.4.Fixed an import in the plonetestcase layer’s tests.1.0 (2012-12-19)initial release (extracted from gocept.selenium-1.0)