iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Example-based unit tests check whether specific inputs produce expected results. Invariant and property-based tests check whether a rule holds across inputs or operations selected from a defined domain. They complement each other: keep your important examples, then add properties that expose behavior your hand-picked cases may miss.
How property-based testing differs from example-based unit testing
A unit test describes what is being tested; it does not dictate how test inputs must be chosen. In a common example-based test, you write a particular input and its expected output. A property-based test instead states a general rule and describes valid inputs. A framework generates cases from that domain and checks whether the rule holds for them.
| Approach | What you supply | What it helps check |
|---|---|---|
| Example-based test | A concrete input and expected result | A known scenario, boundary case, or regression |
| Property-based test | A rule and a description of valid inputs | Whether the rule holds across generated cases |
The distinction is about how cases are supplied, not a choice between unit tests and property tests. A property-based test can test a unit, and a test suite can use both approaches. Hypothesis describes property-based testing as an addition to unit testing, with the framework choosing examples—including edge cases—from strategies you define (Hypothesis documentation).
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsWhat is an invariant?
An invariant is a condition that should remain true across the inputs or operations under test. It often captures a relationship that is more useful than a long list of individual expected outputs.
- Collection size: If a map operation is meant to transform every item without adding or removing any, the output should have the same number of items as the input.
- Conservation across a transfer: For a modeled transfer between two accounts, their combined balance should remain constant if the operation creates or destroys no funds. Fees and currency conversion need separate, explicit rules.
These properties are only as sound as their assumptions. Define what counts as a valid input and what the operation is supposed to preserve; otherwise, a test may enforce the wrong rule.
Four useful property patterns
Invariants
Check that a condition remains true after an operation or across generated inputs, such as preserving item count or a conserved total.
Inverse operations
Check that one operation reverses another under stated constraints. For example, deserializing serialized data should recover the original value when the format and supported values make that relationship valid. Anthropic uses JSON deserialization as an illustration of this pattern (Anthropic’s property-based testing article).
Equivalent implementations
If two implementations are intended to have the same semantics, run them on the same generated input and check that their results agree. This is useful only when the implementations are meant to match for the domain being tested.
Idempotence
Check that applying an operation repeatedly has no additional observable effect after the first application. Trimming whitespace is one possible example: trimming an already trimmed string should leave it unchanged.
QuickTheories documents these patterns, including invariants, inverse functions, analogous functions, and idempotence (QuickTheories documentation). Treat them as prompts for specifying behavior, not recipes to apply without checking the product’s requirements. A property should express expected behavior independently enough that it does not simply repeat the implementation’s own logic.
Example: test a sorting rule with separate properties
Suppose a function sorts lists of numbers. Generate lists from a deliberately defined domain, then check at least two distinct properties:
- Ordering: Each value appears in the required order in the output.
- Preservation: The output contains the same elements as the input, including duplicates.
Ordering alone would not catch a function that drops a duplicate; preservation alone would not catch an unsorted result. Also specify how the domain handles special values such as NaN. Whether those values can be ordered, and what “sorted” means for them, requires an explicit decision rather than a broad claim about all numeric inputs.
What generated tests can—and cannot—establish
A property-based framework checks the cases it generates from the domain you describe. This can broaden exploration beyond a short hand-written list, but a finite run does not prove that a property holds for every possible input. An incomplete input domain can miss relevant cases, and an incorrect or overly weak property can pass without checking the behavior you care about.
Rank #4
Hypothesis explains that its strategies describe inputs and that it chooses examples, including edge cases. Its tutorial also notes that a counterexample may not appear on every random run (Hypothesis introduction). Treat a passing run as evidence about the generated cases, not a proof of universal correctness.
When a generated case fails, it is a counterexample to the assertion as written. Some frameworks can simplify failing cases to make them easier to understand; the exact behavior depends on the framework and its version. Check the tool’s documentation rather than assuming all property-testing libraries reduce failures in the same way.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →How to add property tests to an existing suite
- Choose a behavior with a clear rule. Start with a relationship you can explain plainly, such as preserving a collection’s size or maintaining a total.
- Define the valid domain. Decide which inputs are supported and which need special handling. Make exclusions and assumptions explicit.
- Write one focused property. Assert the invariant or relationship directly, without duplicating the implementation’s internal logic.
- Keep examples for important cases. Retain readable tests for known regressions, boundary conditions, and scenarios whose expected result is valuable in its own right.
- Review failures and test cost. Check whether a reported counterexample is reproducible and understandable, and whether the test’s runtime and maintenance fit the suite.
For systems where behavior depends on sequences of actions, ordinary input/output properties may not be enough. Stateful property testing can model operations and check rules across changing state. QuickTheories describes state-related examples, and Fred Hébert’s book Property-Based Testing with PropEr, Erlang, and Elixir covers stateful programs. The book is specifically focused on Erlang and Elixir, not a language-neutral introduction (publisher page).
Best Value
Choosing a property-based testing library
Choose a library that fits your language and the way your team tests. Compare these practical considerations rather than relying on an unsupported “best” ranking:
- Language and test-runner integration: Can the library fit the project’s existing ecosystem and workflow?
- Generator control: Can you describe the valid domain precisely and generate useful cases for it?
- Stateful support: Does it support operation sequences if your system requires them?
- Failure reproduction and reporting: Can you reproduce a failing case and understand what assertion failed?
- Shrinking or minimization: Does the library reduce failing inputs, and how does that feature work?
- Documentation and maintenance: Are its current docs clear about the APIs and behaviors you need?
For Python, Hypothesis documents strategies, generated examples, and a broader set of guides and API references. For Java, QuickTheories documents property testing and common property patterns. Library APIs and documentation change, so confirm current details in the official docs before adopting them.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

