One of the particularly useful aspects of having a standard interface to Python Web apps is that it lets you build standard test harnesses, too. I've done just that with twill, using wsgi_intercept, a library which lets you "mock" the network interface so that you can run and test WSGI apps in-process.
For example, this code:
#! /usr/bin/env python import twill def simple_app(environ, start_response): status = '200 OK' response_headers = [('Content-type','text/plain')] start_response(status, response_headers) return ['Hello world!\n'] if __name__ == '__main__': print '*** installing WSGI intercept hook ***\n' twill.add_wsgi_intercept('localhost', 80, lambda: simple_app) twill.shell.main()
lets you browse a Web app directly:
% ./twill-wsgi-example.py -u http://localhost:80/ *** installing WSGI intercept hook *** ==> at http://localhost:80/ -= Welcome to twill! =- current page: http://localhost:80/ >> show Hello world!
or run a script, for example this script, hello-test.twill,
code 200 find Hello
produces this output:
% ./twill-wsgi-example.py -u http://localhost:80/ hello-test.twill *** installing WSGI intercept hook *** >> EXECUTING FILE hello-test.twill ==> at http://localhost:80 -- 1 of 1 files SUCCEEDED.
You should even be able to put twill commands into doctests:
def simple_app(environ, start_response): """ It may even be possible to use wsgi_intercept with doctest. For example, >>> twill.add_wsgi_intercept('localhost', 80, lambda: simple_app) >>> go("http://localhost:80/") ==> at http://localhost:80/ >>> show() Hello world! Unfortunately this doesn't actually work, for reasons that I'm sure Grig will solve. """ status = '200 OK' response_headers = [('Content-type','text/plain')] start_response(status, response_headers) return ['Hello world!\n']
Now tell me that wouldn't be neat! (Unfortunately it doesn't work just yet, but I'll figure that out...)