Helpful wrapper around
time-machine that extends its
capabilities to also fake out time.sleep, asyncio.sleep, and
time.monotonic. When you advance time via any of the sleep functions, time
will shift forward without waiting for that time to actually pass.
Both time-machine and freezegun have deliberately avoided mocking sleep functions and monotonic clocks after encountering significant issues (see below).
That said, it is sometimes really handy to be able to mock out dumb sleeps. So user beware :D
Why doesn't upstream do this?
-
time-machineadded monotonic mocking in v2.13.0 and immediately broke asyncio tests, pytest durations, and database drivers (#387, #505, #509). The maintainer now plans to remove it entirely, stating it was "too brittle and broke many things, like asyncio" (#560). -
freezegunmockingtime.monotonic()causesasyncio.sleep()to hang indefinitely (#290, #437, #383) and can make monotonic time move backwards, violating its core guarantee (#556).
uv pip install faketimefaketime has two modes: fake & frozen:
- In
fakemode, "time" still advances naturally in the background. - In
frozenit does not and instead advances only when explicitly moved forward via an explicit action, such as a{time,asyncio}.sleep.
import time
from faketime import faketime, frozentime
with faketime():
start = time.time()
time.sleep(10) # Instantly advance time by t+10 seconds
elapsed = time.time() - start
assert elapsed >= 10 # Note: Will be >= because some actual time has also naturally happened
with frozentime():
start = time.time()
time.sleep(10) # Instantly advance time by exactly 10 seconds
elapsed = time.time() - start
assert elapsed == 10 # Exactly 10 seconds passedThere's also a lightweight set of pytest fixtures you can use to wrap your whole test suite in fake or frozen time.
from faketime.pytest import *
def test_something(faketime):
time.sleep(10) # Instant
def test_frozen(frozentime):
time.sleep(10) # Instant, and also frozen