{"id":22194557,"url":"https://github.com/lugensa/gocept.httpserverlayer","last_synced_at":"2025-03-24T21:28:07.250Z","repository":{"id":37940344,"uuid":"204642016","full_name":"lugensa/gocept.httpserverlayer","owner":"lugensa","description":"This package provides an HTTP server for testing your application with normal HTTP clients (e.g. a real browser). This is done using `test layers`, which are a feature of `zope.testrunner`.","archived":false,"fork":false,"pushed_at":"2023-10-09T06:30:08.000Z","size":644,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-01T12:19:49.513Z","etag":null,"topics":["http","python","testing","testrunner"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lugensa.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-08-27T07:07:16.000Z","updated_at":"2023-12-11T14:57:12.000Z","dependencies_parsed_at":"2023-12-11T11:10:55.583Z","dependency_job_id":null,"html_url":"https://github.com/lugensa/gocept.httpserverlayer","commit_stats":{"total_commits":187,"total_committers":9,"mean_commits":20.77777777777778,"dds":0.6737967914438503,"last_synced_commit":"b324725ed7dd26457a1753961e118e64ee9a4f26"},"previous_names":["gocept/gocept.httpserverlayer"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lugensa%2Fgocept.httpserverlayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lugensa%2Fgocept.httpserverlayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lugensa%2Fgocept.httpserverlayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lugensa%2Fgocept.httpserverlayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lugensa","download_url":"https://codeload.github.com/lugensa/gocept.httpserverlayer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245354284,"owners_count":20601516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","python","testing","testrunner"],"created_at":"2024-12-02T13:13:25.058Z","updated_at":"2025-03-24T21:28:07.216Z","avatar_url":"https://github.com/lugensa.png","language":"Python","readme":"======================\ngocept.httpserverlayer\n======================\n\nThis package provides an HTTP server for testing your application with normal\nHTTP clients (e.g. a real browser). This is done using `test layers`_, which\nare a feature of `zope.testrunner`_.\n\ngocept.httpserverlayer uses `plone.testing`_ for the test layer implementation,\nand exposes the following resources (accessible in your test case as\n``self.layer[RESOURCE_NAME]``):\n\n:http_host: The hostname of the HTTP server (Default: localhost)\n:http_port: The port of the HTTP server (Default: 0, which means chosen\n            automatically by the operating system)\n:http_address: ``hostname:port``, convenient to use in URLs\n   (e.g. ``'http://user:password@%s/path' % self.layer['http_address']``)\n\nThis package is compatible with Python version 3.6, 3.7, 3.8, and 3.9.\n\n.. _`test layers`: https://pypi.org/project/plone.testing/#layers\n.. _`zope.testrunner`: https://pypi.org/project/zope.testrunner/\n.. _`plone.testing`: https://pypi.org/project/plone.testing/\n\n.. contents::\n\n\nWSGI\n====\n\nThis test layer takes a WSGI callable and runs it in a temporary HTTP server::\n\n    import gocept.httpserverlayer.wsgi\n    from mypackage import App\n    import unittest\n\n    HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer()\n    HTTP_LAYER.wsgi_app = App()\n\n    class WSGIExample(unittest.TestCase):\n\n        layer = HTTP_LAYER\n\n        def test_something(self):\n            r = urllib.urlopen('http://{0.layer[http_address]}/'.format(self))\n            self.assertIn('Hello world', r.read())\n\nYou can also have a base layer provide the WSGI callable (in the\n``wsgi_app`` resource)::\n\n\n    import gocept.httpserverlayer.wsgi\n    from mypackage import App\n    import plone.testing\n\n    class WSGILayer(plone.testing.Layer):\n\n        def setUp(self):\n            self['wsgi_app'] = App()\n\n    WSGI_LAYER = WSGILayer()\n\n    HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer(\n        name='HTTPLayer', bases=(WSGI_LAYER,))\n\n\nStatic files\n============\n\nThis test layer serves up the contents of a directory::\n\n    import gocept.httpserverlayer.static\n    import pkg_resources\n    import unittest\n\n    HTTP_LAYER = gocept.httpserverlayer.static.Layer(\n        pkg_resources.resource_filename('my.package.tests', 'fixtures'))\n\n    class DirecoryExample(unittest.TestCase):\n\n        layer = HTTP_LAYER\n\n        def test_something(self):\n            r = urllib.urlopen('http://{0.layer[http_address]}/'.format(self))\n            self.assertIn('Hello world', r.read())\n\nIf you don't pass in a directory, a temporary directory will be created/removed\nautomatically. The directory is provided in the ``documentroot`` resource.\nFor convenience, a layer instance is already provided as ``STATIC_FILES``::\n\n    import gocept.httpserverlayer.static\n    import os.path\n    import unittest\n\n    HTTP_LAYER = gocept.httpserverlayer.static.STATIC_FILES\n\n    class TemporaryExample(unittest.TestCase):\n\n        layer = HTTP_LAYER\n\n        def test_something(self):\n            path = os.path.join(self.testlayer['documentroot'], 'index')\n            with open(path, 'w') as f:\n                f.write('Hello World!')\n            r = urllib.urlopen(\n                'http://{0.layer[http_address]}/index'.format(self))\n            self.assertIn('Hello world', r.read())\n\n\nCustom request handler\n======================\n\nThis test layer allows you to provide your own HTTP request handler for very\nfine-grained control::\n\n    import gocept.httpserverlayer.custom\n    import unittest\n\n    class RequestHandler(gocept.httpserverlayer.custom.RequestHandler):\n\n        response_code = 200\n        response_body = ''\n        posts_received = []\n\n        def do_POST(self):\n            length = int(self.headers['content-length'])\n            self.posts_received.append(dict(\n                path=self.path,\n                data=self.rfile.read(length),\n                headers=self.headers,\n            ))\n            self.send_response(self.response_code)\n            self.end_headers()\n            self.wfile.write(self.response_body)\n\n    HTTP_LAYER = gocept.httpserverlayer.custom.Layer(RequestHandler)\n\n    class POSTExample(unittest.TestCase):\n\n        layer = HTTP_LAYER\n\n        def test_something(self):\n            urllib.urlopen('http://{0.layer[http_address]}/'.format(self),\n                           urllib.urlencode({'foo': 'bar'}))\n            self.assertEqual(\n                'foo=bar',\n                self.layer['request_handler'].posts_received[0]['data'])\n\n\nFramework integration\n=====================\n\ngocept.httpserverlayer also provides integration with some web frameworks.\nDifferent frameworks require different dependencies; this is handled via\nsetuptools extras of gocept.httpserverlayer (e.g. for Grok integration you need\nto require ``gocept.httpserverlayer[zopeappwsgi]``).\n\n\nZope 3 / ZTK / Grok (zope.app.wsgi)\n===================================\n\nRequires ``gocept.httpserverlayer[zopeappwsgi]``\n\nIf your ZTK application uses ``zope.app.wsgi.testlayer`` (which is the\nrecommended test setup for Grok, for example), you can use\n``gocept.httpserverlayer.zopeappwsgi.Layer`` to create a WSGI app that\nintegrates ZODB isolation, and ``gocept.httpserverlayer.wsgi.Layer`` to provide\nthe actual HTTP server. No special TestCase is required, ``unittest.TestCase``\nis enough.\n\nThe ``zopeappwsgi.Layer`` expects to find the current ZODB in the plone.testing\nresource ``zodbDB`` (which is used by ``plone.testing.zodb.EMPTY_ZODB``), or\nyou can inherit and override ``get_current_zodb``. Here's an example setup for\nGrok (which uses ``zope.app.appsetup.testlayer.ZODBLayer``)::\n\n    import gocept.httpserverlayer.wsgi\n    import gocept.httpserverlayer.zopeappwsgi\n    import unittest\n    import zope.app.appsetup.testlayer\n\n    ZODB_LAYER = zope.app.appsetup.testlayer.ZODBLayer(\n        gocept.httpserverlayer.zopeappwsgi, 'testing.zcml')\n\n    class WSGILayer(gocept.httpserverlayer.zopeappwsgi.Layer):\n\n        defaultBases = (ZODB_LAYER,)\n\n        def get_current_zodb(self):\n            return ZODB_LAYER.db\n\n    WSGI_LAYER = WSGILayer()\n\n    HTTP_LAYER = gocept.httpserverlayer.wsgi.Layer(\n        name='HTTPLayer', bases=(WSGI_LAYER,))\n\n    class GrokExample(unittest.TestCase):\n\n        layer = HTTP_LAYER\n\n        def test(self):\n            r = urllib.urlopen('http://%s/' % self.layer['http_address'])\n            self.assertIn('Hello world', r.read())\n\n\nZope via WSGI\n=============\n\nIf your Zope setup supports WSGI, you can use the WSGI integration instead of a\nspecialised Zope integration to run your tests.\n\nYou might see an exception complaining about the ``Connection`` header.\nTo fix this issue you can use an additional middleware around your WSGI\napplication: ``gocept.httpserverlayer.wsgi.FixupMiddleware``.\n\n\nZope / Plone via `plone.testing.zope`\n=====================================\n\nRequires ``gocept.httpserverlayer[plonetestingzope]``.\n\ngocept.httpserverlayer provides a ``plone.testing.Layer`` at\n``gocept.httpserverlayer.plonetestingzope.HTTP_SERVER`` that you can mix and match\nwith your base layers. No special TestCase is required, ``unittest.TestCase``\nis enough.\n\n.. caution:: This setup also uses the WSGI flavour instead of ZServer which\n             was supported in `gocept.httpserverlayer \u003c 3`.\n\nFor a plain Zope application this might look like this (uses\n``plone.testing[zope]``)::\n\n    import gocept.httpserverlayer.plonetestingzope\n    import plone.testing\n    import plone.testing.zope\n\n    class Layer(plone.testing.Layer):\n\n        defaultBases = (plone.testing.zope.STARTUP,)\n\n        def setUp(self):\n            zope.configuration.xmlconfig.file(\n                'testing.zcml', package=mypackage,\n                context=self['configurationContext'])\n\n    ZOPE_LAYER = Layer()\n\n    HTTP_LAYER = plone.testing.Layer(\n        name='HTTPLayer',\n        bases=(ZOPE_LAYER,\n               gocept.httpserverlayer.plonetestingzope.HTTP_SERVER))\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flugensa%2Fgocept.httpserverlayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flugensa%2Fgocept.httpserverlayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flugensa%2Fgocept.httpserverlayer/lists"}