Как выполнить юнит-тестирование asyncio call_later с pytest?

Я пишу некоторый асинхронный код и пытаюсь выполнить запланированные действия. Я хотел бы написать несколько юнит-тестов для моего кода. Что такое "хороший" способ для модульного тестирования кода, который включает call_later() действия? Я хотел бы избежать ожидания в течение нескольких секунд, поэтому мне нужно как-то смоделировать время.

Минимальный пример:

import asyncio

def do_more_stuff():
    print("doing more stuff")

async def do_stuff():
    print("doing stuff")
    await asyncio.sleep(0.1)
    print("scheduling more stuff")
    asyncio.get_event_loop().call_later(2, do_more_stuff)


def test_delayed_action(event_loop: asyncio.AbstractEventLoop):
    asyncio.set_event_loop(event_loop)

    asyncio.get_event_loop().create_task(do_stuff())
    event_loop.run_forever()

Этот пример имеет несколько проблем:

  • Из-за run_forever()не заканчивается после do_more_stuff() назывался. Я хотел бы иметь event_loop работать до тех пор, пока не будет запланировано больше обратных вызовов. Это возможно?

  • Даже если я взломаю в будущем и использую event_loop.run_until_complete(fut)этот тест все еще занимает 2 секунды, чтобы закончить. Я хотел бы либо только бежать do_stuff() и проверить запланированные обратные вызовы; или выдвиньте время, чтобы ускорить запуск обратных вызовов. Возможно ли это?

0 ответов

Другие вопросы по тегам