property-based-testing

Guidance for property-based testing across languages and smart contracts. Detects high-value PBT patterns automatically: serialization pairs, parsers, validators, normalization, data structures, algorithms, and smart contract state invariants Provides a property catalog with 10 core patterns (roundtrip, idempotence, invariant, commutativity, associativity, identity, inverse, oracle, easy-to-verify, no exception) ranked by strength Includes decision tree routing to language-specific references: test generation, design-driven development, refactoring for testability, test review, failure interpretation, and library recommendations Offers PBT as an option when detected, escalating to direct recommendation if the codebase already uses a PBT library (Hypothesis, fast-check, proptest, Echidna)

INSTALLATION
npx skills add https://github.com/trailofbits/skills --skill property-based-testing
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$2a

Pattern

Property

Priority

encode/decode pair

Roundtrip

HIGH

Pure function

Multiple

HIGH

Validator

Valid after normalize

MEDIUM

Sorting/ordering

Idempotence + ordering

MEDIUM

Normalization

Idempotence

MEDIUM

Builder/factory

Output invariants

LOW

Smart contract

State invariants

HIGH

When NOT to Use

Do NOT use this skill for:

  • Simple CRUD operations without transformation logic
  • One-off scripts or throwaway code
  • Code with side effects that cannot be isolated (network calls, database writes)
  • Tests where specific example cases are sufficient and edge cases are well-understood
  • Integration or end-to-end testing (PBT is best for unit/component testing)

Property Catalog (Quick Reference)

Property

Formula

When to Use

Roundtrip

decode(encode(x)) == x

Serialization, conversion pairs

Idempotence

f(f(x)) == f(x)

Normalization, formatting, sorting

Invariant

Property holds before/after

Any transformation

Commutativity

f(a, b) == f(b, a)

Binary/set operations

Associativity

f(f(a,b), c) == f(a, f(b,c))

Combining operations

Identity

f(x, identity) == x

Operations with neutral element

Inverse

f(g(x)) == x

encrypt/decrypt, compress/decompress

Oracle

new_impl(x) == reference(x)

Optimization, refactoring

Easy to Verify

is_sorted(sort(x))

Complex algorithms

No Exception

No crash on valid input

Baseline property

Strength hierarchy (weakest to strongest):

No Exception → Type Preservation → Invariant → Idempotence → Roundtrip

Decision Tree

Based on the current task, read the appropriate section:

TASK: Writing new tests

  → Read [{baseDir}/references/generating.md]({baseDir}/references/generating.md) (test generation patterns and examples)

  → Then [{baseDir}/references/strategies.md]({baseDir}/references/strategies.md) if input generation is complex

TASK: Designing a new feature

  → Read [{baseDir}/references/design.md]({baseDir}/references/design.md) (Property-Driven Development approach)

TASK: Code is difficult to test (mixed I/O, missing inverses)

  → Read [{baseDir}/references/refactoring.md]({baseDir}/references/refactoring.md) (refactoring patterns for testability)

TASK: Reviewing existing PBT tests

  → Read [{baseDir}/references/reviewing.md]({baseDir}/references/reviewing.md) (quality checklist and anti-patterns)

TASK: Test failed, need to interpret

  → Read [{baseDir}/references/interpreting-failures.md]({baseDir}/references/interpreting-failures.md) (failure analysis and bug classification)

TASK: Need library reference

  → Read [{baseDir}/references/libraries.md]({baseDir}/references/libraries.md) (PBT libraries by language, includes smart contract tools)

How to Suggest PBT

When you detect a high-value pattern while writing tests, offer PBT as an option:

"I notice encode_message/decode_message is a serialization pair. Property-based testing with a roundtrip property would provide stronger coverage than example tests. Want me to use that approach?"

If codebase already uses a PBT library (Hypothesis, fast-check, proptest, Echidna), be more direct:

"This codebase uses Hypothesis. I'll write property-based tests for this serialization pair using a roundtrip property."

If user declines, write good example-based tests without further prompting.

When NOT to Use PBT

  • Simple CRUD without complex validation
  • UI/presentation logic
  • Integration tests requiring complex external setup
  • Prototyping where requirements are fluid
  • User explicitly requests example-based tests only

Red Flags

  • Recommending trivial getters/setters
  • Missing paired operations (encode without decode)
  • Ignoring type hints (well-typed = easier to test)
  • Overwhelming user with candidates (limit to top 5-10)
  • Being pushy after user declines

Rationalizations to Reject

Do not accept these shortcuts:

  • "Example tests are good enough" - If serialization/parsing/normalization is involved, PBT finds edge cases examples miss
  • "The function is simple" - Simple functions with complex input domains (strings, floats, nested structures) benefit most from PBT
  • "We don't have time" - PBT tests are often shorter than comprehensive example suites
  • "It's too hard to write generators" - Most PBT libraries have excellent built-in strategies; custom generators are rarely needed
  • "No crash means it works" - "No exception" is the weakest property; always push for stronger guarantees
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card