Home | History | Annotate | Download | only in guide
      1 .. _guide.testing:
      2 
      3 Unit testing
      4 ============
      5 Thanks to `WebOb`_, webapp2 is very testable. Testing a handler is a matter
      6 of building a custom ``Request`` object and calling ``get_response()`` on it
      7 passing the WSGI application.
      8 
      9 Let's see an example. First define a simple 'Hello world' handler to be
     10 tested::
     11 
     12     import webapp2
     13 
     14     class HelloHandler(webapp2.RequestHandler):
     15         def get(self):
     16             self.response.write('Hello, world!')
     17 
     18     app = webapp2.WSGIapplication([('/', HelloHandler)])
     19 
     20     def main():
     21         app.run()
     22 
     23     if __name__ == '__main__':
     24         main()
     25 
     26 To test if this handler returns the correct ``'Hello, world!'`` response, we
     27 build a request object using ``Request.blank()`` and call ``get_response()``
     28 on it::
     29 
     30     import unittest
     31     import webapp2
     32 
     33     # from the app main.py
     34     import main
     35 
     36     class TestHandlers(unittest.TestCase):
     37        def test_hello(self):
     38            # Build a request object passing the URI path to be tested.
     39            # You can also pass headers, query arguments etc.
     40            request = webapp2.Request.blank('/')
     41            # Get a response for that request.
     42            response = request.get_response(main.app)
     43 
     44            # Let's check if the response is correct.
     45            self.assertEqual(response.status_int, 200)
     46            self.assertEqual(response.body, 'Hello, world!')
     47 
     48 To test different HTTP methods, just change the request object::
     49 
     50     request = webapp2.Request.blank('/')
     51     request.method = 'POST'
     52     response = request.get_response(main.app)
     53 
     54     # Our handler doesn't implement post(), so this response will have a
     55     # status code 405.
     56     self.assertEqual(response.status_int, 405)
     57 
     58 
     59 Request.blank()
     60 ---------------
     61 ``Request.blank(path, environ=None, base_url=None, headers=None, POST=None, **kwargs)``
     62 is a class method that creates a new request object for testing purposes. It
     63 receives the following parameters:
     64 
     65 path
     66   A URI path, urlencoded. The path will become path_info, with any query
     67   string split off and used.
     68 environ
     69   An environ dictionary.
     70 base_url
     71   If defined, wsgi.url_scheme, HTTP_HOST and SCRIPT_NAME will be filled in
     72   from this value.
     73 headers
     74   A list of ``(header_name, value)`` tuples for the request headers.
     75 POST
     76   A dictionary of POST data to be encoded, or a urlencoded string. This is a
     77   shortcut to set POST data in the environ. When set, the HTTP method is set
     78   to 'POST' and the CONTENT_TYPE is set to 'application/x-www-form-urlencoded'.
     79 kwargs
     80   Extra keyword arguments to be passed to ``Request.__init__()``.
     81 
     82 All necessary keys will be added to the environ, but the values you pass in
     83 will take precedence.
     84 
     85 
     86 app.get_response()
     87 ------------------
     88 We can also get a response directly from the WSGI application, calling
     89 ``app.get_response()``. This is a convenience to test the app. It receives
     90 the same parameters as ``Request.blank()`` to build a request and call the
     91 application, returning the resulting response::
     92 
     93     class HelloHandler(webapp2.RequestHandler):
     94         def get(self):
     95             self.response.write('Hello, world!')
     96 
     97     app = webapp2.WSGIapplication([('/', HelloHandler)])
     98 
     99     # Test the app, passing parameters to build a request.
    100     response = app.get_response('/')
    101     assert response.status_int == 200
    102     assert response.body == 'Hello, world!'
    103 
    104 Testing handlers could not be easier. Check the `WebOb`_ documentation for more
    105 information about the request and response objects.
    106 
    107 
    108 Testing App Engine services
    109 ---------------------------
    110 If you're using App Engine and need to test an application that uses Datastore,
    111 Memcache or other App Engine services, read
    112 `Local Unit Testing for Python <http://code.google.com/appengine/docs/python/tools/localunittesting.html>`_
    113 in the official documentation. The App Engine SDK provides the module
    114 ``google.appengine.ext.testbed`` that can be used to setup all the necessary
    115 service stubs for testing.
    116 
    117 
    118 .. _WebOb: http://docs.webob.org/
    119