test_background_tasks.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import asyncio
  2. import pytest
  3. from nicegui import app, background_tasks, ui
  4. from nicegui.testing import User
  5. # pylint: disable=missing-function-docstring
  6. # NOTE: click handlers, and system events used to wrap background_task in a background_task (see https://github.com/zauberzeug/nicegui/pull/4641#issuecomment-2837448265)
  7. @pytest.mark.parametrize('strategy', ['direct', 'click', 'system'])
  8. async def test_awaiting_background_tasks_on_shutdown(user: User, strategy: str):
  9. run = set()
  10. cancelled = set()
  11. async def one():
  12. try:
  13. run.add('one')
  14. await asyncio.sleep(1)
  15. except asyncio.CancelledError:
  16. cancelled.add('one')
  17. @background_tasks.await_on_shutdown
  18. async def two():
  19. try:
  20. run.add('two')
  21. await asyncio.sleep(1)
  22. background_tasks.create(three(), name='three')
  23. background_tasks.create(four(), name='four')
  24. except asyncio.CancelledError:
  25. cancelled.add('two')
  26. async def three():
  27. try:
  28. await asyncio.sleep(0.1)
  29. run.add('three')
  30. except asyncio.CancelledError:
  31. cancelled.add('three')
  32. @background_tasks.await_on_shutdown
  33. async def four():
  34. try:
  35. await asyncio.sleep(0.1)
  36. run.add('four')
  37. except asyncio.CancelledError:
  38. cancelled.add('four')
  39. ui.button('One', on_click=lambda: background_tasks.create(one(), name='one'))
  40. ui.button('Two', on_click=lambda: background_tasks.create(two(), name='two'))
  41. if strategy == 'system':
  42. app.on_connect(lambda: background_tasks.create(one(), name='one'))
  43. app.on_connect(lambda: background_tasks.create(two(), name='two'))
  44. await user.open('/')
  45. if strategy == 'click':
  46. user.find('One').click()
  47. user.find('Two').click()
  48. elif strategy == 'direct':
  49. background_tasks.create(one(), name='one')
  50. background_tasks.create(two(), name='two')
  51. await asyncio.sleep(0.1) # NOTE: we need to wait for the tasks to be created
  52. # NOTE: teardown is called on shutdown; here we call it directly to test the teardown logic while test is still running
  53. await background_tasks.teardown()
  54. assert cancelled == {'one', 'three'}
  55. assert run == {'one', 'two', 'four'}