我正在尝试使用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上没有任何运行,为什么不能调用服务器并同时运行它?
答案 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,它将为您创建所需的其他灯具,例如client,config和others。 ..
带有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可能存在另一个问题,该问题会启动主线程来控制实际应用。
最后,对于每个调用客户端夹具的测试功能,您将拥有一个新的隔离应用程序,这就是您想要的。