扭曲的协议行为的高级测试

时间:2014-10-20 09:55:45

标签: python twisted python-unittest

如何在twisted中编写协议的高级测试?

我知道您可以使用StringTransport来测试低级协议详细信息,例如它收到了一些原始数据并且发生了一些状态变化,或者它以某种方式作出了回应:

factory = SomeFactory()
protocol = factory.buildProtocol("ignored")
trans = proto_helpers.StringTransport("foo", 1234)
protocol.makeConnection(trans)
# ...
protocol.dataReceived("RAW PROTOCOL DATA\n")
self.assertEquals("Hello World!\n", self.transport.value())

然而,线路协议现在并不那么重要。它正在变化,我使用AMP无论如何都不必考虑太多。我现在要测试的是高级行为:

  • 建立连接,确保协议通知GUI。
  • 请求联系人列表,确保回送我提供的联系人。

等等。例如:

serverApp = FakeApplication()   # this contains application state
serverFactory = SomeFactory(serverApp)
testEndpoint = magic.TestEndpoint()   # this class doesn't exist
testEndpoint.listen(factory)

clientApp = FakeApplication()
clientFactory = SomeFactory(clientApp)
testEndpoint.otherSide.connect(clientFactory)

self.assertEquals(serverApp.nConnections, 1)
self.assertEquals(clientApp.nConnections, 1)

assert clientApp.onNewConnection.was_called()  # pseudo-code

缺少的是用于连接两个协议对象的某种虚假端点或双向传输。

如何在twisted中测试协议行为(而不是有线协议编码)?

1 个答案:

答案 0 :(得分:2)

正如您所说,您并未尝试测试线路上字节的低级细节。您不需要一个可以移动那些不相关字节的测试工具。

相反,您需要一个测试工具,让我们远离字节并测试对更高级别重要的应用程序级行为。

你提到你正在使用AMP。 Twisted中的AMP API通过为您提供可以传递给协议的callRemote API的命令对象来工作。

如果点击" foo" GUI中的按钮应该会导致" bar"使用某些特定参数遍历网络的命令,将GUI代码挂钩到AMP - 类似于处理命令。对于这样的测试double,callRemote的实现可能类似于(未经测试):

from twisted.internet.defer import execute

class LocalAMP(object):
    def __init__(self, backend):
        self._backend = backend

    def callRemote(self, command, **kwargs):
        try:
            method = getattr(self._backend, command.__name__)
        except AttributeError:
            return fail(NoSuchMethod())
        return execute(method, **kwargs)

现在,您可以调用应用程序级行为,而无需担心协议。

在一个完美的世界中,像这样的类将与Twisted一起分发,作为使用AMP的开发人员的测试库的一部分。也许在你构建它之后,你可以在上游贡献它。