Python’s daemon threads are cool. A Python script will stop when the main thread is done and
only daemon threads are running. To test a simple hello
function that runs indefinitely,
you can do the following:
# test_hello.py
from __future__ import annotations
import asyncio
import threading
from functools import partial
from unittest.mock import patch
async def hello() -> None:
while True:
await asyncio.sleep(1)
print("hello")
@patch("asyncio.sleep", autospec=True)
async def test_hello(mock_asyncio_sleep, capsys):
run = partial(asyncio.run, hello())
t = threading.Thread(target=run, daemon=True)
t.start()
t.join(timeout=0.1)
out, err = capsys.readouterr()
assert err == ""
assert "hello" in out
mock_asyncio_sleep.assert_awaited()
To execute the script, make sure you’ve your virtual env actiavated. Also you’ll need to
install pytest
and pytest-asyncio
. Then run:
pytest -v -s --asyncio-mode=auto
The idea came from this quora answer1.
Recent posts
- SSH saga
- Injecting Pytest fixtures without cluttering test signatures
- Explicit method overriding with @typing.override
- Quicker startup with module-level __getattr__
- Docker mount revisited
- Topological sort
- Writing a circuit breaker in Go
- Discovering direnv
- Notes on building event-driven systems
- Bash namerefs for dynamic variable referencing