测试执行HTTP请求的Python应用程序

时间:2015-01-21 13:35:19

标签: python unit-testing

为了测试我使用pytest,所以如果你建议pytest特定的东西会很棒。

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

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

monkeypatch funcarg可能是解决方案,但我认为嘲弄request.get(...)来电或直接蟒蛇urllib并不好,因为,例如,有些函数可以在里面执行多个HTTP请求,所以我不能用简单的request.get("anyURL")来模拟lambda *args, **kwaargs: """<html>response</html>"""

有不同的网址应该返回不同的内容。有时它应该基于POST / GET数据。此外,我不知道requests.session在直接嘲笑的情况下会如何表现。除了如何模拟会话终止?如何模拟连接失败?

所以最后在我看来,在这里使用猴子补丁非常困难。至少我不能写一个好的模拟功能,它会考虑到一切。另外,如果我选择直接模拟urllib并且有一天requests库开始使用不同的东西,那么我的所有测试都会失败。

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

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

我看到的第二个问题也有同样的问题。或者至少不明白如何使用它。

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

2 个答案:

答案 0 :(得分:1)

我认为使用本地服务器进行单元测试并不是一个好主意,因为这不是单元测试。我们使用requests一种能够模拟请求的好方法是使用由dropbox开发和维护的模块responsesresponse dropbox。使用responses,您可以通过指定在向给定URL发出请求时要返回某个内容来模拟您所做的每个请求。自述文件简要概述了模块的功能。

答案 1 :(得分:0)

您可以在第一次通话后取消静音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