2011-03-06 11 views
9

मैं एक twisted.web सर्वर विकसित कर रहा हूं - इसमें कुछ संसाधन शामिल हैं जो प्रतिपादन सामग्री के अलावा कुछ डेटा लाने और पोस्टग्रेस्क्ल डेटाबेस में कुछ डेटा लिखने के लिए adbapi का उपयोग करते हैं। मैं यह समझने की कोशिश कर रहा हूं कि एक परीक्षण को कैसे लिखना है जो शुद्ध उपयोग किए बिना संसाधन प्रतिपादन का परीक्षण करेगा (दूसरे शब्दों में: जो संसाधन शुरू करेगा, इसे एक डमी अनुरोध आदि देगा)।परीक्षण के साथ मुड़ गए वेब संसाधन का परीक्षण कैसे करें?

मान लें कि व्यू संसाधन एक साधारण पत्ता है कि render_GET में परिणामस्वरूप सरल पाठ उत्पन्न करने के लिए adbapi के साथ NOT_DONE_YET और टिंकर लौटाते हैं। अब, मैं इस बेकार कोड लिखा है और मैं कैसे यह वास्तव में संसाधन प्रारंभ बनाने के लिए नहीं आते हैं और कुछ समझदार प्रतिक्रिया का उत्पादन कर सकते हैं:

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 (देखें) लेकिन एक ही आउटपुट = 1. क्यों? मैं बहुत कुछ उदाहरण के लिए gratefull होगा इस तरह के अनजान लिखने के लिए कैसे!

उत्तर

10

यहाँ एक समारोह है कि एक अनुरोध प्रस्तुत करना होगा और में परिणाम कन्वर्ट है एक आस्थगित पर सक्रिय होता है प्रतिपादन पूरा हो गया है कि:

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,)) 

यह वास्तव में मुड़ वेब के टेस्ट स्वीट में प्रयोग किया जाता है, लेकिन यह निजी है यह कोई इकाई है क्योंकि खुद का परीक्षण ;)

आप इस प्रकार का परीक्षण लिखने के लिए उपयोग कर सकते हैं:

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

धन्यवाद! ऐसा लगता है कि काम करना प्रतीत होता है, लेकिन मुड़ने से परिणाम कभी नहीं लौटाता है - मैंने प्रिंट के साथ जांच की है, यह अनुरोध के बाद इंतजार कर रहा है। नोटिफ़ाईफिशिश()। मैंने जिस स्लग का परीक्षण किया है, वह एक्सेस होने पर अच्छी तरह से काम करता है। संभवतः गलत क्या हो सकता है? – pielgrzym

+0

यह 'request.setHeader' और request.setHost पर रुक जाता है - शायद अधिकतर उन्हें डमीरेक्वेट (या उनमें से एक) में लागू नहीं किया गया है। – pielgrzym

+0

Yup यह इस पर विफल रहता है: setHeader और getCookie - मुझे लगता है कि DummyRequest subclassing और कुकी और setHeader कार्यक्षमता को हल करने से यह हल हो जाएगा :) – pielgrzym

0

यहाँ एक 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" 
+0

यह वास्तव में 404 सेट करता है। क्या यह संभव है कि मुझे अपने संसाधन वर्ग में कोड 200 मैन्युअल रूप से सेट करना होगा? – pielgrzym

+0

'request.setResponseCode()' आमतौर पर 'संसाधन Subclass.render() 'या' .processingFailed() 'विधियों में कहा जाता है। – jfs

+0

ऊपर _render() फ़ंक्शन में हम request.render() को कॉल करते हैं। क्या यह NOT_DONE_YET और स्थगित का उपयोग कर अनुरोध के कारण हो सकता है? – pielgrzym

संबंधित मुद्दे