Python:单元测试基于套接字的代码?

Dav*_*ver 19 python sockets testing gevent

我正在编写一个gevent.socket用于通信的Python客户端+服务器.有没有什么好方法可以测试代码的套接字级操作(例如,验证与无效证书的SSL连接是否会被拒绝)?或者只是spawn一个真正的服务器最简单?

编辑:我不相信"天真"的模拟将足以测试SSL组件,因为涉及复杂的交互.我错了吗?或者有更好的方法来测试SSL的东西吗?

Den*_*nko 17

您可以轻松启动服务器,然后在测试用例中访问它.gevent 自己的测试套件正好用于测试gevent的内置服务器.

例如:

class SimpleServer(gevent.server.StreamServer):

    def handle(self, socket, address):
        socket.sendall('hello and goodbye!')

class Test(unittest.TestCase):      

    def test(self):
        server = SimpleServer(('127.0.0.1', 0))
        server.start()
        client = gevent.socket.create_connection(('127.0.0.1', server.server_port))
        response = client.makefile().read()
        assert response == 'hello and goodbye!'
        server.stop()
Run Code Online (Sandbox Code Playgroud)

使用0的端口值意味着服务器将使用任何可用的端口.启动服务器后,选择的实际值bind可用作server_port属性.

StreamServer支持SSL太,传递keyfilecertfile参数构造函数,它会包装每个插座,SSLObject将它传递给你的处理程序之前.

如果您不使用StreamServer并且您的服务器基于Greenlet,那么确实产生它是您应该做的.不要忘记在测试用例结束时杀死它.

启动服务器,并生成一个greenlet在快速操作GEVENT,比创建一个新的线程或进程更快,你可以很容易地为每个测试用例一个新的服务器.只要不再需要服务器就不要忘记清理.

我相信不需要模拟任何gevent API,只需将它用作服务器就可以了,并且客户可以愉快地生活在同一个流程中.

  • 我的示例中的端口号为零,这意味着bind()将找到一个空闲端口并使用它. (2认同)

Paw*_*icz 8

还有另一种(IMO更好)的方式:你应该模拟你正在使用的库.用于python的示例帮助器的示例是mox.

您不需要一组具有有效证书的服务器,另一个具有无效证书的服务器,根本没有ssl支持,根本不响应任何数据包的服务器等等.您可以使用"虚拟"客户端套接字模拟其行为.它与Mox一起工作的方式是你首先"教"它应该期待什么以及它应该如何反应然后你在它上面执行你的真实代码,同时交换真实的gevent.socket用于模拟它.需要一些练习来掌握它,但这是值得的.


Bil*_*ble 7

模拟和存根很棒,但有时您需要将其提升到下一级集成.由于产生服务器,甚至是假的服务器,可能需要一些时间,因此可以考虑使用单独的测试套件(称为集成测试).

"测试它就像你要使用它"是我的指南,如果你嘲笑和存根以至于你的测试变得微不足道,它就没那么有用了(尽管几乎所有的测试都比没有测试好).如果您担心处理错误的SSL证书,请务必制作一些不好的证书并编写测试夹具,然后将它们提供给它们.如果这意味着产生服务器,那就这样吧.也许如果你的错误足够,它将导致重构,使其以另一种方式可测试.