Fork me on GitHub

Testing Twisted Web Resources

Posted 20 Feb 2012 to python, twisted and has Comments

Testing web resources in Twisted can be a bit of a pain, and the Twisted docs don’t describe how best go go about writing tests for twisted.web.resource.Resource objects.

Generally, usage of twisted.web resources looks something like this:

from twisted.internet.defer import inlineCallbacks
from twisted.internet import defer, reactor
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET

class ChildPage(resource.Resource):
    def render(self, request):
        d = defer.Deferred()
        d.addCallback(self.renderResult, request)
        reactor.callLater(1, d.callback, "hello")
        return NOT_DONE_YET

    def renderResult(self, result, request):
        request.write(result)
        request.finish()
        
class MainPage(resource.Resource):
    def __init__(self):
        resource.Resource.__init__(self)
        self.putChild('childpage', ChildPage())

I created a small bit of code that wraps some of the testing library in Twisted. This code can be used to easily create tests by just using a DummySite instead of a twisted.web.server.Site. You can then call get and post on that site (and pass optional dictionaries of get/post arguments and headers). Here’s what a test looks like:

from twisted.trial import unittest
from twisted_web_test_utils import DummySite

class WebTest(unittest.TestCase):
    def setUp(self):
        self.web = DummySite(MainPage())

    @inlineCallbacks
    def test_get(self):
        response = yield self.web.get("childpage")
        self.assertEqual(response.value(), "hello")

	# if you have params / headers:
	response = yield self.web.get("childpage", {'paramone': 'value'}, {'referer': "http://somesite.com"})

Here’s the testing code if you want to use it:

And with that, a few hours worth of work will save me at least a few 10 minute segments in the future.