问题描述
我正在测试一个可能会死锁的异步函数.我尝试添加一个装置来限制该函数在引发故障之前仅运行 5 秒,但到目前为止还没有奏效.
I am testing an async function that might get deadlocked. I tried to add a fixture to limit the function to only run for 5 seconds before raising a failure, but it hasn't worked so far.
设置:
pipenv --python==3.6
pipenv install pytest==4.4.1
pipenv install pytest-asyncio==0.10.0
代码:
import asyncio
import pytest
@pytest.fixture
def my_fixture():
# attempt to start a timer that will stop the test somehow
asyncio.ensure_future(time_limit())
yield 'eggs'
async def time_limit():
await asyncio.sleep(5)
print('time limit reached') # this isn't printed
raise AssertionError
@pytest.mark.asyncio
async def test(my_fixture):
assert my_fixture == 'eggs'
await asyncio.sleep(10)
print('this should not print') # this is printed
assert 0
--
Mikhail 的解决方案工作正常.不过,我找不到将它合并到装置中的方法.
Mikhail's solution works fine. I can't find a way to incorporate it into a fixture, though.
推荐答案
使用超时限制函数(或代码块)的便捷方法是使用 异步超时 模块.您可以在测试函数中使用它,或者,例如,创建一个装饰器.与夹具不同,它允许为每个测试指定具体时间:
Convenient way to limit function (or block of code) with timeout is to use async-timeout module. You can use it inside your test function or, for example, create a decorator. Unlike with fixture it'll allow to specify concrete time for each test:
import asyncio
import pytest
from async_timeout import timeout
def with_timeout(t):
def wrapper(corofunc):
async def run(*args, **kwargs):
with timeout(t):
return await corofunc(*args, **kwargs)
return run
return wrapper
@pytest.mark.asyncio
@with_timeout(2)
async def test_sleep_1():
await asyncio.sleep(1)
assert 1 == 1
@pytest.mark.asyncio
@with_timeout(2)
async def test_sleep_3():
await asyncio.sleep(3)
assert 1 == 1
为具体时间创建装饰器并不难(with_timeout_5 = partial(with_timeout, 5)
).
It's not hard to create decorator for concrete time (with_timeout_5 = partial(with_timeout, 5)
).
我不知道如何创建纹理(如果你真的需要夹具),但上面的代码可以提供起点.也不确定是否有更好地实现目标的通用方法.
I don't know how to create texture (if you really need fixture), but code above can provide starting point. Also not sure if there's a common way to achieve goal better.
这篇关于如何使用fixture在pytest中超时异步测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!