【问题标题】:LiveServerTestCase hangs at python-requests post call in django viewLiveServerTestCase 在 django 视图中的 python-requests post call 挂起
【发布时间】:2014-02-11 00:26:16
【问题描述】:

我正在编写一个使用我创建的 REST api 的 Django 应用程序。目的是证明使用 web 应用程序的 api 用例。在我看来,我因此使用 python-requests 库调用 api,如下所示:

def my_view_method(request):
    if request.method == 'POST':
    form = MyForm(request.POST)
    if form.is_valid():
        data = form.cleaned_data
        data_to_post = {
            'fieldA': data.get('fieldA_in_form'),
            'fieldB': data.get('fieldB_in_form'),
        }
        post_url = "http://%s/%s/" % (request.get_host(), 'entries')
        logger.info("request api url: "+ post_url)
        r = requests.post(post_url, data=data_to_post)
        return HttpResponseRedirect('/')
    else:
        form = MyForm()

    return render(request, 'myview.html', { 'form': form })

我已经使用单元测试验证了使用有效数据发布到 /entries/ 会导致正确的数据库更新。

url = '/entries/'
#verify initial db state
data = { 'fieldA': value1, 'fieldB': value2 }
response = self.client.post(url, data, format='json')
# verify db was updated

在我的功能测试中,我使用 LiveServerTestCase 并与表单交互。当测试提交表单时,浏览器选项卡在标题中显示“正在连接...”,测试用例挂起。当我直接与数据库交互而不是使用请求调用api时,情况并非如此,所以这一定是延迟的来源。

关于 LiveServerTestCase 的工作原理是否有一些我在这里不理解的地方?

【问题讨论】:

    标签: python django python-requests functional-testing


    【解决方案1】:

    难道 LiveServerTestCase 服务器一次只能处理一个请求?所以它挂起是因为它无法处理请求中的请求?

    The source 说它将“一次处理一个请求”,但又说“不阻塞”,所以这是模棱两可的......

    我认为最好放弃 LiveServerTestCase 并滚动自己的测试运行程序。您可以使用 setUp 在单独的进程中启动 runserver,并使用 tearDown 重置数据库 (manage.py flush?)。如果您想使用测试数据库,您可以使用不同的 settings.py,或者在测试期间将“真实”数据库移开...

    【讨论】:

      【解决方案2】:

      测试完成后请求挂起,因为您是通过requests 库而不是here 描述的官方测试客户端发出请求。

      您甚至不需要这样做,直接测试 API 而不是通过 Django 启动 Web 服务器会更有意义。

      这是文档 here 中对 LiveServerTestCase 的描述

      LiveServerTestCase 在后台启动实时 Django 服务器 设置,并在拆卸时将其关闭。这允许使用自动化 测试客户端,例如 Selenium 客户端,以执行 在浏览器中进行一系列功能测试并模拟真实用户的 行动。

      如果您想测试 API 本身,甚至不需要初始化 Django 应用程序。

      对于此类问题,我喜欢采用的一种测试方法是组件集成方法,在 Wikipedia here 上有所描述。

      在本例中,我们将独立于服务层(API)测试 Django 应用程序(前端)。在测试前端时,您仍然可以使用 API,但存在分离以定义您编写测试的方式。

      由于 API 是 Flask 应用程序,我将使用 here 描述的内置测试工具中的 Flasks。

      API 与 Django 无关,是的,它由 Django 应用程序使用,并且该应用程序对该 API 有很强的依赖关系,但您希望专门测试 API 本身。

      为了帮助进行 UI 测试,您可以将 API 用作测试夹具/setUp 例程的一部分,以免自己使用 UI 添加执行所需的任何测试数据。但是,如果您想测试 API 本身,那么由于上述问题,通过 Django 客户端进行测试将无法正常工作。

      【讨论】:

      • 我猜 Selenium 测试的目的与使用 Django 测试客户端的 API 集成测试完全不同。当然我可以像那样测试 API,但这不会让我知道我的 UI 的行为方式。
      • 查看我上面的编辑,如果你不关心测试组件的分离(我认为你应该这样做)然后使用 Djangos 客户端,如果你有兴趣,请参阅我的其余部分回答。
      最近更新 更多