【问题标题】:How to emulate a http.server for faster unittest in python3?如何在 python 中模拟 http.server 以实现更快的单元测试?
【发布时间】:2019-05-09 21:28:12
【问题描述】:

我正在尝试在 localhost 上模拟 http 服务器以进行更快的测试。

例如:

import my_module

class RequestsTestCase(unittest.TestCase):
    def setUp(self):
        # ...
        html = 'hello, world'
        my_server = MyServer(html, 8888)
        my_server.run()
        ...

    def test_my_module_request_phrase(self):
        response = my_module.get_phrase('http://localhost:8888/')
        self.assertEqual(response, 'hello, world')

使用 python 3 可以实现这样的事情吗?

【问题讨论】:

  • 取决于my_server.run() 的作用。如果它阻塞,那么setUp() 将不会返回,并且您的测试将不会被执行。
  • 您是在尝试测试客户端、服务器还是集成场景?它看起来像一个集成场景,在这种情况下,您无法真正模拟服务器并进行合法测试。如果你正在做一个客户端测试,你可以对你使用的任何 http 库进行猴子补丁,以存根实际的网络通信,并将预设响应返回给客户端。如果您正在测试服务器,除非您实际上是在尝试测试网络堆栈,否则您可以模拟出请求对象并将罐装对象提供给您的模型和其他代码。
  • 在 django 中,您将使用 django.test.client。但正如 sr2222 所说,这取决于您要测试的内容。
  • 除非您有一些中间件或您正在尝试测试的东西,否则您应该能够模拟出请求对象并将其输入您的模型,然后验证您是否获得了适当的响应对象。不过,您仍然应该至少进行一些粗略的端到端集成测试,以全面检查整个堆栈。

标签: python unit-testing http request python-3.3


【解决方案1】:

我只是想在不需要互联网的情况下测试请求的响应 (...)

没问题。您可以在运行测试的同一主机上运行测试 http 服务器。如果您在运行测试的同一进程中运行它(在 setUp() 方法中使用 unittest 和运行测试服务器时就是这种情况),那么服务器必须在单独的线程中运行,这样它就不会阻止你的测试。你可以在 urllib3 here 中看看是怎么做的。

【讨论】:

【解决方案2】:

首先,考虑以下几个方面:

  • 查看是否可以将 I/O(例如 Web 请求)拉到程序的外层(Google for Clean Architecture)。这将使测试变得更加简单。
  • 确保您有集成测试,这些测试可以在包括实时 Web 服务在内的最终上下文中测试您的应用程序。

如果您仍在寻找一种工具来轻松对剩余的 Web I/O 进行单元测试,请考虑使用库 httprettyresponses。使用这些工具,可以轻松指定虚假响应,包括标题字段、返回码等。生成的测试代码将比您单独使用 Python 模拟(或您在其他线程中同时运行的自定义真实 Web 服务器)编写的代码更简洁、更短。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2014-01-29
    • 2017-06-14
    • 2017-07-03
    • 1970-01-01
    相关资源
    最近更新 更多