Пробная витая пробка TDD, "экземпляр StringTransport не имеет атрибута..."
Я работаю над настройкой настраиваемой оболочки-заглушки SSH, аналогичной 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>>>..." (по крайней мере, пока я не сломаю ее, установив настраиваемое приглашение) или попытаться перезаписать приглашение оболочки на получить чистый вывод.
1 ответ
Отличный вопрос; спасибо за вопрос (и спасибо за использование Twisted и выполнение TDD:-)).
HistoricRecvLine
это TerminalProtocol
, который обеспечивает ITerminalProtocol
, ITerminalProtocol.makeConnection
должен быть вызван с поставщиком ITerminalTransport
, С другой стороны, ваш тестовый модуль вызывает ваш ShellProtocol.makeConnection
с экземпляром StringTransport
, который обеспечивает только IConsumer
, IPushProducer
, а также ITransport
,
поскольку ShellProtocol.makeConnection
ожидает ITerminalTransport
, он ожидает, что он может вызвать все свои методы. К несчастью, LEFT_ARROW
официально не задокументировано для этого интерфейса, что является недосмотром, но поставщики этого интерфейса в Twisted также предоставляют этот атрибут.
Что вы хотите сделать, это обернуть ServerProtocol
вокруг вашего ITerminalProtocol
, который в процессе будет служить вашим ITerminalTransport
, Вы можете увидеть простой пример этой композиции в twisted.conch.stdio
,