Twisted reactor 如何与基于试验的单元测试一起工作?

How does Twisted reactor work with trial-based unit tests?

我已经使用 Twisted 编写了一个 TCP/UDP 拦截代理,我想向它添加一些单元测试。我想设置一个回显协议,然后通过我的代理发送一些数据,然后检查返回的响应。

然而,似乎即使是使用套接字(撇开我的拦截代理)连接到 echoer 的简单测试,反应器也不会 似乎 被生成在 setUp 之后 - 测试永远挂起。如果我向套接字添加超时,则会引发超时异常。我什至尝试连接 ncat 以确保不是手动创建的套接字应该受到指责 - 回声器确实在监听,但我没有收到回声数据返回给 ncat 客户端。

我使用的测试代码如下

import pytest
import socket
from twisted.trial import unittest
from twisted.internet import reactor, protocol


class EchoTCP(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)


class EchoTCPFactory(protocol.Factory):
    protocol = EchoTCP


class TestTCP(unittest.TestCase):
    """Twisted has its own unittest class
    https://twistedmatrix.com/documents/15.2.0/core/howto/trial.html
    """
    def setUp(self):
        self.iface = "127.0.0.1"
        self.data = b"Hello, World!"
        
        # Setup twised echoer
        self.port = reactor.listenTCP(
            8080,
            EchoTCPFactory(),
            interface=self.iface
        )

    def tearDown(self):
        self.port.stopListening()

    def test_echo(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((self.iface, self.port.getHost().port))
        
        sent = sock.send(self.data)
        data = sock.recv(1024)
        sock.close()

        assert data == self.data

要运行它我用下面的命令

PYTHONPATH="${PWD}" trial --reactor=default mymodule

输出如下,并保持这样直到我终止进程

mymodule.test.test_network
  TestTCP
    test_echo ...

关于反应堆的工作原理,我似乎遗漏了一些信息。我找过类似的例子,但无法正常工作。

我应该如何编写测试以获得预期的行为?

原来我必须运行测试方法为Deffered,使用inlineCallbacks,所以当反应器是运行宁。为了测试这种行为,我使用了以下代码片段


    from twisted.internet.defer import inlineCallbacks
    # [...]

    def check_reactor(self):
        # time.sleep(100)
        return reactor.running

    @inlineCallbacks
    def test_reactor(self):
        reactor_running = yield threads.deferToThread(self.check_reactor)
        assert reactor_running == True

...使测试成功完成

mymodule.test.test_network
  TestTCP
    test_reactor ...                                                       [OK]

-------------------------------------------------------------------------------
Ran 1 tests in 0.007s

PASSED (successes=1)

如果我在callback方法中启用sleep(100),并在那个时间段连接ncat,我发送到监听端口的数据确实被回显了