如何向在单独线程上运行的Flask服务器发出发布请求

时间:2020-08-05 18:07:19

标签: python multithreading flask python-requests pytest

我正在尝试使用pytest编写测试,以测试给定发布请求的返回。我想将Flask服务器和测试隔离在同一功能中。这是我的代码:

import threading
import requests
from flask import Flask
from flask_restful import Api
from . import UserAuthentication

def test_user_authentication():
    app = Flask(__name__)
    api = Api(app)

    api.add_resource(UserAuthentication, "/<string:stage>/api/user/authentication")

    def app_thread_function():
        app.run(port=5000, host="0.0.0.0")

    app_thread = threading.Thread(target=app_thread_function)
    app_thread.start()

    data = {"username": "xxxxxxx.xxxxxxx@xxxxxxx.com.br", "password": "xxxxxxxxxxxxxx"}
    request = requests.post(url = "http://localhost:5000/dev/api/user/authentication", data = data) 
    print("request")
    print(request)

运行pytest时,出现此错误:

urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded with url: /dev/api/user/authentication (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3a7eeb7280>: Failed to establish a new connection: [Errno 111] Connection refused'))

../web-python/lib/python3.8/site-packages/urllib3/util/retry.py:439: MaxRetryError

端口5000上没有任何运行,为什么不能调用服务器并同时运行它?

1 个答案:

答案 0 :(得分:1)

要为每个测试功能隔离一个应用,应使用@pytest.fixture装饰器。

首先,您应该阅读Testing Flask Applications from the official docs

开始为 conftest.py 中的应用定义一个新的夹具,其功能范围(默认)为other scopes

from myapp import create_app

@pytest.fixture
def app():
    app = create_app()
    return app

然后,在测试功能内,您可以调用应用程序固定装置。

def test_my_function(app):
    # Here you have a fresh app object.
    pass

这里开始另一部分。您需要test_client才能发出请求。 请注意,如果要在应用程序代码中测试断言或异常,则必须将app.testing = True设置为使异常传播到测试客户端。

一种更简单的方法是使用pytest-flask,它将为您创建所需的其他灯具,例如clientconfigothers。 ..

带有pytest-flask的示例:

def test_my_function(client):
    rv = client.get('/')
    assert b'No entries here so far' in rv.data

如果您查看pytest-flask/fixture.py on github,您会发现客户端固定装置仅取决于应用程序固定装置,并从中返回text_client。

您仍然可以尝试使用线程来执行此操作,但是这种方式要简单得多。您不必关心如何结束线程。 debug mode可能存在另一个问题,该问题会启动主线程来控制实际应用。

最后,对于每个调用客户端夹具的测试功能,您将拥有一个新的隔离应用程序,这就是您想要的。