property-based-testing

Property-Based Testing Guide

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "property-based-testing" with this command: npx skills add trailofbits/skills/trailofbits-skills-property-based-testing

Property-Based Testing Guide

Use this skill proactively during development when you encounter patterns where PBT provides stronger coverage than example-based tests.

When to Invoke (Automatic Detection)

Invoke this skill when you detect:

  • Serialization pairs: encode /decode , serialize /deserialize , toJSON /fromJSON , pack /unpack

  • Parsers: URL parsing, config parsing, protocol parsing, string-to-structured-data

  • Normalization: normalize , sanitize , clean , canonicalize , format

  • Validators: is_valid , validate , check_* (especially with normalizers)

  • Data structures: Custom collections with add /remove /get operations

  • Mathematical/algorithmic: Pure functions, sorting, ordering, comparators

  • Smart contracts: Solidity/Vyper contracts, token operations, state invariants, access control

Priority by pattern:

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 (test generation patterns and examples) → Then {baseDir}/references/strategies.md if input generation is complex

TASK: Designing a new feature → Read {baseDir}/references/design.md (Property-Driven Development approach)

TASK: Code is difficult to test (mixed I/O, missing inverses) → Read {baseDir}/references/refactoring.md (refactoring patterns for testability)

TASK: Reviewing existing PBT tests → Read {baseDir}/references/reviewing.md (quality checklist and anti-patterns)

TASK: Test failed, need to interpret → Read {baseDir}/references/interpreting-failures.md (failure analysis and bug classification)

TASK: Need library reference → Read {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

  • "The test failed, so it's a bug" - Failures require validation; see interpreting-failures.md

  • "No crash means it works" - "No exception" is the weakest property; always push for stronger guarantees

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ask-questions-if-underspecified

No summary provided by upstream source.

Repository SourceNeeds Review
General

differential-review

No summary provided by upstream source.

Repository SourceNeeds Review
General

semgrep

No summary provided by upstream source.

Repository SourceNeeds Review
General

sharp-edges

No summary provided by upstream source.

Repository SourceNeeds Review