如何在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无论如何都不必考虑太多。我现在要测试的是高级行为:
等等。例如:
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中测试协议行为(而不是有线协议编码)?
答案 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的开发人员的测试库的一部分。也许在你构建它之后,你可以在上游贡献它。