Как протестировать витой веб-ресурс с пробной? - PullRequest
9 голосов
/ 06 марта 2011

Я разрабатываю сервер twisted.web - он состоит из нескольких ресурсов, которые помимо рендеринга используют adbapi для извлечения некоторых данных и записи некоторых данных в базу данных postgresql.Я пытаюсь выяснить, как написать пробный юнит-тест, который бы тестировал рендеринг ресурса без использования net (другими словами: это инициализировало бы ресурс, создавало бы его фиктивный запрос и т. Д.).

Предположим, что ресурс View является простым листом, который в render_GET возвращает NOT_DONE_YET и работает с adbapi для получения простого текста.Теперь я написал этот бесполезный код и не могу придумать, как заставить его фактически инициализировать ресурс и дать какой-то разумный ответ:

from twisted.trial import unittest
from myserv.views import View
from twisted.web.test.test_web import DummyRequest

class ExistingView(unittest.TestCase):
    def test_rendering(self):
        slug = "hello_world"
        view = View(slug)
        request = DummyRequest([''])
        output = view.render_GET(request)
        self.assertEqual(request.responseCode, 200)

Вывод ... 1. Я имеюи попробовал такой подход: output = request.render (view) но такой же output = 1. Почему?Я был бы очень благодарен за какой-то пример как написать такой юнит-тест!

Ответы [ 2 ]

10 голосов
/ 06 марта 2011

Вот функция, которая будет обрабатывать запрос и преобразовывать результат в отложенный, который срабатывает после завершения рендеринга:

def _render(resource, request):
    result = resource.render(request)
    if isinstance(result, str):
        request.write(result)
        request.finish()
        return succeed(None)
    elif result is server.NOT_DONE_YET:
        if request.finished:
            return succeed(None)
        else:
            return request.notifyFinish()
    else:
        raise ValueError("Unexpected return value: %r" % (result,))

На самом деле он используется в тестовом наборе Twisted Web, но он закрытый, потому что сам не имеет модульных тестов. ;)

Вы можете использовать его, чтобы написать такой тест:

def test_rendering(self):
    slug = "hello_world"
    view = View(slug)
    request = DummyRequest([''])
    d = _render(view, request)
    def rendered(ignored):
        self.assertEquals(request.responseCode, 200)
        self.assertEquals("".join(request.written), "...")
        ...
    d.addCallback(rendered)
    return d
0 голосов
/ 07 марта 2011

Вот класс DummierRequest, который исправляет почти все мои проблемы. Осталось только , код ответа не устанавливается ! Почему?

from twisted.web.test.test_web import DummyRequest
from twisted.web import server
from twisted.internet.defer import succeed
from twisted.internet import interfaces, reactor, protocol, address
from twisted.web.http_headers import _DictHeaders, Headers

class DummierRequest(DummyRequest):
    def __init__(self, postpath, session=None):
        DummyRequest.__init__(self, postpath, session)
        self.notifications = []
        self.received_cookies = {}
        self.requestHeaders = Headers()
        self.responseHeaders = Headers()
        self.cookies = [] # outgoing cookies

    def setHost(self, host, port, ssl=0):
        self._forceSSL = ssl
        self.requestHeaders.setRawHeaders("host", [host])
        self.host = address.IPv4Address("TCP", host, port)

    def addCookie(self, k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None):
        """
        Set an outgoing HTTP cookie.

        In general, you should consider using sessions instead of cookies, see
        L{twisted.web.server.Request.getSession} and the
        L{twisted.web.server.Session} class for details.
        """
        cookie = '%s=%s' % (k, v)
        if expires is not None:
            cookie = cookie +"; Expires=%s" % expires
        if domain is not None:
            cookie = cookie +"; Domain=%s" % domain
        if path is not None:
            cookie = cookie +"; Path=%s" % path
        if max_age is not None:
            cookie = cookie +"; Max-Age=%s" % max_age
        if comment is not None:
            cookie = cookie +"; Comment=%s" % comment
        if secure:
            cookie = cookie +"; Secure"
        self.cookies.append(cookie)

    def getCookie(self, key):
        """
        Get a cookie that was sent from the network.
        """
        return self.received_cookies.get(key)

    def getClientIP(self):
        """
        Return the IPv4 address of the client which made this request, if there
        is one, otherwise C{None}.
        """
        return "192.168.1.199"
...