Skip to content
advanced Phase 16 · Python Testing Advanced

Property-Based Testing

Use Hypothesis for property-based testing and generative test cases.

1h
0 problems
Topic Progress 0%

From Examples to Properties

From Examples to Properties

Example tests assert one input; property tests assert a rule across a generated space:

from hypothesis import given, strategies as st

def canonical(s):            # the function under test
    return "-".join(s.lower().split())

@given(st.text())
def test_idempotent(s):
    once = canonical(s)
    assert canonical(once) == once      # normalizing twice = normalizing once

@given(st.lists(st.integers(), min_size=1))
def test_sort_preserves(xs):
    assert sorted(xs) == sorted(reversed(xs))

Hypothesis runs many generated examples per call, and on failure it shrinks to a minimal counterexample (often a short string or small list) — the main advantage over hand-picked cases. Regressions auto-save: any failing example is replayed on every future run until the bug is fixed.

Building Strategies

Building Strategies

from hypothesis import given, strategies as st, assume

@st.composite
def user(draw):
    name = draw(st.text(min_size=1, max_size=20))
    age = draw(st.integers(min_value=0, max_value=130))
    return {"name": name, "age": age}

@given(user())
def test_roundtrip(u):
    parsed = parse(serialize(u))
    assume(parsed is not None)     # discard invalid draws, don't assert-pass
    assert parsed == u

Composable builders cover most needs: st.one_of for unions, st.builds(Class, ...) for objects, st.sampled_from for enums, st.recursive for nested structures. Constrain with min_size/max_size rather than slicing results, and prefer assume for rare preconditions — but keep rejection rates low or Hypothesis reports a filtered_too_much health check.

Pitfalls and Interview Angles

Pitfalls and Interview Angles

  • Tests must be pure. Reading the clock, network, or a shared DB makes properties flaky; inject fakes or seed the dependency.
  • The database directory .hypothesis/ holds passing examples and failing regressions — keep it out of VCS or commit it deliberately so CI replays the same failures.
  • Health checks. failed_health_check, too_slow, filter_too_much all mean the strategy or assumption logic is misdesigned, not that your code is correct.
  • Stateful testing. RuleBasedStateMachine generates command sequences with @rule/@precondition for caches, queues, and DB layers where single-call properties are not enough.

Interview angle: name three cache properties (hit returns original value, size never exceeds bound, eviction keeps LRU order) and explain why a two-character shrunk counterexample teaches more than a 4 KB one.

Quiz

1. What is the main benefit of Hypothesis shrinking?

Question 1 options

2. When should you use assume() instead of asserting a condition?

Question 2 options

3. What does a filtered_too_much health check indicate?

Question 3 options

Flashcards

Question

Property-based test

Answer

Asserts an invariant over generated inputs; Hypothesis runs many examples and shrinks failures.

Question

@st.composite

Answer

Builds custom strategies by drawing sub-values step by step.

Question

assume()

Answer

Discards draws that violate preconditions instead of failing the test.

Question

Hypothesis database

Answer

Local .hypothesis dir replaying failing examples and shrinking history on every run.

Revision Notes

Key Takeaways

  • 1. Properties (idempotence, round-trip) find bugs examples never think to try
  • 2. Strategies compose; keep rejection rates low to satisfy health checks
  • 3. Lock fixed regressions with @example and decide deliberately whether the database ships in CI

Interview Tips

  • • Offer concrete properties for a real component, not the abstract definition of PBT
  • • Explain shrinking with a mini counterexample story and mention stateful testing for sequence bugs

Cheat Sheet

@given(st.integers()) generates+shrinks; @example pins regressions; assume() for preconditions; @st.composite custom draws; .hypothesis/ replays failures.

Continue Learning