Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测试处理HTTP请求的Python应用程序_Python_Unit Testing - Fatal编程技术网

测试处理HTTP请求的Python应用程序

测试处理HTTP请求的Python应用程序,python,unit-testing,Python,Unit Testing,对于测试,我使用pytest,所以如果您建议一些pytest特定的东西,那就太好了 我有一些使用请求库的代码。它所做的基本上是简单的POST/GET请求,用于登录、解析数据等 当然,我想在本地测试代码,而不做任何实际的HTTP请求 一个monkeypatchfuncarg可能是解决方案,但我认为模仿request.get(…)调用或直接调用pythons的urllib是不好的,因为,例如,有函数在其中执行多个HTTP请求,所以我不能只模仿request.get(“anyURL”)使用简单的lam

对于测试,我使用pytest,所以如果您建议一些pytest特定的东西,那就太好了

我有一些使用
请求
库的代码。它所做的基本上是简单的POST/GET请求,用于登录、解析数据等

当然,我想在本地测试代码,而不做任何实际的HTTP请求

一个
monkeypatch
funcarg可能是解决方案,但我认为模仿
request.get(…)
调用或直接调用pythons的
urllib
是不好的,因为,例如,有函数在其中执行多个HTTP请求,所以我不能只模仿
request.get(“anyURL”)
使用简单的
lambda*args,**kwaargs:“response”“”

有不同的URL应该返回不同的内容。有时它应该基于POST/GET数据。另外,我不知道在直接模拟的情况下,
请求.会话
将如何运行。除此之外,如何模拟会话终止?如何模拟连接故障

因此,在我看来,最终在这里使用猴子补丁是相当困难的。至少我不能写一个好的模拟函数,它会考虑到一切。另外,如果我选择直接模拟
urllib
,有一天
请求库开始使用不同的东西,我的所有测试都会失败

因此,我认为最好的方法是使用实际的HTTP服务器,它在测试运行时打开,如果可能的话,考虑pytest的作用域等(因此它是一个funcarg)。在谷歌搜索时,我发现只有两种解决方案:

第一个设置HTTP服务器并通过特定URL提供预定义内容。这对我来说肯定不起作用,因为正如我提到的,我打算测试的一些函数会执行多个请求,因此所有内部HTTP
requests.get()
都会得到相同的答案。糟糕

据我所知,第二个也有同样的问题。或者至少不知道如何使用它


第三种选择可能是编写一个基于Flask的小服务,但我想我会遇到一个问题,即我在测试中使用的东西也应该进行测试,这是一种不好的做法。

您可以在第一次调用后卸载
get

class Requester():
    def get(*args):
         ...

def mock_get(requester, response):
    orig_get = requester.get
    def return_text_and_unmock(*args, **kwargs):
        self.get = orig_get
        return response
    requester.get = return_text_and_unmock.__get__(requester, Requester)
    return requester

我相信使用本地服务器进行单元测试不是一个好主意,因为这不是真正的单元测试。如果您使用的是
请求
模拟请求的一个好方法是使用dropbox开发和维护的模块
responses
。使用
responses
,您可以通过指定在向给定URL发出请求时希望返回特定内容来模拟每个请求。自述文件快速概述了模块的功能。

这是如何解决问题的。例如,一个网站有一个“删除”链接,可以将您重定向到确认页面。因此,在函数
def delete(…)
中,您在url1上发布,然后在url2上发布第二篇文章。此外,您还必须考虑表单中的令牌等。。。您的解决方案将对实际的Web服务器执行第二个get请求。我认为使用
unittest.mock
(或
mock
用于python 3.4之前版本)进行修补和模拟
urllib.requests()
正是您需要的:您可以测试您的应用程序是否正确调用它,以及
requests()上的行为
返回值。我提到了monkeypatch funcarg,它与unittest.mock几乎相同。它的所有问题都在一个主题中描述。如果你说的是单元测试(而不是集成测试),那么你最好信任
urllib
,并模仿它,即使它做了几个请求(你可以使用mocks对象的
side_effect
属性来处理这些情况)。如果您试图通过模拟服务器来测试您的应用程序,您将遇到很多问题来跟踪您的bug,因为您的感知点距离您的bug太远了。当然,您甚至需要使用real server和real
urllib
调用的集成测试,但不是针对所有预期行为。你可以自由地模拟服务器,但我想你会知道一个可怕的事实:)@Michele d'Amic也许你是对的,我的单元测试更像是集成测试,但不管你怎么说,我应该测试这个应用程序。不幸的是,pytest的monkeypatch没有副作用功能。即使有,在编写补丁函数时,我也需要考虑很多因素。我希望有人能面对这个问题,并编写一个库,按照您的建议进行模拟,但可以说它包含每个URL的副作用。每个URL的副作用非常简单:请花2分钟阅读文档。编写一个可调用的映射词典来完成这项工作。您可以在没有单元测试的情况下使用
mock
。为什么这不是单元测试?当您测试一个任意的Add函数时,该函数会计算某些内容,然后将其添加到数据库中。您将设置一个mysql服务器,并将assert设置为“SELECT…FROM tbl”或类似的内容。多亏了“responses”,如果您在测试代码之外的东西时,需要安装本地服务器或运行数据库,那么我会看一下。IMHO是一个集成测试,这是您负责的。使用
responses
将把测试范围缩小到您可以控制的范围。不过,我不确定Dropbox的响应对HttpRety有什么好处。从我刚才在HttpRety上读到的内容来看,我不会说:)。我的回答是
responses
特定的,因为它是我使用的python包,我以前从未听说过HttpRety。