测试#
Quart 使用全局变量(例如 request
等)使得测试使用这些变量的任何代码变得更加困难。为了解决这个问题,最佳实践是在直接由 Quart 调用的代码中仅使用这些变量,例如路由函数或请求前函数。之后,Quart 提供了一个测试框架来控制这些全局变量。
主要测试应使用绑定到正在测试的 Quart 应用程序的测试客户端来完成。由于这很常见,因此有一个帮助方法 test_client()
返回一个绑定客户端,例如:
async def test_app(app):
client = app.test_client()
response = await client.get('/')
assert response.status_code == 200
事件循环#
要使用 Quart 进行测试,你需要有一个事件循环来调用异步函数。这可以通过手动完成,例如
def aiotest(func):
loop = asyncio.get_event_loop()
loop.run_until_complete(func())
@aiotest
async def test_app(app)
...
但是,使用 pytest-asyncio
让它为你做会更容易。请注意,pytest
是推荐的测试运行器,并且所有示例都假定 pytest
与 pytest-asyncio
一起使用。
调用路由#
测试客户端对所有 HTTP 动词都有帮助方法,例如 post()
。这些是 open()
的帮助方法,因此所有方法至少都期望一个路径,并且可以选择具有查询参数、json 或表单数据。返回一个标准的 Response
类。一个例子
async def test_create(app):
test_client = app.test_client()
data = {'name': 'foo'}
response = await test_client.post('/resource/', json=data)
assert response.status_code == 201
result = await response.get_json()
assert result == data
要测试流式请求或响应的测试路由,请使用 request()
方法
async def test_stream() -> None:
test_client = app.test_client()
async with test_client.request(...) as connection:
await connection.send(b"data")
await connection.send_complete()
...
# receive a chunk of the response
data = await connection.receive()
...
# assemble the rest of the response without the first bit
response = await connection.as_response()
上下文测试#
通常需要测试应用程序或请求上下文中的某些内容。这对应用程序上下文来说很简单,
async def test_app_context(app):
async with app.app_context():
current_app.[use]
但是,对于请求上下文,必须伪造请求上下文,至少需要提供方法和路径,例如
async def test_app_context(app):
async with app.test_request_context("/", method="GET"):
request.[use]
注意
使用 test_request_context
时不会调用任何 before_request
或 after_request
函数。您可以添加 await app.preprocess_request()
来确保调用 before_request
函数。
async def test_app_context(app):
async with app.test_request_context("/", method="GET"):
await app.preprocess_request()
# The before_request functions have now been called
request.[use]