Luigit
repositories / smith

smith

There are many coding harnesses - but this one is fast

owned by admin

.pi/skills/property-testing/SKILL.md

Raw
Rendered preview

name: property-testing description: "Use when a pure function has a law: roundtrip, idempotence, order independence, monotonic bound, or an invariant over arbitrary input; state it as a proptest property."

Property testing

A law over all inputs beats ten examples.

Laws worth stating

  • roundtrip: decode(encode(x)) == x
  • idempotence: f(f(x)) == f(x)
  • order independence: f(shuffle(x)) == f(x)
  • bound: len(compress(x)) <= len(x) + header
  • invariant: after any operation sequence, the structure still validates

Shape

  • One property per law; the name is the law.
  • Strategies from the domain: build valid values by construction, not by filtering; filter only for rare exclusions.
  • Keep the default case count small enough for the commit tier; raise PROPTEST_CASES when hunting.
  • Check in the proptest-regressions/ file; a shrunk counterexample is a permanent test.
  • When a property fails, add the shrunk input as a plain example test too; it reads better in a diff.

Do not

  • Re-implement the function inside the property; assert relations, not values.
  • Property-test I/O, time, or randomness sources; those are behavior tests with injected inputs.

Sources

---
name: property-testing
description: "Use when a pure function has a law: roundtrip, idempotence, order independence, monotonic bound, or an invariant over arbitrary input; state it as a proptest property."
---

# Property testing

A law over all inputs beats ten examples.

## Laws worth stating

- roundtrip: `decode(encode(x)) == x`
- idempotence: `f(f(x)) == f(x)`
- order independence: `f(shuffle(x)) == f(x)`
- bound: `len(compress(x)) <= len(x) + header`
- invariant: after any operation sequence, the structure still validates

## Shape

- One property per law; the name is the law.
- Strategies from the domain: build valid values by construction, not by filtering; filter only for rare exclusions.
- Keep the default case count small enough for the commit tier; raise `PROPTEST_CASES` when hunting.
- Check in the `proptest-regressions/` file; a shrunk counterexample is a permanent test.
- When a property fails, add the shrunk input as a plain example test too; it reads better in a diff.

## Do not

- Re-implement the function inside the property; assert relations, not values.
- Property-test I/O, time, or randomness sources; those are behavior tests with injected inputs.

## Sources

- [proptest book](https://proptest-rs.github.io/proptest/)