テストクライアントの話

Djangodjango.test.Client(django.test.client.Client)の話をid:Voluntasから振られたので書く。
IPアドレスCookieを設定する方法は、MiCHiLUさんが書いてました。
http://michilu.com/blog/posts/56/
テストクライアントのソースを読むと実装は結構よくできていました。
Client.getやClient.postはClient.requestを実行しています。Client.requestがClientはWSGIのハンドラを実行しています。
client.pyよりソースを抜粋。

    def get(self, path, data={}, **extra):
        """
        Requests a response from the server using GET.
        """
        r = {
            'CONTENT_LENGTH':  None,
            'CONTENT_TYPE':    'text/html; charset=utf-8',
            'PATH_INFO':       urllib.unquote(path),
            'QUERY_STRING':    urlencode(data, doseq=True),
            'REQUEST_METHOD': 'GET',
        }
        r.update(extra)

        return self.request(**r)

Client.requestの引数はenviron辞書です。この実装によるとextraで辞書を更新しているので、たとえばPUTやDELETEといったメソッドもClient.getやClient.postで実行することができます。

client.post('/foo/', REQUEST_METHOD='PUT')

私はHTTPについてあまり詳しくないので、PUTメソッドのパラメータがPOSTと同じでいいのかなど怪しいですが、クライアント側はこれでPUTとしてリクエストを出します。この方法はきれいじゃないので、Clientを継承してPUTやDELETEメソッドを実装したほうがいいと思います。
しかしながら、DjangoはPUT/DELETEを今のところサポートしていないので、実際にPUT/DELETEに対応するアプリを作るならDjango本体に手を加える必要があります。
http://humming.via-kitchen.com/2007/11/26/tried-put-and-delete-on-django/
アタックを一通り実装したテストクライアントなんかがあっても面白いかもしれませんな。