Home:ALL Converter>Unittesting cherrypy webapp

Unittesting cherrypy webapp

Ask Time:2013-01-10T22:25:25         Author:Blubber

Json Formatter

I recently had to rewrite our rest api, and made the switch from Flask to Cherrypy (mostly due to Python 3 compatibility). But now I'm stuck trying to write my unit tests, Flask has a really nifty built-in test client, that you can use to sent fake requests to your application (without starting a server.) I can't find any similar functionality for Cherrypy, is there such functionality, or am I stuck starting a server and doing actual requests against it?

Author:Blubber,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/14260101/unittesting-cherrypy-webapp
Sylvain Hellegouarch :

As far as I know, CherryPy doesn't indeed provide a facility for this type of testing (no running server). But it's fairly easy to do it nonetheless (though it relies on some of the internals of CherryPy).\n\nHere's a simple showcase:\n\nfrom StringIO import StringIO\nimport unittest\nimport urllib\n\nimport cherrypy\n\nlocal = cherrypy.lib.httputil.Host('127.0.0.1', 50000, \"\")\nremote = cherrypy.lib.httputil.Host('127.0.0.1', 50001, \"\")\n\nclass Root(object):\n @cherrypy.expose\n def index(self):\n return \"hello world\"\n\n @cherrypy.expose\n def echo(self, msg):\n return msg\n\ndef setUpModule():\n cherrypy.config.update({'environment': \"test_suite\"})\n\n # prevent the HTTP server from ever starting\n cherrypy.server.unsubscribe()\n\n cherrypy.tree.mount(Root(), '/')\n cherrypy.engine.start()\nsetup_module = setUpModule\n\ndef tearDownModule():\n cherrypy.engine.exit()\nteardown_module = tearDownModule\n\nclass BaseCherryPyTestCase(unittest.TestCase):\n def webapp_request(self, path='/', method='GET', **kwargs):\n headers = [('Host', '127.0.0.1')]\n qs = fd = None\n\n if method in ['POST', 'PUT']:\n qs = urllib.urlencode(kwargs)\n headers.append(('content-type', 'application/x-www-form-urlencoded'))\n headers.append(('content-length', '%d' % len(qs)))\n fd = StringIO(qs)\n qs = None\n elif kwargs:\n qs = urllib.urlencode(kwargs)\n\n # Get our application and run the request against it\n app = cherrypy.tree.apps['']\n # Let's fake the local and remote addresses\n # Let's also use a non-secure scheme: 'http'\n request, response = app.get_serving(local, remote, 'http', 'HTTP/1.1')\n try:\n response = request.run(method, path, qs, 'HTTP/1.1', headers, fd)\n finally:\n if fd:\n fd.close()\n fd = None\n\n if response.output_status.startswith('500'):\n print response.body\n raise AssertionError(\"Unexpected error\")\n\n # collapse the response into a bytestring\n response.collapse_body()\n return response\n\nclass TestCherryPyApp(BaseCherryPyTestCase):\n def test_index(self):\n response = self.webapp_request('/')\n self.assertEqual(response.output_status, '200 OK')\n # response body is wrapped into a list internally by CherryPy\n self.assertEqual(response.body, ['hello world'])\n\n def test_echo(self):\n response = self.webapp_request('/echo', msg=\"hey there\")\n self.assertEqual(response.output_status, '200 OK')\n self.assertEqual(response.body, [\"hey there\"])\n\n response = self.webapp_request('/echo', method='POST', msg=\"hey there\")\n self.assertEqual(response.output_status, '200 OK')\n self.assertEqual(response.body, [\"hey there\"])\n\nif __name__ == '__main__':\n unittest.main()\n\n\nEdit, I've extended this answer as a CherryPy recipe.",
2013-01-10T15:13:57
VGE :

It seems that there is an alternate way to perform unittest.\nI just found and check the following recipe which works fine with cherrypy 3.5.\n\nhttp://docs.cherrypy.org/en/latest/advanced.html#testing-your-application\n\n import cherrypy\n\n from cherrypy.test import helper\n\n class SimpleCPTest(helper.CPWebCase):\n def setup_server():\n class Root(object):\n @cherrypy.expose\n def echo(self, message):\n return message\n\n cherrypy.tree.mount(Root())\n setup_server = staticmethod(setup_server)\n\n def test_message_should_be_returned_as_is(self):\n self.getPage(\"/echo?message=Hello%20world\")\n self.assertStatus('200 OK')\n self.assertHeader('Content-Type', 'text/html;charset=utf-8')\n self.assertBody('Hello world')\n\n def test_non_utf8_message_will_fail(self):\n \"\"\"\n CherryPy defaults to decode the query-string\n using UTF-8, trying to send a query-string with\n a different encoding will raise a 404 since\n it considers it's a different URL.\n \"\"\"\n self.getPage(\"/echo?message=A+bient%F4t\",\n headers=[\n ('Accept-Charset', 'ISO-8859-1,utf-8'),\n ('Content-Type', 'text/html;charset=ISO-8859-1')\n ]\n )\n self.assertStatus('404 Not Found')\n",
2015-11-22T11:23:29
yy