扭曲的海螺试验 TDD,"StringTransport instance has no attribute..."
twisted conch trial TDD, "StringTransport instance has no attribute..."
我正在设置一个可配置的 SSH 存根 shell,类似于 MockSSH,我想以测试驱动的方式进行。
当我使用 conch.recvline.HistoricRecvLine 而不是基础 twisted.internet.protocol.Protocol
时,我正在 运行 进行问题测试
# test.py
from twisted.trial import unittest
from twisted.test.proto_helpers import StringTransportenter code here
class ShellTest(unittest.TestCase):
def setUp(self):
shell_factory = StubShell.ShellFactory()
self.shell = shell_factory.buildProtocol(('127.0.0.1', 0))
self.transport = StringTransport()
self.shell.makeConnection(self.transport)
def test_echo(self):
self.shell.lineReceived('irrelevant')
self.assertEqual(self.transport.value(), 'something')
# shell.py
from twisted.internet import protocol
class ShellProtocol(HistoricRecvLine):
def connectionMade(self):
HistoricRecvLine.connectionMade(self)
def lineReceived(self, line):
self.terminal.write('line received')
class ShellFactory(protocol.Factory):
protocol = ShellProtocol
这按预期工作。但是,当我进行更改时:
class ShellProtocol(HistoricRecvLine):
我收到错误:
exceptions.AttributeError: StringTransport instance has no attribute 'LEFT_ARROW'
下一步:
多亏了 Glyph 的帮助,我取得了一些进展,仍在尝试进行最低限度的测试设置,以确保我正确设置了 HistoricRecvLine 协议。
我从 test_recvline.py 偷了一些代码,这对我来说仍然有点神奇,尤其是设置 sp.factory = self(unittest.Testcase)。我一直在努力将其降低到最低限度以使该测试通过。
class ShellTestConch(unittest.TestCase):
def setUp(self):
self.sp = insults.ServerProtocol()
self.transport = StringTransport()
self.my_shell = StubShell.ShellProtocol()
self.sp.protocolFactory = lambda: self.my_shell
self.sp.factory = self
self.sp.makeConnection(self.transport)
这让我更接近预期的输出,但是现在我看到终端对输出进行了很大的破坏,这应该是预料之中的。
twisted.trial.unittest.FailTest: '\x1bc>>> \x1b[4hline received' != 'line received'
出于 TDD 的目的,我不确定我是否应该只接受输出的 '\x1bc>>>...' 版本(至少在我通过设置自定义提示打破它之前)或尝试覆盖 shell 提示以获得干净的输出。
问得好;感谢您的提问(也感谢您使用 Twisted,并进行 TDD :-))。
HistoricRecvLine
is a TerminalProtocol
, which provides ITerminalProtocol
. ITerminalProtocol.makeConnection
must be called with a provider of an ITerminalTransport
. On the other hand, your unit test is calling your ShellProtocol.makeConnection
with an instance of StringTransport
, which provides only IConsumer
, IPushProducer
, and ITransport
.
因为 ShellProtocol.makeConnection
需要一个 ITerminalTransport
,它希望它可以调用它的所有方法。不幸的是,LEFT_ARROW
没有正式记录在这个接口上,这是一个疏忽,但是 Twisted 中这个接口的提供者也提供了那个属性。
你想要做的是在你的 ITerminalProtocol
周围包裹一个 ServerProtocol
,在进程将作为您的ITerminalTransport
。您可以在 twisted.conch.stdio
.
中看到此组合的一个简单示例
我正在设置一个可配置的 SSH 存根 shell,类似于 MockSSH,我想以测试驱动的方式进行。
当我使用 conch.recvline.HistoricRecvLine 而不是基础 twisted.internet.protocol.Protocol
时,我正在 运行 进行问题测试# test.py
from twisted.trial import unittest
from twisted.test.proto_helpers import StringTransportenter code here
class ShellTest(unittest.TestCase):
def setUp(self):
shell_factory = StubShell.ShellFactory()
self.shell = shell_factory.buildProtocol(('127.0.0.1', 0))
self.transport = StringTransport()
self.shell.makeConnection(self.transport)
def test_echo(self):
self.shell.lineReceived('irrelevant')
self.assertEqual(self.transport.value(), 'something')
# shell.py
from twisted.internet import protocol
class ShellProtocol(HistoricRecvLine):
def connectionMade(self):
HistoricRecvLine.connectionMade(self)
def lineReceived(self, line):
self.terminal.write('line received')
class ShellFactory(protocol.Factory):
protocol = ShellProtocol
这按预期工作。但是,当我进行更改时:
class ShellProtocol(HistoricRecvLine):
我收到错误:
exceptions.AttributeError: StringTransport instance has no attribute 'LEFT_ARROW'
下一步: 多亏了 Glyph 的帮助,我取得了一些进展,仍在尝试进行最低限度的测试设置,以确保我正确设置了 HistoricRecvLine 协议。 我从 test_recvline.py 偷了一些代码,这对我来说仍然有点神奇,尤其是设置 sp.factory = self(unittest.Testcase)。我一直在努力将其降低到最低限度以使该测试通过。
class ShellTestConch(unittest.TestCase):
def setUp(self):
self.sp = insults.ServerProtocol()
self.transport = StringTransport()
self.my_shell = StubShell.ShellProtocol()
self.sp.protocolFactory = lambda: self.my_shell
self.sp.factory = self
self.sp.makeConnection(self.transport)
这让我更接近预期的输出,但是现在我看到终端对输出进行了很大的破坏,这应该是预料之中的。
twisted.trial.unittest.FailTest: '\x1bc>>> \x1b[4hline received' != 'line received'
出于 TDD 的目的,我不确定我是否应该只接受输出的 '\x1bc>>>...' 版本(至少在我通过设置自定义提示打破它之前)或尝试覆盖 shell 提示以获得干净的输出。
问得好;感谢您的提问(也感谢您使用 Twisted,并进行 TDD :-))。
HistoricRecvLine
is a TerminalProtocol
, which provides ITerminalProtocol
. ITerminalProtocol.makeConnection
must be called with a provider of an ITerminalTransport
. On the other hand, your unit test is calling your ShellProtocol.makeConnection
with an instance of StringTransport
, which provides only IConsumer
, IPushProducer
, and ITransport
.
因为 ShellProtocol.makeConnection
需要一个 ITerminalTransport
,它希望它可以调用它的所有方法。不幸的是,LEFT_ARROW
没有正式记录在这个接口上,这是一个疏忽,但是 Twisted 中这个接口的提供者也提供了那个属性。
你想要做的是在你的 ITerminalProtocol
周围包裹一个 ServerProtocol
,在进程将作为您的ITerminalTransport
。您可以在 twisted.conch.stdio
.