PR

property-based-testing

Improves software reliability by using property-based testing for serialization, parsers, and state invariants.

Install

mkdir -p .claude/skills/property-based-testing && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6273" && unzip -o skill.zip -d .claude/skills/property-based-testing && rm skill.zip

Installs to .claude/skills/property-based-testing

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Provides guidance for property-based testing across multiple languages and smart contracts. Use when writing tests, reviewing code with serialization/validation/parsing patterns, designing features, or when property-based testing would provide stronger coverage than example-based tests.
287 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Identify opportunities for round-trip property testing
  • Map data invariants for custom structures
  • Generate test strategies for serialization/deserialization logic
  • Prioritize coverage based on function volatility

How it works

Analyzes code patterns for properties like round-trip equality or idempotence to structure tests based on behavior rather than inputs.

Inputs & outputs

You give it
Code snippet or transformation function
You get back
Property-based test strategy and invariant list

When to use property-based-testing

  • Validate encode/decode pairs
  • Test pure transformation functions
  • Verify smart contract state invariants
  • Check parser robustness

About this skill

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:

PatternPropertyPriority
encode/decode pairRoundtripHIGH
Pure functionMultipleHIGH
ValidatorValid after normalizeMEDIUM
Sorting/orderingIdempotence + orderingMEDIUM
NormalizationIdempotenceMEDIUM
Builder/factoryOutput invariantsLOW
Smart contractState invariantsHIGH

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)

PropertyFormulaWhen to Use
Roundtripdecode(encode(x)) == xSerialization, conversion pairs
Idempotencef(f(x)) == f(x)Normalization, formatting, sorting
InvariantProperty holds before/afterAny transformation
Commutativityf(a, b) == f(b, a)Binary/set operations
Associativityf(f(a,b), c) == f(a, f(b,c))Combining operations
Identityf(x, identity) == xOperations with neutral element
Inversef(g(x)) == xencrypt/decrypt, compress/decompress
Oraclenew_impl(x) == reference(x)Optimization, refactoring
Easy to Verifyis_sorted(sort(x))Complex algorithms
No ExceptionNo crash on valid inputBaseline 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
  • "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

When not to use it

  • Testing code with complex side effects
  • Simple CRUD operations without internal logic

Limitations

  • Requires writing logic that can be mathematically verified
  • Overhead for simple functions

How it compares

It prioritizes property invariants over hardcoded examples, yielding better coverage for edge cases.

Compared to similar skills

property-based-testing side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
property-based-testing (this skill)12moNo flagsAdvanced
netalertx-code-standards12moReviewIntermediate
review-implementation05moReviewIntermediate
test01moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by trailofbits

View all by trailofbits

differential-review

trailofbits

Performs security-focused differential review of code changes (PRs, commits, diffs). Adapts analysis depth to codebase size, uses git history for context, calculates blast radius, checks test coverage, and generates comprehensive markdown reports. Automatically detects and prevents security regressions.

3115

code-maturity-assessor

trailofbits

Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing. Produces professional scorecard with evidence-based ratings and actionable recommendations.

416

modern-python

trailofbits

Configures Python projects with modern tooling (uv, ruff, ty). Use when creating projects, writing standalone scripts, or migrating from pip/Poetry/mypy/black.

427

semgrep-rule-creator

trailofbits

Creates custom Semgrep rules for detecting security vulnerabilities, bug patterns, and code patterns. Use when writing Semgrep rules or building custom static analysis detections.

416

ton-vulnerability-scanner

trailofbits

Scans TON (The Open Network) smart contracts for 3 critical vulnerabilities including integer-as-boolean misuse, fake Jetton contracts, and forward TON without gas checks. Use when auditing FunC contracts.

410

cosmos-vulnerability-scanner

trailofbits

Scans Cosmos SDK blockchains for 9 consensus-critical vulnerabilities including non-determinism, incorrect signers, ABCI panics, and rounding errors. Use when auditing Cosmos chains or CosmWasm contracts.

32

Search skills

Search the agent skills registry