CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/fake-clock-testing

Fake clocks / freeze time in tests across every mainstream runtime: freezegun (Python), Jest fake timers + Sinon @sinonjs/fake-timers (JS/TS), timecop (Ruby), java.time.Clock / InstantSource injection (JVM), .NET TimeProvider / FakeTimeProvider, and libfaketime (LD_PRELOAD for any native binary). Covers the language-agnostic discipline - inject or patch the clock, freeze vs tick vs advance vs set-system-time semantics, teardown so fake clocks never leak between tests - plus the shared anti-pattern table (real sleep under a frozen clock, leaked clock state, timezone-dependent assertions). Per-library setup, API, and CI recipes live in references/{python,js,ruby,jvm,dotnet,libfaketime}.md. Use when tests need deterministic control of now(), timers, or timeouts in any language, or when choosing the right fake-clock tool for a stack.

93

Quality

93%

Does it follow best practices?

Impact

Average score across 3 eval scenarios

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

libfaketime.mdreferences/

libfaketime - the LD_PRELOAD escape hatch

Per github.com/wolfcw/libfaketime, libfaketime returns a value derived from the FAKETIME environment variable instead of the real clock by intercepting libc time() / gettimeofday() / clock_gettime(). Because it hooks libc, it works for any dynamically linked binary - C/C++, Go (cgo builds), Rust, Python - including processes you don't control the source of. Reach for it when language-native fakes cannot patch the code (C extensions, closed-source binaries, multi-process integration tests).

Install

sudo apt install faketime        # Debian/Ubuntu
brew install libfaketime         # macOS
# or from source: git clone https://github.com/wolfcw/libfaketime && make && sudo make install

Absolute-date mode

faketime '2026-12-31 23:59:00' your_command
# equivalent raw form:
LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 \
  FAKETIME='2026-12-31 23:59:00' your_command

Relative offset and advance-rate modes

faketime '-1d' your_command                       # 1 day in the past
faketime '+2h30m' your_command                    # 2h30m ahead
faketime -f '@2026-12-31 23:59:00 x10' your_cmd   # start there, run at 10x speed

The x<rate> spec suits scheduler/cron simulations - e.g. faketime -f '@2026-01-01 00:00:00 x5256' ./cron-runner simulates a year in ~10 minutes.

High-resolution mode

FAKETIME_NO_CACHE=1 faketime '2026-12-31 23:59:00' your_command

Disables libfaketime's per-second caching so code reading time hundreds of times per second sees consistent values.

Asserting from a test runner

libfaketime emits nothing itself - assert on the wrapped program's visible behaviour:

import subprocess

def test_cron_fires_at_midnight():
    result = subprocess.run(
        ["faketime", "2026-12-31 23:59:30", "./cron-runner"],
        capture_output=True, text=True, timeout=5,
    )
    assert "Fired at 2027-01-01 00:00:00" in result.stdout

DST recipe - non-existent local time

TZ='America/New_York' faketime '2026-03-08 02:30:00' ./my-program

US Eastern springs forward at 02:00 on 2026-03-08, so 02:30 local does not exist; TZ makes the program resolve the faked instant in Eastern. Assert the program skips the job or normalises to 03:30, per dst-transition-reference.

CI integration

jobs:
  time-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - run: sudo apt-get install -y faketime
      - run: pytest tests/time/

Anti-patterns

Anti-patternWhy it failsFix
Statically linked binariesLD_PRELOAD has no symbols to interceptLanguage-native fake clock
Raw LD_PRELOAD with a wrong pathSilently no-opsUse the faketime wrapper
Spring-forward test without TZFake time resolves in UTC onlyPrefix TZ='<zone>'
Missing FAKETIME_NO_CACHE=1 for fast-polling codeTime stalls between cache refreshesSet it explicitly
Using it against the JVMSome JVM time calls bypass libcClock injection (jvm.md)

Limitations

  • Linux + macOS only - Windows uses different time syscalls.
  • Static binaries unaffected - Go compiled with CGO_ENABLED=0 does not see libfaketime.
  • Monotonic clocks are not faked by default; some clock_gettime flags pass through.

References

SKILL.md

tile.json