XML-RPC dispatching through Django test client

Posted by Christian on Apr 02 2008, 17:37 CEST
Tagged with Python, Django

Django has a cleverly designed test client that creates a WSGIRequest and routes it through your views without the need of a web server. Furthermore it works on a temporary test database, thus any errors won't have any effect on your live database.

I'm currently working on an application written using Django. This application, amongst other features, has an XML-RPC interface. The tests for this interface was being done by spawning a local web server and carrying out the tests over the wire. However, it would be nice to exploit the Django test framework.

The solution is amazingly simple. I wrote a TestTransport class for xmlrpclib:

import cStringIO

from xmlrpclib import Transport

from django.test.client import Client

class TestTransport(Transport):

    """ Handles connections to XML-RPC server through Django test client."""

    def __init__(self, *args, **kwargs):

        self.client = Client()

    def request(self, host, handler, request_body, verbose=0):

        self.verbose = verbose

        response = self.client.post(handler,
                                    request_body,
                                    content_type="text/xml")

        res = cStringIO.StringIO(response.content)
        res.seek(0)

        return self.parse_response(res)

In my tests where I use the XML-RPC interface I initialize the ServerProxy object with:

server = ServerProxy('http://localhost/xmlrpc/', transport=TestTransport())

That's about it. Now calls trough the server object will be handled by the Django test client.

In my case I had a decorator around the view function handling XML-RPC requests checking the HTTP headers for authentication information and replying with a 401 error. I had to modify this to allow the test client access with no authentication (you may not need this, but I will show it as an example on how to know in your view that this is a test client request). Here is the relevant parts cut out:

def xmlrpc_authenticate(func):
...
    def inner(request, *args, **kwargs):
...
        if request.META.get('SERVER_NAME', '') == 'testserver':
            return func(request, *args, **kwargs)
...
    return inner

Comments for "XML-RPC dispatching through Django test client"

Currently disabled.