agentleFS
DROOdotFOODROOdotFOO/agent-skills/skills/property-testing/SKILL.md

property-testing

Skill1 starsChanged 2 months agoMITView on GitHub

Property-based and generative testing across the polyglot stack. TRIGGER when: user asks about property-based testing, generative testing, QuickCheck, Hypothesis, proptest, StreamData, fast-check, fuzzing test inputs, or finding edge cases that example tests miss. DO NOT TRIGGER when: user asks about TDD workflow (use tdd), mutation testing (use tdd), load testing (use performance-profiler), or security fuzzing (use security-auditor).

  • Installs packages

We split this skill into the rules it gives an agent

4 rules. 0 are common, 1 is distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Before writing any generators, identify what properties the code should satisfy.

    line 50
  2. Very specific:

    Use the language's built-in generators first.

    line 60
  3. Very specific:

    When a property fails, the framework shrinks the input to the minimal counterexample.

    line 99
  4. Distinctive:

    Every PBT run must be reproducible.

    line 104

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

You are a Senior Test Architect -- you distrust example-based tests that only prove the author's assumptions, and you design properties that let the machine find the bugs you didn't imagine.

property-testing

Property-based testing (PBT) generates random inputs, checks that properties hold for all of them, and shrinks failures to minimal counterexamples. It finds edge cases that hand-written examples miss.

What You Get

  • Property definitions for the target code (roundtrip, invariant, oracle, metamorphic)
  • Custom generators tailored to the domain, not just random noise
  • Deterministic CI configuration (fixed seeds, bounded examples)
  • Shrunk counterexamples with reproduction commands

When PBT Beats Example Tests

Use PBTStick with examples
Parsers, serializers (roundtrip property)Simple CRUD operations
Sorting, filtering (invariant properties)UI rendering
State machines, protocols (model-based)Integration tests with external services
Numeric algorithms (oracle: compare to reference)Code where the property restates the implementation
Any function with a large input spaceGlue code with minimal logic

The litmus test: Can you state what should be true for ALL inputs without restating the implementation? If yes, use PBT. If the property is just assert f(x) == implementation(x), you are testing nothing.

Workflow

1. Identify properties

Before writing any generators, identify what properties the code should satisfy. See properties.md for the full taxonomy. Common starting points:

  • Roundtrip: decode(encode(x)) == x
  • Invariant: len(sort(xs)) == len(xs)
  • Idempotent: f(f(x)) == f(x)
  • Commutative: f(a, b) == f(b, a) (when applicable)

2. Build generators

Use the language's built-in generators first. Only build custom generators when the input domain has constraints (e.g., valid email addresses, balanced trees). See generators.md.

3. Write the property test

# Python (Hypothesis)
from hypothesis import given, settings
import hypothesis.strategies as st

@given(st.lists(st.integers()))
@settings(max_examples=200, derandomize=True)
def test_sort_preserves_length(xs):
    assert len(sorted(xs)) == len(xs)
// Rust (proptest)
proptest! {
    #[test]
    fn sort_preserves_length(xs: Vec<i32>) {
        let sorted = sort(&xs);
        prop_assert_eq!(sorted.len(), xs.len());
    }
}
# Elixir (StreamData)
property "sort preserves length" do
  check all xs <- list_of(integer()) do
    assert length(Enum.sort(xs)) == length(xs)
  end
end

4. Run, shrink, fix

When a property fails, the framework shrinks the input to the minimal counterexample. See shrinking.md for debugging strategies.

5. Lock the seed for CI

Every PBT run must be reproducible. Set a fixed seed and bounded example count in CI. Allow unbounded exploration in local development.

Tools by Language

LanguageLibraryInstallSeed flag
PythonHypothesispip install hypothesis@settings(derandomize=True)
Rustproptestproptest = "1" in Cargo.tomlPROPTEST_SEED=<n> env var
ElixirStreamData{:stream_data, "~> 1.0", only: :test}--seed <n> in mix test
TypeScriptfast-checknpm i -D fast-checkfc.assert(prop, { seed })
Gogoptergo get github.com/leanovate/goptergopter.DefaultGenParameters().Seed(n)
HaskellQuickCheckcabal install QuickCheckquickCheckWith stdArgs{replay=Just(seed,0)}

Relationship to TDD

PBT fits into the TDD workflow as a validation step after the incremental loop:

Phase 1: Planning
Phase 2: Tracer Bullet (one example test)
Phase 3: Incremental Loop (example tests, RED-GREEN)
Phase 3.5: Property Testing  <-- YOU ARE HERE
Phase 4: Mutation Testing (see tdd skill)
Phase 5: Refactor

PBT and mutation testing target different gaps:

  • PBT: "does the code handle inputs I didn't think of?"
  • Mutation testing: "would my tests catch a bug if one were introduced?"

Common Pitfalls

MistakeFix
Property just restates the implementationFind a different angle: roundtrip, invariant, comparison to reference
Generator produces invalid domain inputsAdd assume() / filter() or build a custom generator
Tests are slow (>30s)Reduce max_examples, use @settings(deadline=None) only locally
Flaky CI from non-deterministic seedsAlways set derandomize=True or equivalent in CI
Only testing pure functionsUse model-based testing for stateful systems

Reading guide

TopicFile
Property taxonomy with examplesproperties.md
Custom generator patternsgenerators.md
Shrinking and debugging failuresshrinking.md

See also

  • tdd -- red-green-refactor workflow; PBT extends Phase 3
  • tdd (mutation-testing sub-file) -- complementary validation (tests the tests, not the input space)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.