Django4.0 测试工具-测试异步代码
如果你只是想测试异步视图的输出,标准测试客户端将在自己的异步循环中运行它们,而不需要你做任何额外的工作。
但是,如果你想为 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):
...