测试#

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 是推荐的测试运行器,并且所有示例都假定 pytestpytest-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_requestafter_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]