2008/03/21

Twill, CherryPy 3 and testing with internal servers

Twill can test CherryPy web servers "in process", without having to run them as servers. I've used twill this way with CherryPy 2, but when I recently tried to do the same thing with a CherryPy 3 server everything broke.

I had based my code on an old CherryPy 2 tutorial by Titus Brown, and was trying to grep through the CherryPy 3 code tree to figure out how to patch it up. Bad idea :)

Yesterday Google finally turned up a solution, from a talk Titus gave at PyCon 2007.

The upshot: don't use cherrypy._cpwsgi.CPWSGIApp. In CherryPy 3, your application itself is already a WSGIApp. What's more, I think cherrypy._cpwsgi.CPWSGIApp may be broken. For sure, it and twill have incompatible ideas about the correct type of the 2nd constructor argument.

Anyway, thanks to Titus, here's an example of how to connect twill to a CherryPy 3 application for in-process testing:

import twill
import cherrypy
...
wsgi_app = cherrypy.tree.mount(myApp, "/", myConfig)
cherrypy.engine.start(blocking=False)
twill.add_wsgi_intercept('localhost', 8080, lambda: wsgi_app)


[Update 2008/03/24] Ditched the cherrypy.server.quickstart() invocation, per fumanchu's comment. Reported as Ticket #801.

2 comments:

fumanchu said...

"For sure, it and twill have incompatible ideas about the correct type of the 2nd constructor argument."

It sure would be nice if someone would inform the CherryPy team about the specifics. http://www.cherrypy.org/newticket

"cherrypy.server.quickstart()"

This looks...odd. Why start the HTTP server listening on a socket when you're going to connect behind its back?

Mitch said...

"It sure would be nice if someone would inform the CherryPy team about the specifics."

Will do.

"""
"cherrypy.server.quickstart()"

This looks...odd. Why start the HTTP server listening on a socket when you're going to connect behind its back?
"""

Good point.