How can I sleep in a pytest environment?
I’m trying to test some hardware using the pytest framework since its fixtures are very useful. However, when I use time.sleep(), it seems to block the hardware fixture logic from running properly.
Example:
import pytest
from time import sleep
from hardware_library import hardware_fixture
def hardware_test(hardware_fixture):
hardware_fixture.start_the_testing_sequence()
sleep(120) # or whatever
It looks like the hardware fixture gets blocked when sleep() is called.
Should I modify pytest to run tests in a thread, or is there a simpler way to achieve non-blocking sleep? How can I make this work?
a
You know, after working quite a bit with hardware-driven pytest setups, I’ve hit this exact issue. Using time.sleep() inside pytest really does freeze everything especially fixtures that need to keep polling or communicating with hardware.
What saved me was shifting the test into an async flow. If you make both your test and fixture async, you can simply use:
await asyncio.sleep(120)
This won’t block the event loop, so your hardware fixture keeps running smoothly in the background. It’s a different style of writing tests, but it avoids the dead-stop that time.sleep() causes.
Yeah, Netra’s async approach definitely works and I’ve used it too but on a couple of older test setups, switching to async would’ve been a huge refactor.
In those cases, I kept the test plain and just offloaded the “waiting” to a background thread. Something super lightweight like:
import threading, time
def wait():
time.sleep(120)
threading.Thread(target=wait).start()
This way the test itself keeps moving, fixtures stay responsive, and only the waiting happens elsewhere. It’s not as elegant as async, but when you need a quick non-blocking wait, it does the job without redesigning the test suite.
I hear both of you async is clean, threads are practical but when dealing with sensitive hardware I’ve found long sleeps risky, no matter how you wrap them.
What worked for me was keeping the test active by breaking the sleep into smaller intervals and letting the fixture or hardware poll between them:
for _ in range(120):
hardware_fixture.check_status()
time.sleep(1)
Instead of going silent for 120 seconds, the test “breathes” every second. This keeps hardware alive, avoids timeouts, and still gives you the delay you need without blocking the system completely.