Property-Based Testing
Property-based testing states a rule over an allowed input domain and generates cases to check it. A failure is a counterexample. Passing generated cases do not prove the rule for every input. Useful properties include preserving elements during sorting and specified round trips.
What a learner can do afterwards
- Write a property that a sorting function must satisfy for any input list
- Explain what shrinking does to a failing case and why it helps
- Explain how weak properties or missing cases can leave faults undetected, and how example tests can add checks
1 · Read
Property-based testing adds a testing style, not another test level. State a rule for an allowed input domain and use a generator to produce cases in that domain. The test checks the rule for each generated case. A failure gives a counterexample; passing generated cases do not prove the rule for every allowed input.
For ascending integer sorting, check that the output is ordered and has exactly the same values with exactly the same counts as the input. This is equality of the complete multisets: no value is added, removed or given a different count. Preserving counts only for values already in the input would wrongly permit new output values.
Shrinking searches for a simpler input that still fails the property. Depending on the tool and search, it may shorten a list or reduce its values. It does not generally guarantee the globally smallest failure. A simpler counterexample can help investigation, but it does not automatically identify the cause.
A parser turns valid text into a value; a printer turns a value into valid text. If the contract preserves values, parsing a printed allowed value should return that value. Printing parsed text may normalize spacing. If printing is canonical, normalize valid text, then normalize the result again. The two normalized texts should match.
Configure generators for this property's domain. For lists of at most six integers, vary empty lists, repeats and order within that limit. Inputs outside this domain need other checks, but they are not automatically invalid for the function. A larger list may be allowed by its full contract. Test error behaviour only where that contract specifies an error.
A property can be too weak. Reversing twice should return the original list, but an implementation that returns its input unchanged also passes that rule. An example such as reversing [5, 8] to [8, 5] rejects that implementation. Other properties could reject it too; exact outputs are not exclusive to examples.
Passing many cases does not establish an untested requirement. If a fee property checks only that fees are nonnegative, it can accept an incorrect positive amount. Add a check against the specified fee rule. That check could use chosen examples or generated cases with an independent expected result.
State a useful rule over allowed inputs. Generate cases, investigate counterexamples and shrink them where supported. Passing cases are not a proof.
Original lesson, questions and flashcards written for this learning dataset.
2 · Watch
Take it off screen
Where it sits
Optional connections
8 questions wait behind this lesson, each with its answer explained. Every answer feeds the sky: stars light as they are learned, and dim when it is time to come back.