Django4 中文入门教程 Django4.0 测试工具-测试异步代码

2024-02-25 开发教程 Django4 中文入门教程 匿名 13

如果你只是想测试异步视图的输出,标准测试客户端将在自己的异步循环中运行它们,而不需要你做任何额外的工作。

但是,如果你想为 Django 项目编写完全异步的测试,你需要考虑到几个问题。

首先,你的测试必须是测试类上的 ​async def​ 方法(为了给它们一个异步的上下文)。Django 会自动检测到任何 ​async def​ 的测试,并将它们封装在自己的事件循环中运行。

如果你从一个异步函数进行测试,你也必须使用异步测试客户端。这在任何测试中都可以作为 ​django.test.AsyncClient​ 或 ​self.async_client​ 使用。

AsyncClient​ 具有与同步(普通)测试客户端相同的方法和签名,但有两个例外:

不支持 ​​follow ​​参数。作为 ​​extra ​​关键字参数传递的头信息不应该有同步客户端所要求的 ​​HTTP_​ ​前缀。例如,下面是如何设置 ​HTTP ​Accept​​ 头:

>>> c = AsyncClient()
>>> c.get(
... '/customers/details/',
... {'name': 'fred', 'age': 7},
... ACCEPT='application/json'
... )

使用 ​AsyncClient ​任何提出请求的方法都必须被等待:

async def test_my_thing(self):
response = await self.async_client.get('/some-url/')
self.assertEqual(response.status_code, 200)

异步客户端也可以调用同步视图;它通过 Django 的 异步请求路径 运行,它支持这两种方式。任何通过 ​AsyncClient ​调用的视图都会得到一个 ​ASGIRequest ​对象作为它的 ​request​,而不是普通客户端创建的 ​WSGIRequest​。

警告

如果你使用的是测试装饰器,它们必须是异步兼容的,以确保它们正确工作。Django 内置的装饰器会正常工作,但第三方的装饰器可能会出现无法执行的情况(它们会“包装”执行流程中错误的部分,而不是你的测试)。
如果你需要使用这些装饰器,那么你应该用 ​async_to_sync()​ 来装饰你的测试方法:

from asgiref.sync import async_to_sync
from django.test import TestCase
class MyTests(TestCase):
@mock.patch(...)
@async_to_sync
async def test_my_thing(self):
...