簡體   English   中英

如何使用twisted.web.client.Agent及其子類編寫代碼測試?

[英]How can I write tests for code using twisted.web.client.Agent and its subclasses?

我閱讀了關於測試驅動開發的官方教程 ,但在我的案例中它並沒有很大幫助。 我編寫了一個小型庫,它大量使用twisted.web.client.Agent及其子類(例如BrowserLikeRedirectAgent ),但我一直在努力使教程的代碼適應我自己的測試用例。

我看了一下twisted.web.test.test_web ,但我不明白如何將所有部分組合在一起。 例如,根據官方教程,我仍然不知道如何從Agent獲取Protocol對象

任何人都可以告訴我如何編寫一些依賴於代理到GETPOST數據的代碼的簡單測試嗎? 我們非常歡迎任何其他細節或建議......

非常感謝!

如何通過使用@inlineCallbacks使生活更簡單(即代碼更具可讀性)。

事實上,我甚至建議不要直接使用Deferred s,除非對於性能或特定用例絕對必要,而是始終堅持使用@inlineCallbacks - 這樣你就可以保持你的代碼看起來像普通代碼一樣,同時受益於非阻塞行為:

from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.internet.defer import inlineCallbacks
from twisted.trial import unittest
from twisted.web.http_headers import Headers
from twisted.internet.error import DNSLookupError


class SomeTestCase(unittest.TestCase):
    @inlineCallbacks
    def test_smth(self):
        ag = Agent(reactor)
        response = yield ag.request('GET', 'http://example.com/', Headers({'User-Agent': ['Twisted Web Client Example']}), None)
        self.assertEquals(response.code, 200)

    @inlineCallbacks
    def test_exception(self):
        ag = Agent(reactor)
        try:
            yield ag.request('GET', 'http://exampleeee.com/', Headers({'User-Agent': ['Twisted Web Client Example']}), None)
        except DNSLookupError:
            pass
        else:
            self.fail()

試驗應該照顧其余部分(即等待從測試函數返回的Deferred s( @inlineCallbacks -wrapped callables)“神奇地”返回Deferred -I強烈建議如果你還不熟悉那么在@inlineCallbacks上閱讀更多)。

PS還有一個用於測試的Twisted“插件”,它允許你從測試函數中返回Deferred s並且在退出之前等待它們被解雇: http//nose.readthedocs.org/en/latest/api/twistedtools。 HTML

這類似於邁克所說,但試圖測試響應處理。 還有其他方法可以做到這一點,但我喜歡這種方式。 此外,我同意測試包裝代理的東西不是太有用,並且在協議中測試協議/保持邏輯可能更好,但有時你只想添加一些綠色滴答。

class MockResponse(object):
    def __init__(self, response_string):
        self.response_string = response_string

    def deliverBody(self, protocol):
        protocol.dataReceived(self.response_string)
        protocol.connectionLost(None)


class MockAgentDeliverStuff(Agent):

    def request(self, method, uri, headers=None, bodyProducer=None):
        d = Deferred()
        reactor.callLater(0, d.callback, MockResponse(response_body))
        return d

class MyWrapperTestCase(unittest.TestCase):

    def setUp:(self):
        agent = MockAgentDeliverStuff(reactor)
        self.wrapper_object = MyWrapper(agent)

    @inlineCallbacks
    def test_something(self):
        response_object = yield self.wrapper_object("example.com")
        self.assertEqual(response_object, expected_object)

這個怎么樣? 對以下內容進行試用。 基本上你只是嘲笑代理並假裝它像宣傳的那樣,並且使用FakeAgent(在這種情況下)使所有請求失敗。 如果你真的想把數據注入到傳輸中,那我認為這樣做會“更多”。 但是,你真的在​​測試你的代碼嗎? 還是代理?

from twisted.web import client
from twisted.internet import reactor, defer

class BidnessLogik(object):
    def __init__(self, agent):
        self.agent = agent
        self.money = None

    def make_moneee_quik(self):
        d = self.agent.request('GET', 'http://no.traffic.plz')
        d.addCallback(self.made_the_money).addErrback(self.no_dice)
        return d

    def made_the_money(self, *args):
        ##print "Moneeyyyy!"
        self.money = True
        return 'money'

    def no_dice(self, fail):
        ##print "Better luck next time!!"
        self.money = False
        return 'no dice'

class FailingAgent(client.Agent):
    expected_uri = 'http://no.traffic.plz'
    expected_method = 'GET'
    reasons = ['No Reason']
    test = None

    def request(self, method, uri, **kw):
        if self.test:
            self.test.assertEqual(self.expected_uri, uri)
            self.test.assertEqual(self.expected_method, method)
            self.test.assertEqual([], kw.keys())
        return defer.fail(client.ResponseFailed(reasons=self.reasons,
                                                response=None))

class TestRequest(unittest.TestCase):
    def setUp(self):
        self.agent = FailingAgent(reactor)
        self.agent.test = self

    @defer.inlineCallbacks
    def test_foo(self):
        bid = BidnessLogik(self.agent)
        resp = yield bid.make_moneee_quik()
        self.assertEqual(resp, 'no dice')
        self.assertEqual(False, bid.money)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM