openskills.info
Course Preview

Property-Based Testing

Property-based testing checks general rules about software against many generated inputs. When a rule fails, the testing library searches for a smaller counterexample that makes the defect easier to understand and reproduce.

itSoftware engineering

Property-Based Testing

Property-based testing checks a general statement about software against many generated examples. You describe a property that should hold over a range of valid inputs. A testing library generates inputs, runs the property, and reports a counterexample when the statement is false.

An example-based test starts with a value chosen by a person. It might assert that sorting [3, 1, 2] returns [1, 2, 3]. A property-based test starts with a relationship. It can assert that sorting any generated list preserves its length, produces an ordered result, and preserves the same elements. The two styles complement each other. Named examples document important cases, while generated examples explore variations that were not written by hand.

The execution pipeline

A property-based run connects five parts:

  1. Property: an executable statement about behavior.
  2. Generator: a description of the input space and how values are produced.
  3. Runner: repeated execution of the property with generated values.
  4. Shrinker: a search for a smaller input that still fails.
  5. Failure report: the reduced counterexample and information needed to reproduce it.

The runner asks each generator for a value. It passes that value to the property. A passing result leads to another generated value. A failing result starts shrinking. The shrinker proposes related values that are smaller according to the library's ordering. It keeps a candidate only when the property still fails. The final report contains a reduced counterexample rather than the first, potentially large failure.

Generation and shrinking form one design problem. A generator must produce valid and useful data. Its shrinking behavior must preserve constraints that matter to the property. Filtering a broad generator can spend most runs rejecting invalid values. It can also make a failure hard to shrink. Constructing valid values directly usually gives the runner more useful executions and the shrinker a clearer route toward a small counterexample.

What makes a useful property

Continue the course

This section is part of the paid course.

See pricing to subscribe, or log in if you already have access.

Where this skill leads

Relevant careers

See how this topic contributes to broader role-level skill maps.

Sources