Modern QA2026Failure Mode 5: The Non-Deterministic Test — tiles
Log inJoin
43 / 87 · 02 AI-Augmented Test Design · Common AI Test Failures← prev⊞ allnext →☰ Read as one page

7.6Failure Mode 5: The Non-Deterministic Test

The test depends on time, random data, or external state that changes between runs.

# FLAKY: depends on current time
def test_expiry_check():
    token = create_token(expires_in=3600)
    assert not token.is_expired()    # Passes now, fails if test takes > 1 hour

# FLAKY: depends on random data
def test_random_assignment():
    user = create_user()
    assert user.group in ["A", "B"]  # Passes most times, fails if random assigns "C"

# FLAKY: depends on database state from another test
def test_user_count():
    assert User.count() == 5  # Depends on exact state left by previous tests

How to fix it:

# FIXED: mock time explicitly
def test_expiry_check(freezer):
    freezer.move_to("2026-02-09T10:00:00Z")
    token = create_token(expires_in=3600)
    freezer.move_to("2026-02-09T10:30:00Z")  # 30 min later
    assert not token.is_expired()
    freezer.move_to("2026-02-09T11:01:00Z")  # 61 min later
    assert token.is_expired()

# FIXED: seed random
def test_random_assignment():
    random.seed(42)
    user = create_user()
    assert user.group == "A"  # Deterministic with seed

# FIXED: use relative assertions
def test_user_creation_increments_count():
    before = User.count()
    create_user(name="New User")
    assert User.count() == before + 1