Quite often you want to unittest your application or just check the output from an interactive python session. In theory that is pretty simple because you can fake a WSGI environment and call the application with a dummy start_response and iterate over the application iterator but there are argumentably better ways to interact with an application.
Werkzeug provides an object called Client which you can pass a WSGI application (and optionally a response wrapper) which you can use to send virtual requests to the application.
A response wrapper is a callable that takes three arguments: the application iterator, the status and finally a list of headers. The default response wrapper returns a tuple. Because response objects have the same signature you can use them as response wrapper, ideally by subclassing them and hooking in test functionality.
>>> from werkzeug import Client, BaseResponse, test_app >>> c = Client(test_app, BaseResponse) >>> resp = c.get('/') >>> resp.status_code 200 >>> resp.headers Headers([('Content-Type', 'text/html; charset=utf-8')]) >>> resp.response_body.splitlines()[:2] ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"', ' "http://www.w3.org/TR/html4/loose.dtd">']
Or here without wrapper defined:
>>> from werkzeug import Client, test_app >>> c = Client(test_app) >>> app_iter, status, headers = c.get('/') >>> status '200 OK' >>> headers [('Content-Type', 'text/html; charset=utf-8')] >>> ''.join(app_iter).splitlines()[:2] ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"', ' "http://www.w3.org/TR/html4/loose.dtd">']
The following functions are available:
- open(path, base_url, query_string, **options)
Takes the same arguments as the create_environ function from the utility module with some additions.
The first parameter should be the path of the request which defaults to '/'. The second one can either be a absolute path (in that case the url host is localhost:80) or a full path to the request with scheme, netloc port and the path to the script.
If the path contains a query string it will be used, even if the query_string parameter was given. If it does not contain one the query_string parameter is used as querystring. In that case it can either be a dict, MultiDict or string.
The following options exist:
- The request method. Defaults to GET
- The input stream. Defaults to an empty read only stream.
The data you want to transmit. You can set this to a string and define a content type instead of specifying an input stream. Additionally you can pass a dict with the form data. The values could then be strings (no unicode objects!) which are then url encoded or file objects.
A file object for this method is either a file descriptor with an additional name attribute (like a file descriptor returned by the open / file function), a tuple in the form (fd, filename, mimetype) (all arguments except fd optional) or as dict with those keys and values.
Additionally you can instanciate the werkzeug.test.File object (or a subclass of it) and pass it as value.
- The content type for this request. Default is an empty content type.
- The value for the content length header. Defaults to 0.
- The wsgi.errors stream. Defaults to sys.stderr.
- The multithreaded flag for the WSGI Environment. Defaults to False.
- The multiprocess flag for the WSGI Environment. Defaults to False.
- The run_once flag for the WSGI Environment. Defaults to False.
- Like open() but enforces GET as method.
- Like open() but enforces POST as method.
- Like open() but enforces HEAD as method.
- Like open() but enforces PUT as method.
- Like open() but enforces DELETE as method.