freezegun Time Not Frozen / "ModuleNotFoundError" in CI
freezegun patches datetime/time to return a fixed instant. It only affects code that reads time through the standard library after the freeze is active - a C-extension clock, a cached timestamp, or code outside the decorated scope still sees real time.
What this error means
A test asserting on a frozen timestamp fails because the value is the real current time, or freezegun is missing entirely with ModuleNotFoundError: No module named 'freezegun'. The freeze is not reaching the code under test.
AssertionError: assert datetime(2026, 6, 25, 0, 0) == datetime(2026, 6, 25, 14, 32, 8)
# freeze_time did not affect the value the code readCommon causes
Time read outside the frozen scope
Code that captured datetime.now() at import time, or runs before freeze_time activates, keeps the real value. The freeze must wrap the call site.
A non-standard time source
A C extension or a vendored clock that does not go through datetime/time is not patched by freezegun, so it still returns real time.
freezegun not installed in CI
The dev dependency is absent from the CI environment, so the import fails before any freezing happens.
How to fix it
Freeze around the code under test
Apply freeze_time so it is active when the time is read.
from freezegun import freeze_time
@freeze_time("2026-06-25")
def test_report_date():
assert build_report().date == "2026-06-25"Install freezegun in the test env
pip install freezegun
# or add to test extras / dev dependenciesPatch the right time source
- Confirm the code reads time via
datetime/time, not a C extension. - Avoid capturing timestamps at import; read them when the function runs.
- For unpatchable sources, inject a clock dependency you can stub.
How to prevent it
- Apply
freeze_timeto the exact scope that reads the clock. - Inject time as a dependency for code with non-standard clocks.
- Pin freezegun in test/dev dependencies so CI has it.