如何使用编写代码测试twisted.web.client.Agent及其子类?

2024-09-19 23:38:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我读过关于测试驱动开发的official tutorial,但它对我的案例没有太大帮助。我编写了一个小库,它广泛地使用了twisted.web.client.Agent及其子类(例如BrowserLikeRedirectAgent),但我一直在努力使教程的代码适应我自己的测试用例。在

我看了一下twisted.web.test.test_web,但我不明白如何将所有的部分组合在一起。例如,根据官方教程,我仍然不知道如何从Agent获取Protocol对象

有谁能告诉我如何为一些依赖于GETPOST数据的代码编写一个简单的测试?任何额外的细节或建议是非常欢迎的。。。在

非常感谢!在


Tags: 代码testclientweb官方twisted测试用例教程
3条回答

不如用@inlineCallbacks让生活更简单(即代码更可读)。在

事实上,我甚至建议不要直接使用Deferreds,除非对于性能或在特定的用例中是绝对必要的,而是始终坚持使用@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()

试用应该负责剩下的工作(即等待从测试函数返回的Deferreds(@inlineCallbacks-包装的可调用文件也“神奇地”返回Deferred-如果您还不熟悉@inlineCallbacks,我强烈建议您阅读更多关于@inlineCallbacks的内容)。在

另外,还有一个用于nosetests的扭曲的“插件”,它允许您从测试函数返回DeferredS,并让nose等待它们被激发后再退出:http://nose.readthedocs.org/en/latest/api/twistedtools.html

这与mike所说的类似,但尝试测试响应处理。还有其他的方法,但我喜欢这样。我也同意,测试wrap代理的东西并没有太大帮助,测试协议/在协议中保持逻辑可能更好,但有时您只想添加一些绿色标记。在

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)

相关问题 更多 >